1732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov/* 2732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project 3732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov * 4732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License"); 5732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov * you may not use this file except in compliance with the License. 6732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov * You may obtain a copy of the License at 7732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov * 8732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov * http://www.apache.org/licenses/LICENSE-2.0 9732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov * 10732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov * Unless required by applicable law or agreed to in writing, software 11732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS, 12732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov * See the License for the specific language governing permissions and 14732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov * limitations under the License. 15732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov */ 16732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikovpackage com.android.contacts.list; 17732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov 1893a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikovimport com.android.common.widget.CompositeCursorAdapter.Partition; 1968e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikovimport com.android.contacts.R; 206cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuanimport com.android.contacts.util.ContactLoaderUtils; 21753f8f6fde5a4f74181310593acebee94a014fe2Dmitri Plotnikovimport com.android.contacts.widget.AutoScrollListView; 2268e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov 23d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikovimport android.app.Activity; 24892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikovimport android.content.ContentResolver; 257d402246e9ac26e05eeb25528bc74083412d1a5aDmitri Plotnikovimport android.content.ContentUris; 26cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikovimport android.content.Loader; 276e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikovimport android.content.SharedPreferences; 28d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikovimport android.content.SharedPreferences.Editor; 29cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikovimport android.database.Cursor; 30732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikovimport android.net.Uri; 316cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuanimport android.os.AsyncTask; 32cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikovimport android.os.Bundle; 33d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikovimport android.os.Handler; 34d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikovimport android.os.Message; 35d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikovimport android.preference.PreferenceManager; 367ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikovimport android.provider.ContactsContract; 37cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikovimport android.provider.ContactsContract.Contacts; 387ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikovimport android.provider.ContactsContract.Directory; 397ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikovimport android.text.TextUtils; 40264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikovimport android.util.Log; 41732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov 42892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikovimport java.util.List; 43892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov 44732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov/** 45416b569901ce4c577c1f76c3f29496d1adab29e1Dmitri Plotnikov * Fragment containing a contact list used for browsing (as compared to 46416b569901ce4c577c1f76c3f29496d1adab29e1Dmitri Plotnikov * picking a contact with one of the PICK intents). 47732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov */ 48238d9847d8f2ace658fb7337c8847a2088ddc9d1Dmitri Plotnikovpublic abstract class ContactBrowseListFragment extends 49238d9847d8f2ace658fb7337c8847a2088ddc9d1Dmitri Plotnikov ContactEntryListFragment<ContactListAdapter> { 50732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov 51264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov private static final String TAG = "ContactList"; 52264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov 53cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov private static final String KEY_SELECTED_URI = "selectedUri"; 546e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov private static final String KEY_SELECTION_VERIFIED = "selectionVerified"; 55264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov private static final String KEY_FILTER = "filter"; 56682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov private static final String KEY_LAST_SELECTED_POSITION = "lastSelected"; 57d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 58d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private static final String PERSISTENT_SELECTION_PREFIX = "defaultContactBrowserSelection"; 59d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 60d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov /** 61d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov * The id for a delayed message that triggers automatic selection of the first 62d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov * found contact in search mode. 63d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov */ 64d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private static final int MESSAGE_AUTOSELECT_FIRST_FOUND_CONTACT = 1; 65d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 66d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov /** 67d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov * The delay that is used for automatically selecting the first found contact. 68d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov */ 69d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private static final int DELAY_AUTOSELECT_FIRST_FOUND_CONTACT_MILLIS = 500; 70d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 71d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov /** 72d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov * The minimum number of characters in the search query that is required 73d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov * before we automatically select the first found contact. 74d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov */ 75d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private static final int AUTOSELECT_FIRST_FOUND_CONTACT_MIN_QUERY_LENGTH = 2; 76d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 77d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private SharedPreferences mPrefs; 78d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private Handler mHandler; 793c69e21d278b1f99b9af817f8459044215238938Dmitri Plotnikov 80d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private boolean mStartedLoading; 81d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private boolean mSelectionRequired; 82d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private boolean mSelectionToScreenRequested; 83d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private boolean mSmoothScrollRequested; 84d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private boolean mSelectionPersistenceRequested; 85cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov private Uri mSelectedContactUri; 867ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov private long mSelectedContactDirectoryId; 877ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov private String mSelectedContactLookupKey; 887d402246e9ac26e05eeb25528bc74083412d1a5aDmitri Plotnikov private long mSelectedContactId; 896e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov private boolean mSelectionVerified; 90682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov private int mLastSelectedPosition = -1; 91892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov private boolean mRefreshingContactUri; 92d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private ContactListFilter mFilter; 93d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private String mPersistentSelectionPrefix = PERSISTENT_SELECTION_PREFIX; 94cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov 956e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov protected OnContactBrowserActionListener mListener; 966cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan private ContactLookupTask mContactLookupTask; 97732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov 986cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan private final class ContactLookupTask extends AsyncTask<Void, Void, Uri> { 995ffd9298a6cd842c5bfb2612a2eda798fa92b7adDmitri Plotnikov 1006cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan private final Uri mUri; 1016cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan private boolean mIsCancelled; 102892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov 1036cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan public ContactLookupTask(Uri uri) { 1046cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan mUri = uri; 1055ffd9298a6cd842c5bfb2612a2eda798fa92b7adDmitri Plotnikov } 1065ffd9298a6cd842c5bfb2612a2eda798fa92b7adDmitri Plotnikov 1075ffd9298a6cd842c5bfb2612a2eda798fa92b7adDmitri Plotnikov @Override 1086cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan protected Uri doInBackground(Void... args) { 1096cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan Cursor cursor = null; 1106cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan try { 1116cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan final ContentResolver resolver = getContext().getContentResolver(); 1126cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan final Uri uriCurrentFormat = ContactLoaderUtils.ensureIsContactUri(resolver, mUri); 1136cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan cursor = resolver.query(uriCurrentFormat, 1146cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan new String[] { Contacts._ID, Contacts.LOOKUP_KEY }, null, null, null); 1156cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan 1166cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan if (cursor != null && cursor.moveToFirst()) { 1176cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan final long contactId = cursor.getLong(0); 1186cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan final String lookupKey = cursor.getString(1); 1196cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan if (contactId != 0 && !TextUtils.isEmpty(lookupKey)) { 1206cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan return Contacts.getLookupUri(contactId, lookupKey); 1216cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan } 1228773bcb491d18e88b4e3d1f9cf7c57f6bc8e69edDmitri Plotnikov } 123892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov 1246cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan Log.e(TAG, "Error: No contact ID or lookup key for contact " + mUri); 1256cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan return null; 1266cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan } finally { 1276cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan if (cursor != null) { 1286cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan cursor.close(); 1296cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan } 130892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov } 1316cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan } 132892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov 1336cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan public void cancel() { 1346cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan super.cancel(true); 1356cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan // Use a flag to keep track of whether the {@link AsyncTask} was cancelled or not in 1366cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan // order to ensure onPostExecute() is not executed after the cancel request. The flag is 1376cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan // necessary because {@link AsyncTask} still calls onPostExecute() if the cancel request 1386cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan // came after the worker thread was finished. 1396cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan mIsCancelled = true; 1406cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan } 141a5a2744ab8102cf4ff5fbd3e1fa074a45257b3ddDmitri Plotnikov 1426cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan @Override 1436cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan protected void onPostExecute(Uri uri) { 1446cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan // Make sure the {@link Fragment} is at least still attached to the {@link Activity} 145db90ba16b3d99819e2be961ee6ecf0d532237408Katherine Kuan // before continuing. Null URIs should still be allowed so that the list can be 146db90ba16b3d99819e2be961ee6ecf0d532237408Katherine Kuan // refreshed and a default contact can be selected (i.e. the case of deleted 147db90ba16b3d99819e2be961ee6ecf0d532237408Katherine Kuan // contacts). 148db90ba16b3d99819e2be961ee6ecf0d532237408Katherine Kuan if (mIsCancelled || !isAdded()) { 1496cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan return; 1506cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan } 151db90ba16b3d99819e2be961ee6ecf0d532237408Katherine Kuan onContactUriQueryFinished(uri); 1525ffd9298a6cd842c5bfb2612a2eda798fa92b7adDmitri Plotnikov } 153892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov } 154892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov 1555251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov private boolean mDelaySelection; 1565251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov 157d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private Handler getHandler() { 158d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (mHandler == null) { 159d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mHandler = new Handler() { 160d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov @Override 161d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov public void handleMessage(Message msg) { 162d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov switch (msg.what) { 163d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov case MESSAGE_AUTOSELECT_FIRST_FOUND_CONTACT: 164d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov selectDefaultContact(); 165d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov break; 166d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 167d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 168d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov }; 169d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 170d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov return mHandler; 171d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 172d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 173d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov @Override 174d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov public void onAttach(Activity activity) { 175d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov super.onAttach(activity); 176d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mPrefs = PreferenceManager.getDefaultSharedPreferences(activity); 177264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov restoreFilter(); 178264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov restoreSelectedUri(false); 179d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 180d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 181fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov @Override 1821db00f68b34f6cf7e9d19fedb559cf12f8c05e9cMakoto Onuki protected void setSearchMode(boolean flag) { 183fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov if (isSearchMode() != flag) { 184fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov if (!flag) { 185fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov restoreSelectedUri(true); 186fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov } 187fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov super.setSearchMode(flag); 188fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov } 189d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 190d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 191d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov public void setFilter(ContactListFilter filter) { 192a5a2744ab8102cf4ff5fbd3e1fa074a45257b3ddDmitri Plotnikov setFilter(filter, true); 193a5a2744ab8102cf4ff5fbd3e1fa074a45257b3ddDmitri Plotnikov } 194a5a2744ab8102cf4ff5fbd3e1fa074a45257b3ddDmitri Plotnikov 195a5a2744ab8102cf4ff5fbd3e1fa074a45257b3ddDmitri Plotnikov public void setFilter(ContactListFilter filter, boolean restoreSelectedUri) { 196d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (mFilter == null && filter == null) { 197d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov return; 198d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 199d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 200d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (mFilter != null && mFilter.equals(filter)) { 201d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov return; 202d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 203d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 2048daa1797310aca2333efcff0a0e0b0ed03187fffDmitri Plotnikov Log.v(TAG, "New filter: " + filter); 205264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov 206d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mFilter = filter; 207682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov mLastSelectedPosition = -1; 208264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov saveFilter(); 209a5a2744ab8102cf4ff5fbd3e1fa074a45257b3ddDmitri Plotnikov if (restoreSelectedUri) { 210a5a2744ab8102cf4ff5fbd3e1fa074a45257b3ddDmitri Plotnikov mSelectedContactUri = null; 211a5a2744ab8102cf4ff5fbd3e1fa074a45257b3ddDmitri Plotnikov restoreSelectedUri(true); 212a5a2744ab8102cf4ff5fbd3e1fa074a45257b3ddDmitri Plotnikov } 213d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov reloadData(); 214d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 215d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 216d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov public ContactListFilter getFilter() { 217d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov return mFilter; 218d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 219d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 22068e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov @Override 221cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov public void restoreSavedState(Bundle savedState) { 222cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov super.restoreSavedState(savedState); 223cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov 224cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov if (savedState == null) { 225cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov return; 226cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov } 227cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov 228264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov mFilter = savedState.getParcelable(KEY_FILTER); 229cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov mSelectedContactUri = savedState.getParcelable(KEY_SELECTED_URI); 2306e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov mSelectionVerified = savedState.getBoolean(KEY_SELECTION_VERIFIED); 231682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov mLastSelectedPosition = savedState.getInt(KEY_LAST_SELECTED_POSITION); 232580286bf8b280cfb607942cd207b3eb68fb8af66Dmitri Plotnikov parseSelectedContactUri(); 233cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov } 234cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov 235cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov @Override 236cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov public void onSaveInstanceState(Bundle outState) { 237cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov super.onSaveInstanceState(outState); 238264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov outState.putParcelable(KEY_FILTER, mFilter); 239cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov outState.putParcelable(KEY_SELECTED_URI, mSelectedContactUri); 2406e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov outState.putBoolean(KEY_SELECTION_VERIFIED, mSelectionVerified); 241682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov outState.putInt(KEY_LAST_SELECTED_POSITION, mLastSelectedPosition); 242cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov } 243cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov 244892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov protected void refreshSelectedContactUri() { 2456cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan if (mContactLookupTask != null) { 2466cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan mContactLookupTask.cancel(); 247892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov } 248cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov 249d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (!isSelectionVisible()) { 250d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov return; 251d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 252d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 253892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov mRefreshingContactUri = true; 254d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 255d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (mSelectedContactUri == null) { 256892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov onContactUriQueryFinished(null); 257d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov return; 258d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 259d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 260d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (mSelectedContactDirectoryId != Directory.DEFAULT 261d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov && mSelectedContactDirectoryId != Directory.LOCAL_INVISIBLE) { 262892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov onContactUriQueryFinished(mSelectedContactUri); 2637ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov } else { 2646cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan mContactLookupTask = new ContactLookupTask(mSelectedContactUri); 2656cd5b0ab721bcc97d465c768a13e292e59259274Katherine Kuan mContactLookupTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null); 266892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov } 267d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 268d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 269892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov protected void onContactUriQueryFinished(Uri uri) { 270892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov mRefreshingContactUri = false; 271892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov mSelectedContactUri = uri; 272892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov parseSelectedContactUri(); 273892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov checkSelection(); 2747ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov } 2757ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov 276cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov @Override 27768e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov protected void prepareEmptyView() { 27868e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov if (isSearchMode()) { 27968e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov return; 28068e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov } else if (isSyncActive()) { 28168e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov if (hasIccCard()) { 28268e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov setEmptyText(R.string.noContactsHelpTextWithSync); 28368e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov } else { 28468e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov setEmptyText(R.string.noContactsNoSimHelpTextWithSync); 28568e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov } 28668e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov } else { 28768e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov if (hasIccCard()) { 28868e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov setEmptyText(R.string.noContactsHelpText); 28968e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov } else { 29068e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov setEmptyText(R.string.noContactsNoSimHelpText); 29168e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov } 29268e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov } 29368e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov } 29468e32a3e3248a36f90e43e4f970ebe0196e74e43Dmitri Plotnikov 295cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov public Uri getSelectedContactUri() { 296cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov return mSelectedContactUri; 297cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov } 298cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov 299d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov /** 300d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov * Sets the new selection for the list. 301d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov */ 302cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov public void setSelectedContactUri(Uri uri) { 303264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov setSelectedContactUri(uri, true, true, true, false); 304d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 305d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 3065251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov @Override 3075251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov public void setQueryString(String queryString, boolean delaySelection) { 3085251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov mDelaySelection = delaySelection; 3095251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov super.setQueryString(queryString, delaySelection); 3105251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov } 3115251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov 312264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov /** 313e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan * Sets whether or not a contact selection must be made. 314e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan * @param required if true, we need to check if the selection is present in 315e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan * the list and if not notify the listener so that it can load a 316e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan * different list. 317e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan * TODO: Figure out how to reconcile this with {@link #setSelectedContactUri}, 318e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan * without causing unnecessary loading of the list if the selected contact URI is 319e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan * the same as before. 320e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan */ 321e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan public void setSelectionRequired(boolean required) { 322e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan mSelectionRequired = required; 323e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan } 324e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan 325e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan /** 326264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov * Sets the new contact selection. 327264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov * 328264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov * @param uri the new selection 329264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov * @param required if true, we need to check if the selection is present in 330264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov * the list and if not notify the listener so that it can load a 331264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov * different list 332264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov * @param smoothScroll if true, the UI will roll smoothly to the new 333264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov * selection 334264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov * @param persistent if true, the selection will be stored in shared 335264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov * preferences. 336264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov * @param willReloadData if true, the selection will be remembered but not 337264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov * actually shown, because we are expecting that the data will be 338264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov * reloaded momentarily 339264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov */ 340264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov private void setSelectedContactUri(Uri uri, boolean required, boolean smoothScroll, 341264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov boolean persistent, boolean willReloadData) { 342d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mSmoothScrollRequested = smoothScroll; 343d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mSelectionToScreenRequested = true; 344d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 345174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov if ((mSelectedContactUri == null && uri != null) 346cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov || (mSelectedContactUri != null && !mSelectedContactUri.equals(uri))) { 347d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mSelectionVerified = false; 348d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mSelectionRequired = required; 349d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mSelectionPersistenceRequested = persistent; 3507ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov mSelectedContactUri = uri; 351580286bf8b280cfb607942cd207b3eb68fb8af66Dmitri Plotnikov parseSelectedContactUri(); 3527ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov 353264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov if (!willReloadData) { 354264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov // Configure the adapter to show the selection based on the 355264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov // lookup key extracted from the URI 356264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov ContactListAdapter adapter = getAdapter(); 357264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov if (adapter != null) { 3587d402246e9ac26e05eeb25528bc74083412d1a5aDmitri Plotnikov adapter.setSelectedContact(mSelectedContactDirectoryId, 3597d402246e9ac26e05eeb25528bc74083412d1a5aDmitri Plotnikov mSelectedContactLookupKey, mSelectedContactId); 3602f28edacb95db9ee56631815f592e46ec928a33fDmitri Plotnikov getListView().invalidateViews(); 361264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov } 362264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov } 363264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov 364892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov // Also, launch a loader to pick up a new lookup URI in case it has changed 365892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov refreshSelectedContactUri(); 3667ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov } 3677ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov } 3687ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov 369580286bf8b280cfb607942cd207b3eb68fb8af66Dmitri Plotnikov private void parseSelectedContactUri() { 370580286bf8b280cfb607942cd207b3eb68fb8af66Dmitri Plotnikov if (mSelectedContactUri != null) { 371580286bf8b280cfb607942cd207b3eb68fb8af66Dmitri Plotnikov String directoryParam = 372892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov mSelectedContactUri.getQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY); 37390715b38713ea97504f2b4a8452c8dd46d1c20ecDmitri Plotnikov mSelectedContactDirectoryId = TextUtils.isEmpty(directoryParam) ? Directory.DEFAULT 374580286bf8b280cfb607942cd207b3eb68fb8af66Dmitri Plotnikov : Long.parseLong(directoryParam); 37590715b38713ea97504f2b4a8452c8dd46d1c20ecDmitri Plotnikov if (mSelectedContactUri.toString().startsWith(Contacts.CONTENT_LOOKUP_URI.toString())) { 376892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov List<String> pathSegments = mSelectedContactUri.getPathSegments(); 377892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov mSelectedContactLookupKey = Uri.encode(pathSegments.get(2)); 378b906cbe036505547895a568b20187c8361b89fffDmitri Plotnikov if (pathSegments.size() == 4) { 3790c708094307e6c6b782095c854a1b545b6972b86Dmitri Plotnikov mSelectedContactId = ContentUris.parseId(mSelectedContactUri); 3800c708094307e6c6b782095c854a1b545b6972b86Dmitri Plotnikov } 381fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov } else if (mSelectedContactUri.toString().startsWith(Contacts.CONTENT_URI.toString()) && 382fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov mSelectedContactUri.getPathSegments().size() >= 2) { 3837d402246e9ac26e05eeb25528bc74083412d1a5aDmitri Plotnikov mSelectedContactLookupKey = null; 3847d402246e9ac26e05eeb25528bc74083412d1a5aDmitri Plotnikov mSelectedContactId = ContentUris.parseId(mSelectedContactUri); 38590715b38713ea97504f2b4a8452c8dd46d1c20ecDmitri Plotnikov } else { 3867d402246e9ac26e05eeb25528bc74083412d1a5aDmitri Plotnikov Log.e(TAG, "Unsupported contact URI: " + mSelectedContactUri); 38790715b38713ea97504f2b4a8452c8dd46d1c20ecDmitri Plotnikov mSelectedContactLookupKey = null; 3887d402246e9ac26e05eeb25528bc74083412d1a5aDmitri Plotnikov mSelectedContactId = 0; 38990715b38713ea97504f2b4a8452c8dd46d1c20ecDmitri Plotnikov } 39090715b38713ea97504f2b4a8452c8dd46d1c20ecDmitri Plotnikov 391580286bf8b280cfb607942cd207b3eb68fb8af66Dmitri Plotnikov } else { 392580286bf8b280cfb607942cd207b3eb68fb8af66Dmitri Plotnikov mSelectedContactDirectoryId = Directory.DEFAULT; 393580286bf8b280cfb607942cd207b3eb68fb8af66Dmitri Plotnikov mSelectedContactLookupKey = null; 3947d402246e9ac26e05eeb25528bc74083412d1a5aDmitri Plotnikov mSelectedContactId = 0; 395580286bf8b280cfb607942cd207b3eb68fb8af66Dmitri Plotnikov } 396580286bf8b280cfb607942cd207b3eb68fb8af66Dmitri Plotnikov } 397580286bf8b280cfb607942cd207b3eb68fb8af66Dmitri Plotnikov 3987ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov @Override 3997ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov protected void configureAdapter() { 4007ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov super.configureAdapter(); 4017ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov 4027ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov ContactListAdapter adapter = getAdapter(); 4037ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov if (adapter == null) { 4047ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov return; 405cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov } 4067ccdc1f5337f2cb7b311358c8bb3c68aef6213d1Dmitri Plotnikov 4078fdf890892dd5aeec35f693c158777f9fdd7d0e4Isaac Katzenelson boolean searchMode = isSearchMode(); 4088fdf890892dd5aeec35f693c158777f9fdd7d0e4Isaac Katzenelson if (!searchMode && mFilter != null) { 409d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov adapter.setFilter(mFilter); 4103c8c3e811917998620b4526330b83d32d3c17078Dmitri Plotnikov if (mSelectionRequired 4113c8c3e811917998620b4526330b83d32d3c17078Dmitri Plotnikov || mFilter.filterType == ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) { 4127d402246e9ac26e05eeb25528bc74083412d1a5aDmitri Plotnikov adapter.setSelectedContact( 4137d402246e9ac26e05eeb25528bc74083412d1a5aDmitri Plotnikov mSelectedContactDirectoryId, mSelectedContactLookupKey, mSelectedContactId); 41493a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov } 415d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 4160a4d2258411478c7c78790cd55ba25c99f588c26Dave Santoro 4178fdf890892dd5aeec35f693c158777f9fdd7d0e4Isaac Katzenelson // Display the user's profile if not in search mode 4188fdf890892dd5aeec35f693c158777f9fdd7d0e4Isaac Katzenelson adapter.setIncludeProfile(!searchMode); 4196e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov } 4206e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov 4216e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov @Override 422174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 423174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov super.onLoadFinished(loader, data); 424d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mSelectionVerified = false; 425892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov 426892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov // Refresh the currently selected lookup in case it changed while we were sleeping 427892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov refreshSelectedContactUri(); 4286e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov } 4296e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov 4300cd01309feeaf08b1a9852d33fc123c6cbddca6cDmitri Plotnikov @Override 4314ef95cc3329b4ad9fa450e4090efaad9935d493fDianne Hackborn public void onLoaderReset(Loader<Cursor> loader) { 4324ef95cc3329b4ad9fa450e4090efaad9935d493fDianne Hackborn } 4334ef95cc3329b4ad9fa450e4090efaad9935d493fDianne Hackborn 4346e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov private void checkSelection() { 435174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov if (mSelectionVerified) { 4366e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov return; 4376e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov } 4386e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov 43993a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov if (mRefreshingContactUri) { 44093a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov return; 44193a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov } 44293a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov 44393a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov if (isLoadingDirectoryList()) { 4446e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov return; 4456e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov } 4466e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov 447174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov ContactListAdapter adapter = getAdapter(); 448264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov if (adapter == null) { 449d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov return; 450d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 451d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 45293a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov boolean directoryLoading = true; 45393a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov int count = adapter.getPartitionCount(); 45493a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov for (int i = 0; i < count; i++) { 45593a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov Partition partition = adapter.getPartition(i); 45693a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov if (partition instanceof DirectoryPartition) { 45793a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov DirectoryPartition directory = (DirectoryPartition) partition; 45893a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov if (directory.getDirectoryId() == mSelectedContactDirectoryId) { 45993a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov directoryLoading = directory.isLoading(); 46093a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov break; 46193a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov } 46293a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov } 46393a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov } 46493a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov 46593a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov if (directoryLoading) { 46693a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov return; 46793a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov } 46893a05db5aa59dc031ccd5ce76f816f7b2ab1d3a4Dmitri Plotnikov 4697d402246e9ac26e05eeb25528bc74083412d1a5aDmitri Plotnikov adapter.setSelectedContact( 4707d402246e9ac26e05eeb25528bc74083412d1a5aDmitri Plotnikov mSelectedContactDirectoryId, mSelectedContactLookupKey, mSelectedContactId); 471264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov 472e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan final int selectedPosition = adapter.getSelectedContactPosition(); 473682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov if (selectedPosition != -1) { 474682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov mLastSelectedPosition = selectedPosition; 475682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov } else { 476d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (isSearchMode()) { 4775251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov if (mDelaySelection) { 4785251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov selectFirstFoundContactAfterDelay(); 4795251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov if (mListener != null) { 4805251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov mListener.onSelectionChange(); 4815251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov } 4825251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov return; 483264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov } 4845251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov } else if (mSelectionRequired) { 4858fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov // A specific contact was requested, but it's not in the loaded list. 4868fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov 4878fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov // Try reconfiguring and reloading the list that will hopefully contain 4888fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov // the requested contact. Only take one attempt to avoid an infinite loop 4898fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov // in case the contact cannot be found at all. 4908fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov mSelectionRequired = false; 4918fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov 4928fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov // If we were looking at a different specific contact, just reload 4938fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov if (mFilter != null 4948fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov && mFilter.filterType == ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) { 4958fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov reloadData(); 4968fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov } else { 4978fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov // Otherwise, call the listener, which will adjust the filter. 4988fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov notifyInvalidSelection(); 4998fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov } 5008fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov return; 5015251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov } else if (mFilter != null 5028fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov && mFilter.filterType == ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) { 5035251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov // If we were trying to load a specific contact, but that contact no longer 5045251884bbcdb92dad577d027126547527285fcceDmitri Plotnikov // exists, call the listener, which will adjust the filter. 5058fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov notifyInvalidSelection(); 5068fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov return; 5078fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov } 5088fe7821d91764dc33270f70e1f08ec05647ef041Dmitri Plotnikov 509264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov saveSelectedUri(null); 510264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov selectDefaultContact(); 511d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 512d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 513d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mSelectionRequired = false; 514d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mSelectionVerified = true; 515d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 516d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (mSelectionPersistenceRequested) { 517d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov saveSelectedUri(mSelectedContactUri); 518d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mSelectionPersistenceRequested = false; 519d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 520d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 521d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (mSelectionToScreenRequested) { 522e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan requestSelectionToScreen(selectedPosition); 523d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 524d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 5252f28edacb95db9ee56631815f592e46ec928a33fDmitri Plotnikov getListView().invalidateViews(); 526264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov 527d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (mListener != null) { 528d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mListener.onSelectionChange(); 529d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 530d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 531d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 532d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov /** 533d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov * Automatically selects the first found contact in search mode. The selection 534d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov * is updated after a delay to allow the user to type without to much UI churn 535d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov * and to save bandwidth on directory queries. 536d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov */ 537d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov public void selectFirstFoundContactAfterDelay() { 538d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov Handler handler = getHandler(); 539d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov handler.removeMessages(MESSAGE_AUTOSELECT_FIRST_FOUND_CONTACT); 540d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 541d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov String queryString = getQueryString(); 542d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (queryString != null 543d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov && queryString.length() >= AUTOSELECT_FIRST_FOUND_CONTACT_MIN_QUERY_LENGTH) { 544d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov handler.sendEmptyMessageDelayed(MESSAGE_AUTOSELECT_FIRST_FOUND_CONTACT, 545d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov DELAY_AUTOSELECT_FIRST_FOUND_CONTACT_MILLIS); 546d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } else { 547264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov setSelectedContactUri(null, false, false, false, false); 548d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 549d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 550d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 551d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov protected void selectDefaultContact() { 552682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov Uri contactUri = null; 55307bf52d66b6a17be1d1a1016fdf53321a1b83861Dmitri Plotnikov ContactListAdapter adapter = getAdapter(); 554682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov if (mLastSelectedPosition != -1) { 55507bf52d66b6a17be1d1a1016fdf53321a1b83861Dmitri Plotnikov int count = adapter.getCount(); 55607bf52d66b6a17be1d1a1016fdf53321a1b83861Dmitri Plotnikov int pos = mLastSelectedPosition; 55707bf52d66b6a17be1d1a1016fdf53321a1b83861Dmitri Plotnikov if (pos >= count && count > 0) { 55807bf52d66b6a17be1d1a1016fdf53321a1b83861Dmitri Plotnikov pos = count - 1; 55907bf52d66b6a17be1d1a1016fdf53321a1b83861Dmitri Plotnikov } 56007bf52d66b6a17be1d1a1016fdf53321a1b83861Dmitri Plotnikov contactUri = adapter.getContactUri(pos); 561682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov } 562682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov 563682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov if (contactUri == null) { 56407bf52d66b6a17be1d1a1016fdf53321a1b83861Dmitri Plotnikov contactUri = adapter.getFirstContactUri(); 565682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov } 566682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov 567682e152f65a14971d7df191ff849f9db9d50d617Dmitri Plotnikov setSelectedContactUri(contactUri, false, mSmoothScrollRequested, false, false); 568d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 569d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov 570e1cabcd0956f24a3d3cbe0777b430030f681a739Katherine Kuan protected void requestSelectionToScreen(int selectedPosition) { 571d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (selectedPosition != -1) { 572753f8f6fde5a4f74181310593acebee94a014fe2Dmitri Plotnikov AutoScrollListView listView = (AutoScrollListView)getListView(); 573753f8f6fde5a4f74181310593acebee94a014fe2Dmitri Plotnikov listView.requestPositionToScreen( 574d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov selectedPosition + listView.getHeaderViewsCount(), mSmoothScrollRequested); 575d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mSelectionToScreenRequested = false; 5766e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov } 5776e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov } 5786e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov 579174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov @Override 580174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov public boolean isLoading() { 581892fb517ff1ba2e3f8804b0a9365a2173bff1f3aDmitri Plotnikov return mRefreshingContactUri || super.isLoading(); 582174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov } 583174fdc2dcb965f11cf4eb25e4ea961f0e1e56c85Dmitri Plotnikov 5846e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov @Override 585264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov protected void startLoading() { 586264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov mStartedLoading = true; 587264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov mSelectionVerified = false; 588264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov super.startLoading(); 5896e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov } 5906e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov 591a5a2744ab8102cf4ff5fbd3e1fa074a45257b3ddDmitri Plotnikov public void reloadDataAndSetSelectedUri(Uri uri) { 592a5a2744ab8102cf4ff5fbd3e1fa074a45257b3ddDmitri Plotnikov setSelectedContactUri(uri, true, true, true, true); 593a5a2744ab8102cf4ff5fbd3e1fa074a45257b3ddDmitri Plotnikov reloadData(); 594a5a2744ab8102cf4ff5fbd3e1fa074a45257b3ddDmitri Plotnikov } 595a5a2744ab8102cf4ff5fbd3e1fa074a45257b3ddDmitri Plotnikov 5966e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov @Override 5976e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov public void reloadData() { 598d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (mStartedLoading) { 599d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov mSelectionVerified = false; 60004bad51421ca4adab40900324dc2e108f5554e04Dmitri Plotnikov mLastSelectedPosition = -1; 601d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov super.reloadData(); 602d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 603cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov } 604cfc648986f569bde83715584a91f89ed28dd8335Dmitri Plotnikov 605416b569901ce4c577c1f76c3f29496d1adab29e1Dmitri Plotnikov public void setOnContactListActionListener(OnContactBrowserActionListener listener) { 606732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov mListener = listener; 607732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov } 608732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov 609238d9847d8f2ace658fb7337c8847a2088ddc9d1Dmitri Plotnikov public void createNewContact() { 6107152124ac79a2faf6fd8e4135069feb92edeb1feDmitri Plotnikov if (mListener != null) mListener.onCreateNewContactAction(); 611732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov } 612732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov 613e20d3432a370dd3996deec2df4e3cdf726c94992Daniel Lehmann public void viewContact(Uri contactUri) { 614264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov setSelectedContactUri(contactUri, false, false, true, false); 615a5b3d4642e709153e202b187e8c9021506882323Daniel Lehmann if (mListener != null) mListener.onViewContactAction(contactUri); 6161323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov } 6171323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov 6181323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov public void editContact(Uri contactUri) { 6197152124ac79a2faf6fd8e4135069feb92edeb1feDmitri Plotnikov if (mListener != null) mListener.onEditContactAction(contactUri); 6201323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov } 6211323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov 6221323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov public void deleteContact(Uri contactUri) { 6237152124ac79a2faf6fd8e4135069feb92edeb1feDmitri Plotnikov if (mListener != null) mListener.onDeleteContactAction(contactUri); 6241323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov } 6251323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov 6261323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov public void addToFavorites(Uri contactUri) { 6277152124ac79a2faf6fd8e4135069feb92edeb1feDmitri Plotnikov if (mListener != null) mListener.onAddToFavoritesAction(contactUri); 6281323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov } 6291323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov 6301323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov public void removeFromFavorites(Uri contactUri) { 6317152124ac79a2faf6fd8e4135069feb92edeb1feDmitri Plotnikov if (mListener != null) mListener.onRemoveFromFavoritesAction(contactUri); 6321323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov } 6331323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov 6341323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov public void callContact(Uri contactUri) { 6357152124ac79a2faf6fd8e4135069feb92edeb1feDmitri Plotnikov if (mListener != null) mListener.onCallContactAction(contactUri); 6361323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov } 637732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov 6381323d69c40649914ae2195088573a20cc35da86eDmitri Plotnikov public void smsContact(Uri contactUri) { 6397152124ac79a2faf6fd8e4135069feb92edeb1feDmitri Plotnikov if (mListener != null) mListener.onSmsContactAction(contactUri); 640732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov } 641e3fbfd99842607a0c208d0a930878bb54bb91dedDmitri Plotnikov 6426e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov private void notifyInvalidSelection() { 6437152124ac79a2faf6fd8e4135069feb92edeb1feDmitri Plotnikov if (mListener != null) mListener.onInvalidSelection(); 6446e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov } 6456e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov 646e3fbfd99842607a0c208d0a930878bb54bb91dedDmitri Plotnikov @Override 647e3fbfd99842607a0c208d0a930878bb54bb91dedDmitri Plotnikov protected void finish() { 648e3fbfd99842607a0c208d0a930878bb54bb91dedDmitri Plotnikov super.finish(); 6497152124ac79a2faf6fd8e4135069feb92edeb1feDmitri Plotnikov if (mListener != null) mListener.onFinishAction(); 650e3fbfd99842607a0c208d0a930878bb54bb91dedDmitri Plotnikov } 6518c6955ff3c05e1f3899110701c3cb5559a492f1eDmitri Plotnikov 652d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private void saveSelectedUri(Uri contactUri) { 653fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov if (isSearchMode()) { 654fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov return; 6558c6955ff3c05e1f3899110701c3cb5559a492f1eDmitri Plotnikov } 6568c6955ff3c05e1f3899110701c3cb5559a492f1eDmitri Plotnikov 657fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov ContactListFilter.storeToPreferences(mPrefs, mFilter); 658fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov 659fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov Editor editor = mPrefs.edit(); 660fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov if (contactUri == null) { 661fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov editor.remove(getPersistentSelectionKey()); 662fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov } else { 663fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov editor.putString(getPersistentSelectionKey(), contactUri.toString()); 6648c6955ff3c05e1f3899110701c3cb5559a492f1eDmitri Plotnikov } 665fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov editor.apply(); 6668c6955ff3c05e1f3899110701c3cb5559a492f1eDmitri Plotnikov } 6676e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov 668264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov private void restoreSelectedUri(boolean willReloadData) { 669264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov // The meaning of mSelectionRequired is that we need to show some 670264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov // selection other than the previous selection saved in shared preferences 671264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov if (mSelectionRequired) { 672d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov return; 673d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 6746e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov 675d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov String selectedUri = mPrefs.getString(getPersistentSelectionKey(), null); 676d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (selectedUri == null) { 677264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov setSelectedContactUri(null, false, false, false, willReloadData); 678d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } else { 679264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov setSelectedContactUri(Uri.parse(selectedUri), false, false, false, willReloadData); 680264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov } 681264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov } 682264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov 683264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov private void saveFilter() { 684fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov ContactListFilter.storeToPreferences(mPrefs, mFilter); 685264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov } 686264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov 687264023c04b75043fa77267fd1b940d0afb13421dDmitri Plotnikov private void restoreFilter() { 688d4ed72eb6610b1318545741140569a973c4ab452Daisuke Miyakawa mFilter = ContactListFilter.restoreDefaultPreferences(mPrefs); 6896e850a046fcea8ba82a793b43944051246d08180Dmitri Plotnikov } 69030cc853792b4a71871cef8bca03b67b805fdc34eDmitri Plotnikov 691d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov private String getPersistentSelectionKey() { 692d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov if (mFilter == null) { 693d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov return mPersistentSelectionPrefix; 694d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } else { 695d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov return mPersistentSelectionPrefix + "-" + mFilter.getId(); 696d959104d37df65f0d6de9290c3fa2b59065be0fcDmitri Plotnikov } 69730cc853792b4a71871cef8bca03b67b805fdc34eDmitri Plotnikov } 6980cd01309feeaf08b1a9852d33fc123c6cbddca6cDmitri Plotnikov 6990cd01309feeaf08b1a9852d33fc123c6cbddca6cDmitri Plotnikov public boolean isOptionsMenuChanged() { 7000cd01309feeaf08b1a9852d33fc123c6cbddca6cDmitri Plotnikov // This fragment does not have an option menu of its own 7010cd01309feeaf08b1a9852d33fc123c6cbddca6cDmitri Plotnikov return false; 7020cd01309feeaf08b1a9852d33fc123c6cbddca6cDmitri Plotnikov } 703732f65236e7f804941e84757c077a84eb11eab16Dmitri Plotnikov} 704