Fragmentize ZoneList, which is needed in DateTimeSettings refactoring.

- remove old ZonePicker and rename ZoneList to ZonePicker, as
  the name is really confusing (see LocalePicker)
- Make the new ZonePicker fragment.
- remove dependency toward "ZoneList" class.
-- AndroidManifest.xml does not allow the other components to
   access ZoneList directly, so it would be ok to remove without
   using activity-alias.
-- Noticed there is a significant code duplication between
   DateTimeSettings and DateTimeSettingsActivity. I'll work on it
   later.
- add DateTimeSettingsSetupWizardXL class, which is not used yet,
  but will be in the near future.
-- It is not recognized by AndroidManifest.xml

Change-Id: Id26152a3d560f9e0bd84afdf3e1c5101f0e166b4
This commit is contained in:
Daisuke Miyakawa
2010-09-03 15:40:17 -07:00
parent 0cec40628b
commit 0f4f2f3a81
8 changed files with 262 additions and 325 deletions

View File

@@ -560,8 +560,6 @@
android:label="@string/lockpattern_change_lock_pattern_label"> android:label="@string/lockpattern_change_lock_pattern_label">
</activity> </activity>
<activity android:name="ZoneList" android:label="@string/choose_timezone" />
<activity android:name=".deviceinfo.Status" android:label="@string/device_status_activity_title" <activity android:name=".deviceinfo.Status" android:label="@string/device_status_activity_title"
android:process="com.android.phone"> android:process="com.android.phone">
<intent-filter> <intent-filter>

View File

@@ -492,7 +492,7 @@
<!-- mobile network settings screen, setting option summary text --> <!-- mobile network settings screen, setting option summary text -->
<string name="sum_carrier_select">Select a network operator</string> <string name="sum_carrier_select">Select a network operator</string>
<!-- Date and time settings --> <!-- Date and time settings --><skip />
<!-- Main Settings screen setting option name to go into the date and time settings--> <!-- Main Settings screen setting option name to go into the date and time settings-->
<string name="date_and_time_settings_title">Date &amp; time</string> <string name="date_and_time_settings_title">Date &amp; time</string>
<!-- Main Settings screen setting option summary text for the item to go into the date and time settings. --> <!-- Main Settings screen setting option summary text for the item to go into the date and time settings. -->
@@ -2685,4 +2685,13 @@ found in the list of installed applications.</string>
<!-- The message show above available networks when connection is established. <!-- The message show above available networks when connection is established.
Used in Wifi Setup For Setup Wizard with XL screen. --> Used in Wifi Setup For Setup Wizard with XL screen. -->
<string name="wifi_setup_status_connected">Connected</string> <string name="wifi_setup_status_connected">Connected</string>
<!-- Do not translate. Just a temprary stub. -->
<string name="time_zone_manual_select_enabler" translatable="false">Experimental text</string>
<!-- Do not translate. Just a temprary stub. -->
<string name="date_time_manual_select_enabler" translatable="false">Experimental text</string>
<!-- Do not translate. Just a temprary stub. -->
<string name="date_time_setup_skip" translatable="false">Skip</string>
<!-- Do not translate. Just a temprary stub. -->
<string name="date_time_setup_next" translatable="false">Next</string>
</resources> </resources>

View File

@@ -25,7 +25,9 @@
android:title="@string/date_time_set_date" android:title="@string/date_time_set_date"
android:summary="03/10/2008" android:summary="03/10/2008"
/> />
<PreferenceScreen android:key="timezone" <PreferenceScreen
android:fragment="com.android.settings.ZonePicker"
android:key="timezone"
android:title="@string/date_time_set_timezone" android:title="@string/date_time_set_timezone"
android:summary="GMT-8:00" android:summary="GMT-8:00"
/> />

View File

