1afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project/* 2afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 3afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * 4afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * you may not use this file except in compliance with the License. 6afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * You may obtain a copy of the License at 7afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * 8afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * 10afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * See the License for the specific language governing permissions and 14afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project * limitations under the License. 15afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project */ 16afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 17afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectpackage com.android.settings; 18afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 190f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport android.app.Activity; 200f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport android.app.AlarmManager; 210f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport android.app.ListFragment; 220f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport android.content.Context; 230f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport android.content.res.XmlResourceParser; 24afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.os.Bundle; 250f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport android.util.Log; 260f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport android.view.Menu; 270f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport android.view.MenuInflater; 280f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport android.view.MenuItem; 29afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.view.View; 30afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport android.widget.ListView; 310f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport android.widget.SimpleAdapter; 32afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 330f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport org.xmlpull.v1.XmlPullParserException; 340f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 350f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport java.util.ArrayList; 360f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport java.util.Calendar; 370f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport java.util.Collections; 380f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport java.util.Comparator; 39afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.HashMap; 40afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.List; 41afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Projectimport java.util.Map; 420f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawaimport java.util.TimeZone; 430f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 440f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa/** 450f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa * The class displaying a list of time zones that match a filter string 460f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa * such as "Africa", "Europe", etc. Choosing an item from the list will set 470f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa * the time zone. Pressing Back without choosing from the list will not 480f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa * result in a change in the time zone setting. 490f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa */ 500f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawapublic class ZonePicker extends ListFragment { 510f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa private static final String TAG = "ZonePicker"; 520f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 530f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa public static interface ZoneSelectionListener { 540f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa // You can add any argument if you really need it... 5571cc548f7ee51ff77a2c1dfb5da7a3f7b6c55fd5Daisuke Miyakawa public void onZoneSelected(TimeZone tz); 560f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 570f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 582571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa private static final String KEY_ID = "id"; // value: String 592571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa private static final String KEY_DISPLAYNAME = "name"; // value: String 602571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa private static final String KEY_GMT = "gmt"; // value: String 612571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa private static final String KEY_OFFSET = "offset"; // value: int (Integer) 620f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa private static final String XMLTAG_TIMEZONE = "timezone"; 630f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 640f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa private static final int HOURS_1 = 60 * 60000; 650f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 660f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa private static final int MENU_TIMEZONE = Menu.FIRST+1; 670f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa private static final int MENU_ALPHABETICAL = Menu.FIRST; 680f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 690f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa private boolean mSortedByTimezone; 700f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 710f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa private SimpleAdapter mTimezoneSortedAdapter; 720f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa private SimpleAdapter mAlphabeticalAdapter; 730f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 740f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa private ZoneSelectionListener mListener; 750f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 762571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa /** 772571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa * Constructs an adapter with TimeZone list. Sorted by TimeZone in default. 782571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa * 792571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa * @param sortedByName use Name for sorting the list. 802571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa */ 812571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa public static SimpleAdapter constructTimezoneAdapter(Context context, 822571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa boolean sortedByName) { 830688f251af533c09682c791ae20834ab7854d7d7Daisuke Miyakawa return constructTimezoneAdapter(context, sortedByName, 840688f251af533c09682c791ae20834ab7854d7d7Daisuke Miyakawa android.R.layout.simple_list_item_2); 850688f251af533c09682c791ae20834ab7854d7d7Daisuke Miyakawa } 860688f251af533c09682c791ae20834ab7854d7d7Daisuke Miyakawa 870688f251af533c09682c791ae20834ab7854d7d7Daisuke Miyakawa /** 880688f251af533c09682c791ae20834ab7854d7d7Daisuke Miyakawa * Constructs an adapter with TimeZone list. Sorted by TimeZone in default. 890688f251af533c09682c791ae20834ab7854d7d7Daisuke Miyakawa * 900688f251af533c09682c791ae20834ab7854d7d7Daisuke Miyakawa * @param sortedByName use Name for sorting the list. 910688f251af533c09682c791ae20834ab7854d7d7Daisuke Miyakawa */ 920688f251af533c09682c791ae20834ab7854d7d7Daisuke Miyakawa public static SimpleAdapter constructTimezoneAdapter(Context context, 930688f251af533c09682c791ae20834ab7854d7d7Daisuke Miyakawa boolean sortedByName, int layoutId) { 940f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa final String[] from = new String[] {KEY_DISPLAYNAME, KEY_GMT}; 950f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa final int[] to = new int[] {android.R.id.text1, android.R.id.text2}; 96afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 972571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final String sortKey = (sortedByName ? KEY_DISPLAYNAME : KEY_OFFSET); 982571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final MyComparator comparator = new MyComparator(sortKey); 992571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final List<HashMap<String, Object>> sortedList = getZones(context); 1002571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa Collections.sort(sortedList, comparator); 1012571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final SimpleAdapter adapter = new SimpleAdapter(context, 1022571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa sortedList, 1030688f251af533c09682c791ae20834ab7854d7d7Daisuke Miyakawa layoutId, 1040f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa from, 1050f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa to); 1060f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 1072571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa return adapter; 1082571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa } 1092571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa 1102571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa /** 1112571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa * Searches {@link TimeZone} from the given {@link SimpleAdapter} object, and returns 1122571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa * the index for the TimeZone. 1132571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa * 1142571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa * @param adapter SimpleAdapter constructed by 1152571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa * {@link #constructTimezoneAdapter(Context, boolean)}. 1162571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa * @param tz TimeZone to be searched. 1172571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa * @return Index for the given TimeZone. -1 when there's no corresponding list item. 1182571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa * returned. 1192571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa */ 1202571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa public static int getTimeZoneIndex(SimpleAdapter adapter, TimeZone tz) { 1212571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final String defaultId = tz.getID(); 1222571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final int listSize = adapter.getCount(); 1232571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa for (int i = 0; i < listSize; i++) { 1242571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa // Using HashMap<String, Object> induces unnecessary warning. 1252571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final HashMap<?,?> map = (HashMap<?,?>)adapter.getItem(i); 1262571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final String id = (String)map.get(KEY_ID); 1272571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa if (defaultId.equals(id)) { 1282571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa // If current timezone is in this list, move focus to it 1292571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa return i; 1302571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa } 1312571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa } 1322571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa return -1; 1332571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa } 1342571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa 1352571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa /** 1362571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa * @param item one of items in adapters. The adapter should be constructed by 1372571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa * {@link #constructTimezoneAdapter(Context, boolean)}. 1382571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa * @return TimeZone object corresponding to the item. 1392571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa */ 1402571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa public static TimeZone obtainTimeZoneFromItem(Object item) { 1412571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa return TimeZone.getTimeZone((String)((Map<?, ?>)item).get(KEY_ID)); 1422571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa } 1432571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa 1442571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa @Override 1452571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa public void onActivityCreated(Bundle savedInstanseState) { 1462571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa super.onActivityCreated(savedInstanseState); 1472571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa 1482571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final Activity activity = getActivity(); 1492571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa mTimezoneSortedAdapter = constructTimezoneAdapter(activity, false); 1502571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa mAlphabeticalAdapter = constructTimezoneAdapter(activity, true); 1510f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 1520f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa // Sets the adapter 1530f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa setSorting(true); 1541e9d497e2b0a3d00e83372d536b79c9ec0646b9dDaisuke Miyakawa setHasOptionsMenu(true); 1550f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 156afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 157afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project @Override 1580f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 1590f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa menu.add(0, MENU_ALPHABETICAL, 0, R.string.zone_list_menu_sort_alphabetically) 1600f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa .setIcon(android.R.drawable.ic_menu_sort_alphabetically); 1610f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa menu.add(0, MENU_TIMEZONE, 0, R.string.zone_list_menu_sort_by_timezone) 1620f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa .setIcon(R.drawable.ic_menu_3d_globe); 1630f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa super.onCreateOptionsMenu(menu, inflater); 164afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 1650f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 1660f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa @Override 1670f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa public void onPrepareOptionsMenu(Menu menu) { 1680f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa if (mSortedByTimezone) { 1690f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa menu.findItem(MENU_TIMEZONE).setVisible(false); 1700f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa menu.findItem(MENU_ALPHABETICAL).setVisible(true); 1710f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } else { 1720f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa menu.findItem(MENU_TIMEZONE).setVisible(true); 1730f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa menu.findItem(MENU_ALPHABETICAL).setVisible(false); 1740f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 175afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 176afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project 177afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project @Override 1780f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa public boolean onOptionsItemSelected(MenuItem item) { 1790f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa switch (item.getItemId()) { 1800f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 1810f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa case MENU_TIMEZONE: 1820f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa setSorting(true); 1830f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa return true; 1840f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 1850f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa case MENU_ALPHABETICAL: 1860f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa setSorting(false); 1870f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa return true; 1880f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 1890f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa default: 1900f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa return false; 1910f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 1920f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 1930f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 1940f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa public void setZoneSelectionListener(ZoneSelectionListener listener) { 1950f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa mListener = listener; 1960f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 1970f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 1982571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa private void setSorting(boolean sortByTimezone) { 1992571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final SimpleAdapter adapter = 2002571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa sortByTimezone ? mTimezoneSortedAdapter : mAlphabeticalAdapter; 2012571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa setListAdapter(adapter); 2022571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa mSortedByTimezone = sortByTimezone; 2032571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final int defaultIndex = getTimeZoneIndex(adapter, TimeZone.getDefault()); 2042571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa if (defaultIndex >= 0) { 2052571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa setSelection(defaultIndex); 2062571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa } 2070f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 2080f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 2092571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa private static List<HashMap<String, Object>> getZones(Context context) { 2102571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final List<HashMap<String, Object>> myData = new ArrayList<HashMap<String, Object>>(); 2112571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final long date = Calendar.getInstance().getTimeInMillis(); 2120f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa try { 2132571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa XmlResourceParser xrp = context.getResources().getXml(R.xml.timezones); 2140f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa while (xrp.next() != XmlResourceParser.START_TAG) 2150f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa continue; 2160f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa xrp.next(); 2170f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa while (xrp.getEventType() != XmlResourceParser.END_TAG) { 2180f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa while (xrp.getEventType() != XmlResourceParser.START_TAG) { 2190f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa if (xrp.getEventType() == XmlResourceParser.END_DOCUMENT) { 2200f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa return myData; 2210f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 2220f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa xrp.next(); 2230f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 2240f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa if (xrp.getName().equals(XMLTAG_TIMEZONE)) { 2250f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa String id = xrp.getAttributeValue(0); 2260f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa String displayName = xrp.nextText(); 2270f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa addItem(myData, id, displayName, date); 2280f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 2290f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa while (xrp.getEventType() != XmlResourceParser.END_TAG) { 2300f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa xrp.next(); 2310f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 2320f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa xrp.next(); 2330f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 2340f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa xrp.close(); 2350f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } catch (XmlPullParserException xppe) { 2360f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa Log.e(TAG, "Ill-formatted timezones.xml file"); 2370f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } catch (java.io.IOException ioe) { 2380f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa Log.e(TAG, "Unable to read timezones.xml file"); 2390f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 2400f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 2410f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa return myData; 2420f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 2430f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 2442571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa private static void addItem( 2452571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa List<HashMap<String, Object>> myData, String id, String displayName, long date) { 2462571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final HashMap<String, Object> map = new HashMap<String, Object>(); 2470f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa map.put(KEY_ID, id); 2480f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa map.put(KEY_DISPLAYNAME, displayName); 2492571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final TimeZone tz = TimeZone.getTimeZone(id); 2502571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final int offset = tz.getOffset(date); 2512571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final int p = Math.abs(offset); 2522571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final StringBuilder name = new StringBuilder(); 2530f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa name.append("GMT"); 2540f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 2550f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa if (offset < 0) { 2560f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa name.append('-'); 2570f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } else { 2580f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa name.append('+'); 2590f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 2600f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 2610f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa name.append(p / (HOURS_1)); 2620f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa name.append(':'); 2630f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 2640f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa int min = p / 60000; 2650f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa min %= 60; 2660f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 2670f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa if (min < 10) { 2680f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa name.append('0'); 2690f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 2700f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa name.append(min); 2710f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 2720f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa map.put(KEY_GMT, name.toString()); 2730f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa map.put(KEY_OFFSET, offset); 2740f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 2750f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa myData.add(map); 276afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 2770f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 278afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project @Override 2792571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa public void onListItemClick(ListView listView, View v, int position, long id) { 2802571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final Map<?, ?> map = (Map<?, ?>)listView.getItemAtPosition(position); 2812571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final String tzId = (String) map.get(KEY_ID); 2822571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa 2830f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa // Update the system timezone value 2840f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa final Activity activity = getActivity(); 2852571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa final AlarmManager alarm = (AlarmManager) activity.getSystemService(Context.ALARM_SERVICE); 28671cc548f7ee51ff77a2c1dfb5da7a3f7b6c55fd5Daisuke Miyakawa alarm.setTimeZone(tzId); 28771cc548f7ee51ff77a2c1dfb5da7a3f7b6c55fd5Daisuke Miyakawa final TimeZone tz = TimeZone.getTimeZone(tzId); 2880f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa if (mListener != null) { 28971cc548f7ee51ff77a2c1dfb5da7a3f7b6c55fd5Daisuke Miyakawa mListener.onZoneSelected(tz); 29071cc548f7ee51ff77a2c1dfb5da7a3f7b6c55fd5Daisuke Miyakawa } else { 29171cc548f7ee51ff77a2c1dfb5da7a3f7b6c55fd5Daisuke Miyakawa getActivity().onBackPressed(); 2920f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 2930f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 2940f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 2952571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa private static class MyComparator implements Comparator<HashMap<?, ?>> { 2960f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa private String mSortingKey; 2970f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 2980f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa public MyComparator(String sortingKey) { 2990f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa mSortingKey = sortingKey; 3000f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 3010f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 3020f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa public void setSortingKey(String sortingKey) { 3030f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa mSortingKey = sortingKey; 304afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project } 3050f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 3062571f0dcb1cc96b7220687aff6fcddc623b57c3cDaisuke Miyakawa public int compare(HashMap<?, ?> map1, HashMap<?, ?> map2) { 3070f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa Object value1 = map1.get(mSortingKey); 3080f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa Object value2 = map2.get(mSortingKey); 3090f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 3100f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa /* 3110f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa * This should never happen, but just in-case, put non-comparable 3120f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa * items at the end. 3130f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa */ 3140f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa if (!isComparable(value1)) { 3150f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa return isComparable(value2) ? 1 : 0; 3160f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } else if (!isComparable(value2)) { 3170f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa return -1; 3180f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 3190f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 3200f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa return ((Comparable) value1).compareTo(value2); 3210f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 3220f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa 3230f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa private boolean isComparable(Object value) { 3240f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa return (value != null) && (value instanceof Comparable); 3250f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 3260f4f2f3a81f2a6d7100b4cff0d8de062cb2bc8f6Daisuke Miyakawa } 327afc4ab2ffbb8327ddce9907961295a32cbf49d0fThe Android Open Source Project} 328