/** * Fully upgrades this ContactLoader to one with all lists fully loaded. When done, the * new result will be delivered */ public void upgradeToFullContact() { // Everything requested already? Nothing to do, so let's bail out if (mLoadGroupMetaData && mLoadInvitableAccountTypes && mPostViewNotification && mComputeFormattedPhoneNumber) return; mLoadGroupMetaData = true; mLoadInvitableAccountTypes = true; mPostViewNotification = true; mComputeFormattedPhoneNumber = true; // Cache the current result, so that we only load the "missing" parts of the contact. cacheResult(); // Our load parameters have changed, so let's pretend the data has changed. Its the same // thing, essentially. onContentChanged(); }
@Override protected void onReset() { super.onReset(); cancelLoad(); unregisterObserver(); mContact = null; }
/** * Extracts RawContact level columns from the cursor. */ private ContentValues loadRawContactValues(Cursor cursor) { ContentValues cv = new ContentValues(); cv.put(RawContacts._ID, cursor.getLong(ContactQuery.RAW_CONTACT_ID)); cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_NAME); cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_TYPE); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SET); cursorColumnToContentValues(cursor, cv, ContactQuery.DIRTY); cursorColumnToContentValues(cursor, cv, ContactQuery.VERSION); cursorColumnToContentValues(cursor, cv, ContactQuery.SOURCE_ID); cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC1); cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC2); cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC3); cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC4); cursorColumnToContentValues(cursor, cv, ContactQuery.DELETED); cursorColumnToContentValues(cursor, cv, ContactQuery.CONTACT_ID); cursorColumnToContentValues(cursor, cv, ContactQuery.STARRED); return cv; }
@Override protected void onStartLoading() { if (mContact != null) { deliverResult(mContact); } if (takeContentChanged() || mContact == null) { forceLoad(); } }
Log.e(TAG, "loadInBackground=" + mLookupUri); try { final ContentResolver resolver = getContext().getContentResolver(); final Uri uriCurrentFormat = ContactLoaderUtils.ensureIsContactUri( resolver, mLookupUri); } else { if (uriCurrentFormat.getLastPathSegment().equals(Constants.LOOKUP_URI_ENCODED)) { result = loadEncodedContactEntity(uriCurrentFormat, mLookupUri); } else { result = loadContactEntity(resolver, uriCurrentFormat); if (result.isDirectoryEntry()) { if (!resultIsCached) { loadDirectoryMetaData(result); loadGroupMetaData(result); computeFormattedPhoneNumbers(result); if (!resultIsCached) loadPhotoBinaryData(result); loadInvitableAccountTypes(result);
@Override public void deliverResult(Contact result) { unregisterObserver(); // The creator isn't interested in any further updates if (isReset() || result == null) { return; } mContact = result; if (result.isLoaded()) { mLookupUri = result.getLookupUri(); if (!result.isDirectoryEntry()) { Log.i(TAG, "Registering content observer for " + mLookupUri); if (mObserver == null) { mObserver = new ForceLoadContentObserver(); } getContext().getContentResolver().registerContentObserver( mLookupUri, true, mObserver); } if (mPostViewNotification) { // inform the source of the data that this contact is being looked at postViewNotificationToSyncAdapter(); } } super.deliverResult(mContact); }
Contact contact = loadContactHeaderData(cursor, contactUri); rawContact = new RawContact(loadRawContactValues(cursor)); rawContactsBuilder.add(rawContact); ContentValues data = loadDataValues(cursor); rawContact.addDataItemValues(data);
private void unregisterObserver() { if (mObserver != null) { getContext().getContentResolver().unregisterContentObserver(mObserver); mObserver = null; } }
loadThumbnailBinaryData(contactData); fd = null; } else { fd = getContext().getContentResolver().openAssetFileDescriptor(uri, "r"); inputStream = fd.createInputStream();
@Override protected void onStopLoading() { cancelLoad(); }
private void loadDirectoryMetaData(Contact result) { long directoryId = result.getDirectoryId(); Cursor cursor = getContext().getContentResolver().query( ContentUris.withAppendedId(Directory.CONTENT_URI, directoryId), DirectoryQuery.COLUMNS, null, null, null); String directoryType = null; if (!TextUtils.isEmpty(packageName)) { PackageManager pm = getContext().getPackageManager(); try { Resources resources = pm.getResourcesForApplication(packageName);
/** * Posts a message to the contributing sync adapters that have opted-in, notifying them * that the contact has just been loaded */ private void postViewNotificationToSyncAdapter() { Context context = getContext(); for (RawContact rawContact : mContact.getRawContacts()) { final long rawContactId = rawContact.getId(); if (mNotifiedRawContactIds.contains(rawContactId)) { continue; // Already notified for this raw contact. } mNotifiedRawContactIds.add(rawContactId); final AccountType accountType = rawContact.getAccountType(context); final String serviceName = accountType.getViewContactNotifyServiceClassName(); final String servicePackageName = accountType.getViewContactNotifyServicePackageName(); if (!TextUtils.isEmpty(serviceName) && !TextUtils.isEmpty(servicePackageName)) { final Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId); final Intent intent = new Intent(); intent.setClassName(servicePackageName, serviceName); intent.setAction(Intent.ACTION_VIEW); intent.setDataAndType(uri, RawContacts.CONTENT_ITEM_TYPE); try { context.startService(intent); } catch (Exception e) { Log.e(TAG, "Error sending message to source-app", e); } } } }
cursorColumnToContentValues(cursor, cv, ContactQuery.DATA1); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA2); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA3); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA4); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA5); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA6); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA7); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA8); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA9); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA10); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA11); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA12); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA13); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA14); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA15); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC1); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC2); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC3); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC4); cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_VERSION); cursorColumnToContentValues(cursor, cv, ContactQuery.IS_PRIMARY); cursorColumnToContentValues(cursor, cv, ContactQuery.IS_SUPERPRIMARY); cursorColumnToContentValues(cursor, cv, ContactQuery.MIMETYPE); cursorColumnToContentValues(cursor, cv, ContactQuery.GROUP_SOURCE_ID); cursorColumnToContentValues(cursor, cv, ContactQuery.CHAT_CAPABILITY); cursorColumnToContentValues(cursor, cv, ContactQuery.TIMES_USED); cursorColumnToContentValues(cursor, cv, ContactQuery.LAST_TIME_USED); if (CompatUtils.isMarshmallowCompatible()) { cursorColumnToContentValues(cursor, cv, ContactQuery.CARRIER_PRESENCE);
/** * Iterates over all data items that represent phone numbers are tries to calculate a formatted * number. This function can safely be called several times as no unformatted data is * overwritten */ private void computeFormattedPhoneNumbers(Contact contactData) { final String countryIso = GeoUtil.getCurrentCountryIso(getContext()); final ImmutableList<RawContact> rawContacts = contactData.getRawContacts(); final int rawContactCount = rawContacts.size(); for (int rawContactIndex = 0; rawContactIndex < rawContactCount; rawContactIndex++) { final RawContact rawContact = rawContacts.get(rawContactIndex); final List<DataItem> dataItems = rawContact.getDataItems(); final int dataCount = dataItems.size(); for (int dataIndex = 0; dataIndex < dataCount; dataIndex++) { final DataItem dataItem = dataItems.get(dataIndex); if (dataItem instanceof PhoneDataItem) { final PhoneDataItem phoneDataItem = (PhoneDataItem) dataItem; phoneDataItem.computeFormattedPhoneNumber(countryIso); } } } }
final Cursor cursor = getContext().getContentResolver().query(Groups.CONTENT_URI, GroupQuery.COLUMNS, selection.toString(), selectionArgs.toArray(new String[0]), null);
/** * Sets the "invitable" account types to {@link Contact#mInvitableAccountTypes}. */ private void loadInvitableAccountTypes(Contact contactData) { final ImmutableList.Builder<AccountType> resultListBuilder = new ImmutableList.Builder<AccountType>(); if (!contactData.isUserProfile()) { Map<AccountTypeWithDataSet, AccountType> invitables = AccountTypeManager.getInstance(getContext()).getUsableInvitableAccountTypes(); if (!invitables.isEmpty()) { final Map<AccountTypeWithDataSet, AccountType> resultMap = Maps.newHashMap(invitables); // Remove the ones that already have a raw contact in the current contact for (RawContact rawContact : contactData.getRawContacts()) { final AccountTypeWithDataSet type = AccountTypeWithDataSet.get( rawContact.getAccountTypeString(), rawContact.getDataSet()); resultMap.remove(type); } resultListBuilder.addAll(resultMap.values()); } } // Set to mInvitableAccountTypes contactData.setInvitableAccountTypes(resultListBuilder.build()); }