@@ -41,8 +41,7 @@ import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.TimeZone; import java.util.TimeZone;
public class DateTimeSettings public class DateTimeSettings extends SettingsPreferenceFragment
extends SettingsPreferenceFragment
implements OnSharedPreferenceChangeListener, implements OnSharedPreferenceChangeListener,
TimePickerDialog.OnTimeSetListener , DatePickerDialog.OnDateSetListener { TimePickerDialog.OnTimeSetListener , DatePickerDialog.OnDateSetListener {
@@ -152,6 +151,7 @@ public class DateTimeSettings
mDateFormat.setSummary(shortDateFormat.format(dummyDate)); mDateFormat.setSummary(shortDateFormat.format(dummyDate));
} }
@Override
public void onDateSet(DatePicker view, int year, int month, int day) { public void onDateSet(DatePicker view, int year, int month, int day) {
Calendar c = Calendar.getInstance(); Calendar c = Calendar.getInstance();
@@ -166,6 +166,7 @@ public class DateTimeSettings
updateTimeAndDateDisplay(); updateTimeAndDateDisplay();
} }
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) { public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
Calendar c = Calendar.getInstance(); Calendar c = Calendar.getInstance();
@@ -183,6 +184,7 @@ public class DateTimeSettings
// SystemClock time. // SystemClock time.
} }
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
if (key.equals(KEY_DATE_FORMAT)) { if (key.equals(KEY_DATE_FORMAT)) {
String format = preferences.getString(key, String format = preferences.getString(key,
@@ -274,12 +276,8 @@ public class DateTimeSettings
set24Hour(((CheckBoxPreference)mTime24Pref).isChecked()); set24Hour(((CheckBoxPreference)mTime24Pref).isChecked());
updateTimeAndDateDisplay(); updateTimeAndDateDisplay();
timeUpdated(); timeUpdated();
} else if (preference == mTimeZone) {
Intent intent = new Intent();
intent.setClass(getActivity(), ZoneList.class);
startActivityForResult(intent, 0);
} }
return false; return super.onPreferenceTreeClick(preferenceScreen, preference);
} }
@Override @Override

View File

@@ -274,10 +274,6 @@ public class DateTimeSettingsActivity
set24Hour(((CheckBoxPreference)mTime24Pref).isChecked()); set24Hour(((CheckBoxPreference)mTime24Pref).isChecked());
updateTimeAndDateDisplay(); updateTimeAndDateDisplay();
timeUpdated(); timeUpdated();
} else if (preference == mTimeZone) {
Intent intent = new Intent();
intent.setClass(this, ZoneList.class);
startActivityForResult(intent, 0);
} }
return false; return false;
} }

View File

