Loading src/com/android/contacts/ContactLoader.java +3 −42 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.contacts; import com.android.contacts.model.AccountType; import com.android.contacts.model.AccountTypeManager; import com.android.contacts.model.AccountTypeWithDataSet; import com.android.contacts.util.ContactLoaderUtils; import com.android.contacts.util.DataStatus; import com.android.contacts.util.StreamItemEntry; import com.android.contacts.util.StreamItemPhotoEntry; Loading Loading @@ -681,7 +682,8 @@ public class ContactLoader extends Loader<ContactLoader.Result> { protected Result doInBackground(Void... args) { try { final ContentResolver resolver = getContext().getContentResolver(); final Uri uriCurrentFormat = ensureIsContactUri(resolver, mLookupUri); final Uri uriCurrentFormat = ContactLoaderUtils.ensureIsContactUri( resolver, mLookupUri); Result result = loadContactEntity(resolver, uriCurrentFormat); if (!result.isNotFound()) { if (result.isDirectoryEntry()) { Loading @@ -706,47 +708,6 @@ public class ContactLoader extends Loader<ContactLoader.Result> { } } /** * Transforms the given Uri and returns a Lookup-Uri that represents the contact. * For legacy contacts, a raw-contact lookup is performed. * @param resolver */ private Uri ensureIsContactUri(final ContentResolver resolver, final Uri uri) { if (uri == null) throw new IllegalArgumentException("uri must not be null"); final String authority = uri.getAuthority(); // Current Style Uri? if (ContactsContract.AUTHORITY.equals(authority)) { final String type = resolver.getType(uri); // Contact-Uri? Good, return it if (Contacts.CONTENT_ITEM_TYPE.equals(type)) { return uri; } // RawContact-Uri? Transform it to ContactUri if (RawContacts.CONTENT_ITEM_TYPE.equals(type)) { final long rawContactId = ContentUris.parseId(uri); return RawContacts.getContactLookupUri(getContext().getContentResolver(), ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId)); } // Anything else? We don't know what this is throw new IllegalArgumentException("uri format is unknown"); } // Legacy Style? Convert to RawContact final String OBSOLETE_AUTHORITY = "contacts"; if (OBSOLETE_AUTHORITY.equals(authority)) { // Legacy Format. Convert to RawContact-Uri and then lookup the contact final long rawContactId = ContentUris.parseId(uri); return RawContacts.getContactLookupUri(resolver, ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId)); } throw new IllegalArgumentException("uri authority is unknown"); } private Result loadContactEntity(ContentResolver resolver, Uri contactUri) { Uri entityUri = Uri.withAppendedPath(contactUri, Contacts.Entity.CONTENT_DIRECTORY); Cursor cursor = resolver.query(entityUri, ContactQuery.COLUMNS, null, null, Loading src/com/android/contacts/list/ContactBrowseListFragment.java +50 −38 Original line number Diff line number Diff line Loading @@ -17,10 +17,10 @@ package com.android.contacts.list; import com.android.common.widget.CompositeCursorAdapter.Partition; import com.android.contacts.R; import com.android.contacts.util.ContactLoaderUtils; import com.android.contacts.widget.AutoScrollListView; import android.app.Activity; import android.content.AsyncQueryHandler; import android.content.ContentResolver; import android.content.ContentUris; import android.content.Loader; Loading @@ -28,6 +28,7 @@ import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Message; Loading Loading @@ -92,50 +93,63 @@ public abstract class ContactBrowseListFragment extends private String mPersistentSelectionPrefix = PERSISTENT_SELECTION_PREFIX; protected OnContactBrowserActionListener mListener; private ContactLookupTask mContactLookupTask; /** * Refreshes a contact URI: it may have changed as a result of aggregation * activity. */ private class ContactUriQueryHandler extends AsyncQueryHandler { private final class ContactLookupTask extends AsyncTask<Void, Void, Uri> { public ContactUriQueryHandler(ContentResolver cr) { super(cr); } private final Uri mUri; private boolean mIsCancelled; public void runQuery() { startQuery(0, mSelectedContactUri, mSelectedContactUri, new String[] { Contacts._ID, Contacts.LOOKUP_KEY }, null, null, null); public ContactLookupTask(Uri uri) { mUri = uri; } @Override protected void onQueryComplete(int token, Object cookie, Cursor data) { long contactId = 0; String lookupKey = null; if (data != null) { if (data.moveToFirst()) { contactId = data.getLong(0); lookupKey = data.getString(1); protected Uri doInBackground(Void... args) { Cursor cursor = null; try { final ContentResolver resolver = getContext().getContentResolver(); final Uri uriCurrentFormat = ContactLoaderUtils.ensureIsContactUri(resolver, mUri); cursor = resolver.query(uriCurrentFormat, new String[] { Contacts._ID, Contacts.LOOKUP_KEY }, null, null, null); if (cursor != null && cursor.moveToFirst()) { final long contactId = cursor.getLong(0); final String lookupKey = cursor.getString(1); if (contactId != 0 && !TextUtils.isEmpty(lookupKey)) { return Contacts.getLookupUri(contactId, lookupKey); } data.close(); } if (!cookie.equals(mSelectedContactUri)) { return; Log.e(TAG, "Error: No contact ID or lookup key for contact " + mUri); return null; } finally { if (cursor != null) { cursor.close(); } } } Uri uri; if (contactId != 0 && lookupKey != null) { uri = Contacts.getLookupUri(contactId, lookupKey); } else { uri = null; public void cancel() { super.cancel(true); // Use a flag to keep track of whether the {@link AsyncTask} was cancelled or not in // order to ensure onPostExecute() is not executed after the cancel request. The flag is // necessary because {@link AsyncTask} still calls onPostExecute() if the cancel request // came after the worker thread was finished. mIsCancelled = true; } onContactUriQueryFinished(uri); @Override protected void onPostExecute(Uri uri) { // Make sure the {@link Fragment} is at least still attached to the {@link Activity} // before continuing. if (mIsCancelled || !isAdded() || uri == null) { return; } mSelectedContactUri = uri; onContactUriQueryFinished(mSelectedContactUri); } } private ContactUriQueryHandler mQueryHandler; private boolean mDelaySelection; Loading @@ -158,7 +172,6 @@ public abstract class ContactBrowseListFragment extends @Override public void onAttach(Activity activity) { super.onAttach(activity); mQueryHandler = new ContactUriQueryHandler(activity.getContentResolver()); mPrefs = PreferenceManager.getDefaultSharedPreferences(activity); restoreFilter(); restoreSelectedUri(false); Loading Loading @@ -228,12 +241,10 @@ public abstract class ContactBrowseListFragment extends } protected void refreshSelectedContactUri() { if (mQueryHandler == null) { return; if (mContactLookupTask != null) { mContactLookupTask.cancel(); } mQueryHandler.cancelOperation(0); if (!isSelectionVisible()) { return; } Loading @@ -249,7 +260,8 @@ public abstract class ContactBrowseListFragment extends && mSelectedContactDirectoryId != Directory.LOCAL_INVISIBLE) { onContactUriQueryFinished(mSelectedContactUri); } else { mQueryHandler.runQuery(); mContactLookupTask = new ContactLookupTask(mSelectedContactUri); mContactLookupTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null); } } Loading src/com/android/contacts/util/ContactLoaderUtils.java 0 → 100644 +78 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 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.contacts.util; import android.content.ContentResolver; import android.content.ContentUris; import android.net.Uri; import android.provider.Contacts; import android.provider.ContactsContract; import android.provider.ContactsContract.RawContacts; /** * Utility methods for the {@link ContactLoader}. */ public final class ContactLoaderUtils { /** Static helper, not instantiable. */ private ContactLoaderUtils() {} /** * Transforms the given Uri and returns a Lookup-Uri that represents the contact. * For legacy contacts, a raw-contact lookup is performed. An {@link IllegalArgumentException} * can be thrown if the URI is null or the authority is not recognized. * * Do not call from the UI thread. */ @SuppressWarnings("deprecation") public static Uri ensureIsContactUri(final ContentResolver resolver, final Uri uri) throws IllegalArgumentException { if (uri == null) throw new IllegalArgumentException("uri must not be null"); final String authority = uri.getAuthority(); // Current Style Uri? if (ContactsContract.AUTHORITY.equals(authority)) { final String type = resolver.getType(uri); // Contact-Uri? Good, return it if (ContactsContract.Contacts.CONTENT_ITEM_TYPE.equals(type)) { return uri; } // RawContact-Uri? Transform it to ContactUri if (RawContacts.CONTENT_ITEM_TYPE.equals(type)) { final long rawContactId = ContentUris.parseId(uri); return RawContacts.getContactLookupUri(resolver, ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId)); } // Anything else? We don't know what this is throw new IllegalArgumentException("uri format is unknown"); } // Legacy Style? Convert to RawContact final String OBSOLETE_AUTHORITY = Contacts.AUTHORITY; if (OBSOLETE_AUTHORITY.equals(authority)) { // Legacy Format. Convert to RawContact-Uri and then lookup the contact final long rawContactId = ContentUris.parseId(uri); return RawContacts.getContactLookupUri(resolver, ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId)); } throw new IllegalArgumentException("uri authority is unknown"); } } Loading
src/com/android/contacts/ContactLoader.java +3 −42 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.contacts; import com.android.contacts.model.AccountType; import com.android.contacts.model.AccountTypeManager; import com.android.contacts.model.AccountTypeWithDataSet; import com.android.contacts.util.ContactLoaderUtils; import com.android.contacts.util.DataStatus; import com.android.contacts.util.StreamItemEntry; import com.android.contacts.util.StreamItemPhotoEntry; Loading Loading @@ -681,7 +682,8 @@ public class ContactLoader extends Loader<ContactLoader.Result> { protected Result doInBackground(Void... args) { try { final ContentResolver resolver = getContext().getContentResolver(); final Uri uriCurrentFormat = ensureIsContactUri(resolver, mLookupUri); final Uri uriCurrentFormat = ContactLoaderUtils.ensureIsContactUri( resolver, mLookupUri); Result result = loadContactEntity(resolver, uriCurrentFormat); if (!result.isNotFound()) { if (result.isDirectoryEntry()) { Loading @@ -706,47 +708,6 @@ public class ContactLoader extends Loader<ContactLoader.Result> { } } /** * Transforms the given Uri and returns a Lookup-Uri that represents the contact. * For legacy contacts, a raw-contact lookup is performed. * @param resolver */ private Uri ensureIsContactUri(final ContentResolver resolver, final Uri uri) { if (uri == null) throw new IllegalArgumentException("uri must not be null"); final String authority = uri.getAuthority(); // Current Style Uri? if (ContactsContract.AUTHORITY.equals(authority)) { final String type = resolver.getType(uri); // Contact-Uri? Good, return it if (Contacts.CONTENT_ITEM_TYPE.equals(type)) { return uri; } // RawContact-Uri? Transform it to ContactUri if (RawContacts.CONTENT_ITEM_TYPE.equals(type)) { final long rawContactId = ContentUris.parseId(uri); return RawContacts.getContactLookupUri(getContext().getContentResolver(), ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId)); } // Anything else? We don't know what this is throw new IllegalArgumentException("uri format is unknown"); } // Legacy Style? Convert to RawContact final String OBSOLETE_AUTHORITY = "contacts"; if (OBSOLETE_AUTHORITY.equals(authority)) { // Legacy Format. Convert to RawContact-Uri and then lookup the contact final long rawContactId = ContentUris.parseId(uri); return RawContacts.getContactLookupUri(resolver, ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId)); } throw new IllegalArgumentException("uri authority is unknown"); } private Result loadContactEntity(ContentResolver resolver, Uri contactUri) { Uri entityUri = Uri.withAppendedPath(contactUri, Contacts.Entity.CONTENT_DIRECTORY); Cursor cursor = resolver.query(entityUri, ContactQuery.COLUMNS, null, null, Loading
src/com/android/contacts/list/ContactBrowseListFragment.java +50 −38 Original line number Diff line number Diff line Loading @@ -17,10 +17,10 @@ package com.android.contacts.list; import com.android.common.widget.CompositeCursorAdapter.Partition; import com.android.contacts.R; import com.android.contacts.util.ContactLoaderUtils; import com.android.contacts.widget.AutoScrollListView; import android.app.Activity; import android.content.AsyncQueryHandler; import android.content.ContentResolver; import android.content.ContentUris; import android.content.Loader; Loading @@ -28,6 +28,7 @@ import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Message; Loading Loading @@ -92,50 +93,63 @@ public abstract class ContactBrowseListFragment extends private String mPersistentSelectionPrefix = PERSISTENT_SELECTION_PREFIX; protected OnContactBrowserActionListener mListener; private ContactLookupTask mContactLookupTask; /** * Refreshes a contact URI: it may have changed as a result of aggregation * activity. */ private class ContactUriQueryHandler extends AsyncQueryHandler { private final class ContactLookupTask extends AsyncTask<Void, Void, Uri> { public ContactUriQueryHandler(ContentResolver cr) { super(cr); } private final Uri mUri; private boolean mIsCancelled; public void runQuery() { startQuery(0, mSelectedContactUri, mSelectedContactUri, new String[] { Contacts._ID, Contacts.LOOKUP_KEY }, null, null, null); public ContactLookupTask(Uri uri) { mUri = uri; } @Override protected void onQueryComplete(int token, Object cookie, Cursor data) { long contactId = 0; String lookupKey = null; if (data != null) { if (data.moveToFirst()) { contactId = data.getLong(0); lookupKey = data.getString(1); protected Uri doInBackground(Void... args) { Cursor cursor = null; try { final ContentResolver resolver = getContext().getContentResolver(); final Uri uriCurrentFormat = ContactLoaderUtils.ensureIsContactUri(resolver, mUri); cursor = resolver.query(uriCurrentFormat, new String[] { Contacts._ID, Contacts.LOOKUP_KEY }, null, null, null); if (cursor != null && cursor.moveToFirst()) { final long contactId = cursor.getLong(0); final String lookupKey = cursor.getString(1); if (contactId != 0 && !TextUtils.isEmpty(lookupKey)) { return Contacts.getLookupUri(contactId, lookupKey); } data.close(); } if (!cookie.equals(mSelectedContactUri)) { return; Log.e(TAG, "Error: No contact ID or lookup key for contact " + mUri); return null; } finally { if (cursor != null) { cursor.close(); } } } Uri uri; if (contactId != 0 && lookupKey != null) { uri = Contacts.getLookupUri(contactId, lookupKey); } else { uri = null; public void cancel() { super.cancel(true); // Use a flag to keep track of whether the {@link AsyncTask} was cancelled or not in // order to ensure onPostExecute() is not executed after the cancel request. The flag is // necessary because {@link AsyncTask} still calls onPostExecute() if the cancel request // came after the worker thread was finished. mIsCancelled = true; } onContactUriQueryFinished(uri); @Override protected void onPostExecute(Uri uri) { // Make sure the {@link Fragment} is at least still attached to the {@link Activity} // before continuing. if (mIsCancelled || !isAdded() || uri == null) { return; } mSelectedContactUri = uri; onContactUriQueryFinished(mSelectedContactUri); } } private ContactUriQueryHandler mQueryHandler; private boolean mDelaySelection; Loading @@ -158,7 +172,6 @@ public abstract class ContactBrowseListFragment extends @Override public void onAttach(Activity activity) { super.onAttach(activity); mQueryHandler = new ContactUriQueryHandler(activity.getContentResolver()); mPrefs = PreferenceManager.getDefaultSharedPreferences(activity); restoreFilter(); restoreSelectedUri(false); Loading Loading @@ -228,12 +241,10 @@ public abstract class ContactBrowseListFragment extends } protected void refreshSelectedContactUri() { if (mQueryHandler == null) { return; if (mContactLookupTask != null) { mContactLookupTask.cancel(); } mQueryHandler.cancelOperation(0); if (!isSelectionVisible()) { return; } Loading @@ -249,7 +260,8 @@ public abstract class ContactBrowseListFragment extends && mSelectedContactDirectoryId != Directory.LOCAL_INVISIBLE) { onContactUriQueryFinished(mSelectedContactUri); } else { mQueryHandler.runQuery(); mContactLookupTask = new ContactLookupTask(mSelectedContactUri); mContactLookupTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null); } } Loading
src/com/android/contacts/util/ContactLoaderUtils.java 0 → 100644 +78 −0 Original line number Diff line number Diff line /* * Copyright (C) 2011 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.contacts.util; import android.content.ContentResolver; import android.content.ContentUris; import android.net.Uri; import android.provider.Contacts; import android.provider.ContactsContract; import android.provider.ContactsContract.RawContacts; /** * Utility methods for the {@link ContactLoader}. */ public final class ContactLoaderUtils { /** Static helper, not instantiable. */ private ContactLoaderUtils() {} /** * Transforms the given Uri and returns a Lookup-Uri that represents the contact. * For legacy contacts, a raw-contact lookup is performed. An {@link IllegalArgumentException} * can be thrown if the URI is null or the authority is not recognized. * * Do not call from the UI thread. */ @SuppressWarnings("deprecation") public static Uri ensureIsContactUri(final ContentResolver resolver, final Uri uri) throws IllegalArgumentException { if (uri == null) throw new IllegalArgumentException("uri must not be null"); final String authority = uri.getAuthority(); // Current Style Uri? if (ContactsContract.AUTHORITY.equals(authority)) { final String type = resolver.getType(uri); // Contact-Uri? Good, return it if (ContactsContract.Contacts.CONTENT_ITEM_TYPE.equals(type)) { return uri; } // RawContact-Uri? Transform it to ContactUri if (RawContacts.CONTENT_ITEM_TYPE.equals(type)) { final long rawContactId = ContentUris.parseId(uri); return RawContacts.getContactLookupUri(resolver, ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId)); } // Anything else? We don't know what this is throw new IllegalArgumentException("uri format is unknown"); } // Legacy Style? Convert to RawContact final String OBSOLETE_AUTHORITY = Contacts.AUTHORITY; if (OBSOLETE_AUTHORITY.equals(authority)) { // Legacy Format. Convert to RawContact-Uri and then lookup the contact final long rawContactId = ContentUris.parseId(uri); return RawContacts.getContactLookupUri(resolver, ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId)); } throw new IllegalArgumentException("uri authority is unknown"); } }