@@ -21,7 +21,8 @@ import android.view.View;
import android.view.Window; import android.view.Window;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
public class DateTimeSettingsSetupWizard extends DateTimeSettingsActivity implements OnClickListener { public class DateTimeSettingsSetupWizard extends DateTimeSettingsActivity
implements OnClickListener {
private View mNextButton; private View mNextButton;
@Override @Override

View File

@@ -1,273 +0,0 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings;
import android.app.AlarmManager;
import android.app.ListActivity;
import android.content.Context;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import org.xmlpull.v1.XmlPullParserException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
/**
* This activity displays a list of time zones that match a filter string
* such as "Africa", "Europe", etc. Choosing an item from the list will set
* the time zone. Pressing Back without choosing from the list will not
* result in a change in the time zone setting.
*/
public class ZoneList extends ListActivity {
private static final String TAG = "ZoneList";
private static final String KEY_ID = "id";
private static final String KEY_DISPLAYNAME = "name";
private static final String KEY_GMT = "gmt";
private static final String KEY_OFFSET = "offset";
private static final String XMLTAG_TIMEZONE = "timezone";
private static final int HOURS_1 = 60 * 60000;
private static final int HOURS_24 = 24 * HOURS_1;
private static final int HOURS_HALF = HOURS_1 / 2;
private static final int MENU_TIMEZONE = Menu.FIRST+1;
private static final int MENU_ALPHABETICAL = Menu.FIRST;
// Initial focus position
private int mDefault;
private boolean mSortedByTimezone;
private SimpleAdapter mTimezoneSortedAdapter;
private SimpleAdapter mAlphabeticalAdapter;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
String[] from = new String[] {KEY_DISPLAYNAME, KEY_GMT};
int[] to = new int[] {android.R.id.text1, android.R.id.text2};
MyComparator comparator = new MyComparator(KEY_OFFSET);
List<HashMap> timezoneSortedList = getZones();
Collections.sort(timezoneSortedList, comparator);
mTimezoneSortedAdapter = new SimpleAdapter(this,
(List) timezoneSortedList,
android.R.layout.simple_list_item_2,
from,
to);
List<HashMap> alphabeticalList = new ArrayList<HashMap>(timezoneSortedList);
comparator.setSortingKey(KEY_DISPLAYNAME);
Collections.sort(alphabeticalList, comparator);
mAlphabeticalAdapter = new SimpleAdapter(this,
(List) alphabeticalList,
android.R.layout.simple_list_item_2,
from,
to);
// Sets the adapter
setSorting(true);
// If current timezone is in this list, move focus to it
setSelection(mDefault);
// Assume user may press Back
setResult(RESULT_CANCELED);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, MENU_ALPHABETICAL, 0, R.string.zone_list_menu_sort_alphabetically)
.setIcon(android.R.drawable.ic_menu_sort_alphabetically);
menu.add(0, MENU_TIMEZONE, 0, R.string.zone_list_menu_sort_by_timezone)
.setIcon(R.drawable.ic_menu_3d_globe);
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (mSortedByTimezone) {
menu.findItem(MENU_TIMEZONE).setVisible(false);
menu.findItem(MENU_ALPHABETICAL).setVisible(true);
} else {
menu.findItem(MENU_TIMEZONE).setVisible(true);
menu.findItem(MENU_ALPHABETICAL).setVisible(false);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_TIMEZONE:
setSorting(true);
return true;
case MENU_ALPHABETICAL:
setSorting(false);
return true;
default:
return false;
}
}
private void setSorting(boolean timezone) {
setListAdapter(timezone ? mTimezoneSortedAdapter : mAlphabeticalAdapter);
mSortedByTimezone = timezone;
}
private List<HashMap> getZones() {
List<HashMap> myData = new ArrayList<HashMap>();
long date = Calendar.getInstance().getTimeInMillis();
try {
XmlResourceParser xrp = getResources().getXml(R.xml.timezones);
while (xrp.next() != XmlResourceParser.START_TAG)
continue;
xrp.next();
while (xrp.getEventType() != XmlResourceParser.END_TAG) {
while (xrp.getEventType() != XmlResourceParser.START_TAG) {
if (xrp.getEventType() == XmlResourceParser.END_DOCUMENT) {
return myData;
}
xrp.next();
}
if (xrp.getName().equals(XMLTAG_TIMEZONE)) {
String id = xrp.getAttributeValue(0);
String displayName = xrp.nextText();
addItem(myData, id, displayName, date);
}
while (xrp.getEventType() != XmlResourceParser.END_TAG) {
xrp.next();
}
xrp.next();
}
xrp.close();
} catch (XmlPullParserException xppe) {
Log.e(TAG, "Ill-formatted timezones.xml file");
} catch (java.io.IOException ioe) {
Log.e(TAG, "Unable to read timezones.xml file");
}
return myData;
}
protected void addItem(List<HashMap> myData, String id, String displayName,
long date) {
HashMap map = new HashMap();
map.put(KEY_ID, id);
map.put(KEY_DISPLAYNAME, displayName);
TimeZone tz = TimeZone.getTimeZone(id);
int offset = tz.getOffset(date);
int p = Math.abs(offset);
StringBuilder name = new StringBuilder();
name.append("GMT");
if (offset < 0) {
name.append('-');
} else {
name.append('+');
}
name.append(p / (HOURS_1));
name.append(':');
int min = p / 60000;
min %= 60;
if (min < 10) {
name.append('0');
}
name.append(min);
map.put(KEY_GMT, name.toString());
map.put(KEY_OFFSET, offset);
if (id.equals(TimeZone.getDefault().getID())) {
mDefault = myData.size();
}
myData.add(map);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Map map = (Map) l.getItemAtPosition(position);
// Update the system timezone value
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.setTimeZone((String) map.get(KEY_ID));
setResult(RESULT_OK);
finish();
}
private static class MyComparator implements Comparator<HashMap> {
private String mSortingKey;
public MyComparator(String sortingKey) {
mSortingKey = sortingKey;
}
public void setSortingKey(String sortingKey) {
mSortingKey = sortingKey;
}
public int compare(HashMap map1, HashMap map2) {
Object value1 = map1.get(mSortingKey);
Object value2 = map2.get(mSortingKey);
/*
* This should never happen, but just in-case, put non-comparable
* items at the end.
*/
if (!isComparable(value1)) {
return isComparable(value2) ? 1 : 0;
} else if (!isComparable(value2)) {
return -1;
}
return ((Comparable) value1).compareTo(value2);
}
private boolean isComparable(Object value) {
return (value != null) && (value instanceof Comparable);
}
}
}

View File

@@ -16,55 +16,261 @@
package com.android.settings; package com.android.settings;
import android.app.ListActivity; import android.app.Activity;
import android.content.Intent; import android.app.AlarmManager;
import android.app.ListFragment;
import android.content.Context;
import android.content.res.XmlResourceParser;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView; import android.widget.ListView;
import android.widget.SimpleAdapter;
import org.xmlpull.v1.XmlPullParserException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TimeZone;
public class ZonePicker extends ListActivity { /**
* The class displaying a list of time zones that match a filter string
* such as "Africa", "Europe", etc. Choosing an item from the list will set
* the time zone. Pressing Back without choosing from the list will not
* result in a change in the time zone setting.
*/
public class ZonePicker extends ListFragment {
private static final String TAG = "ZonePicker";
private ArrayAdapter<CharSequence> mFilterAdapter; public static interface ZoneSelectionListener {
// You can add any argument if you really need it...
@Override public void onZoneSelected();
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mFilterAdapter = ArrayAdapter.createFromResource(this,
R.array.timezone_filters, android.R.layout.simple_list_item_1);
setListAdapter(mFilterAdapter);
} }
protected void addItem(List<Map> data, String name, String zone) { private static final String KEY_ID = "id";
HashMap temp = new HashMap(); private static final String KEY_DISPLAYNAME = "name";
temp.put("title", name); private static final String KEY_GMT = "gmt";
temp.put("zone", zone); private static final String KEY_OFFSET = "offset";
data.add(temp); private static final String XMLTAG_TIMEZONE = "timezone";
private static final int HOURS_1 = 60 * 60000;
private static final int MENU_TIMEZONE = Menu.FIRST+1;
private static final int MENU_ALPHABETICAL = Menu.FIRST;
// Initial focus position
private int mDefault;
private boolean mSortedByTimezone;
private SimpleAdapter mTimezoneSortedAdapter;
private SimpleAdapter mAlphabeticalAdapter;
private ZoneSelectionListener mListener;
@Override
public void onActivityCreated(Bundle savedInstanseState) {
super.onActivityCreated(savedInstanseState);
final String[] from = new String[] {KEY_DISPLAYNAME, KEY_GMT};
final int[] to = new int[] {android.R.id.text1, android.R.id.text2};
MyComparator comparator = new MyComparator(KEY_OFFSET);
Activity activity = getActivity();
List<HashMap> timezoneSortedList = getZones();
Collections.sort(timezoneSortedList, comparator);
mTimezoneSortedAdapter = new SimpleAdapter(activity,
(List) timezoneSortedList,
android.R.layout.simple_list_item_2,
from,
to);
List<HashMap> alphabeticalList = new ArrayList<HashMap>(timezoneSortedList);
comparator.setSortingKey(KEY_DISPLAYNAME);
Collections.sort(alphabeticalList, comparator);
mAlphabeticalAdapter = new SimpleAdapter(getActivity(),
(List) alphabeticalList,
android.R.layout.simple_list_item_2,
from,
to);
// Sets the adapter
setSorting(true);
// If current timezone is in this list, move focus to it
setSelection(mDefault);
} }
@Override @Override
protected void onListItemClick(ListView l, View v, int position, long id) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
String filter = (String) mFilterAdapter.getItem(position); menu.add(0, MENU_ALPHABETICAL, 0, R.string.zone_list_menu_sort_alphabetically)
// If All is chosen, reset the filter .setIcon(android.R.drawable.ic_menu_sort_alphabetically);
if (filter.equals("All")) { menu.add(0, MENU_TIMEZONE, 0, R.string.zone_list_menu_sort_by_timezone)
filter = null; .setIcon(R.drawable.ic_menu_3d_globe);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
if (mSortedByTimezone) {
menu.findItem(MENU_TIMEZONE).setVisible(false);
menu.findItem(MENU_ALPHABETICAL).setVisible(true);
} else {
menu.findItem(MENU_TIMEZONE).setVisible(true);
menu.findItem(MENU_ALPHABETICAL).setVisible(false);
} }
Intent zoneList = new Intent();
zoneList.setClass(this, ZoneList.class);
zoneList.putExtra("filter", filter);
startActivityForResult(zoneList, 0);
} }
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { public boolean onOptionsItemSelected(MenuItem item) {
// If subactivity has resulted in a timezone selection, close this act. switch (item.getItemId()) {
if (resultCode == RESULT_OK) {
finish(); case MENU_TIMEZONE:
setSorting(true);
return true;
case MENU_ALPHABETICAL:
setSorting(false);
return true;
default:
return false;
}
}
public void setZoneSelectionListener(ZoneSelectionListener listener) {
mListener = listener;
}
private void setSorting(boolean timezone) {
setListAdapter(timezone ? mTimezoneSortedAdapter : mAlphabeticalAdapter);
mSortedByTimezone = timezone;
}
private List<HashMap> getZones() {
List<HashMap> myData = new ArrayList<HashMap>();
long date = Calendar.getInstance().getTimeInMillis();
try {
XmlResourceParser xrp = getActivity().getResources().getXml(R.xml.timezones);
while (xrp.next() != XmlResourceParser.START_TAG)
continue;
xrp.next();
while (xrp.getEventType() != XmlResourceParser.END_TAG) {
while (xrp.getEventType() != XmlResourceParser.START_TAG) {
if (xrp.getEventType() == XmlResourceParser.END_DOCUMENT) {
return myData;
}
xrp.next();
}
if (xrp.getName().equals(XMLTAG_TIMEZONE)) {
String id = xrp.getAttributeValue(0);
String displayName = xrp.nextText();
addItem(myData, id, displayName, date);
}
while (xrp.getEventType() != XmlResourceParser.END_TAG) {
xrp.next();
}
xrp.next();
}
xrp.close();
} catch (XmlPullParserException xppe) {
Log.e(TAG, "Ill-formatted timezones.xml file");
} catch (java.io.IOException ioe) {
Log.e(TAG, "Unable to read timezones.xml file");
}
return myData;
}
protected void addItem(List<HashMap> myData, String id, String displayName,
long date) {
HashMap map = new HashMap();
map.put(KEY_ID, id);
map.put(KEY_DISPLAYNAME, displayName);
TimeZone tz = TimeZone.getTimeZone(id);
int offset = tz.getOffset(date);
int p = Math.abs(offset);
StringBuilder name = new StringBuilder();
name.append("GMT");
if (offset < 0) {
name.append('-');
} else {
name.append('+');
}
name.append(p / (HOURS_1));
name.append(':');
int min = p / 60000;
min %= 60;
if (min < 10) {
name.append('0');
}
name.append(min);
map.put(KEY_GMT, name.toString());
map.put(KEY_OFFSET, offset);
if (id.equals(TimeZone.getDefault().getID())) {
mDefault = myData.size();
}
myData.add(map);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
Map map = (Map) l.getItemAtPosition(position);
// Update the system timezone value
final Activity activity = getActivity();
AlarmManager alarm = (AlarmManager) activity.getSystemService(Context.ALARM_SERVICE);
alarm.setTimeZone((String) map.get(KEY_ID));
if (mListener != null) {
mListener.onZoneSelected();
}
}
private static class MyComparator implements Comparator<HashMap> {
private String mSortingKey;
public MyComparator(String sortingKey) {
mSortingKey = sortingKey;
}
public void setSortingKey(String sortingKey) {
mSortingKey = sortingKey;
}
public int compare(HashMap map1, HashMap map2) {
Object value1 = map1.get(mSortingKey);
Object value2 = map2.get(mSortingKey);
/*
* This should never happen, but just in-case, put non-comparable
* items at the end.
*/
if (!isComparable(value1)) {
return isComparable(value2) ? 1 : 0;
} else if (!isComparable(value2)) {
return -1;
}
return ((Comparable) value1).compareTo(value2);
}
private boolean isComparable(Object value) {
return (value != null) && (value instanceof Comparable);
} }
} }
} }