I'm trying to aggregate two `Contacts` using their `Contacts._ID` using
code from the `Android Contacts` application. I have sorted out many most
problems but `RawContacts.NAME_VERIFIED` is not in the `public API`. Could
you suggest any method to fix this without losing functionality? Also it
would be nice if you can point out any mistakes that I might have made. I
have posted the full code below.
public class JoinContacts {
>
> private static final String TAG = "JoinContacts";
> final ContentResolver resolver;
>
> public JoinContacts(ContentResolver cr) {
> resolver = cr;
> }
>
> private interface JoinContactQuery {
> String[] PROJECTION = { RawContacts._ID,
> RawContacts.CONTACT_ID,
> // FIXME Compiler breaks here
> RawContacts.NAME_VERIFIED,
> RawContacts.DISPLAY_NAME_SOURCE, };
>
> String SELECTION = RawContacts.CONTACT_ID + "=? OR "
> + RawContacts.CONTACT_ID + "=?";
>
> int _ID = 0;
> int CONTACT_ID = 1;
> int NAME_VERIFIED = 2;
> int DISPLAY_NAME_SOURCE = 3;
> }
>
> // private void joinContacts(Intent intent) {
> // long contactId1 = intent.getLongExtra(EXTRA_CONTACT_ID1, -1);
> // long contactId2 = intent.getLongExtra(EXTRA_CONTACT_ID2, -1);
> // boolean writable =
> intent.getBooleanExtra(EXTRA_CONTACT_WRITABLE, false);
>
> // Get contactIds as fields instead of from intent.
> private void joinContacts(long contactId1, long contactId2,
> boolean writable) {
>
> if (contactId1 == -1 || contactId2 == -1) {
> Log.e(TAG, "Invalid arguments for joinContacts request");
> return;
> }
>
> // final ContentResolver resolver = getContentResolver();
>
> // We will get ContentResolver from constructer instead.
>
> // Load raw contact IDs for all raw contacts involved -
> currently edited
> // and selected
> // in the join UIs
> Cursor c = resolver.query(
> RawContacts.CONTENT_URI,
> JoinContactQuery.PROJECTION,
> JoinContactQuery.SELECTION,
> new String[] { String.valueOf(contactId1),
> String.valueOf(contactId2) }, null);
>
> long rawContactIds[];
> long verifiedNameRawContactId = -1;
> try {
> int maxDisplayNameSource = -1;
> rawContactIds = new long[c.getCount()];
> for (int i = 0; i < rawContactIds.length; i++) {
> c.moveToPosition(i);
> long rawContactId = c.getLong(JoinContactQuery._ID);
> rawContactIds[i] = rawContactId;
> int nameSource =
> c.getInt(JoinContactQuery.DISPLAY_NAME_SOURCE);
> if (nameSource > maxDisplayNameSource) {
> maxDisplayNameSource = nameSource;
> }
> }
>
> // Find an appropriate display name for the joined contact:
> // if should have a higher DisplayNameSource or be the name
> // of the original contact that we are joining with
> another.
> if (writable) {
> for (int i = 0; i < rawContactIds.length; i++) {
> c.moveToPosition(i);
> if (c.getLong(JoinContactQuery.CONTACT_ID) ==
> contactId1) {
> int nameSource = c
>
> .getInt(JoinContactQuery.DISPLAY_NAME_SOURCE);
> if (nameSource == maxDisplayNameSource
> && (verifiedNameRawContactId == -1 || c
>
> .getInt(JoinContactQuery.NAME_VERIFIED) != 0)) {
> verifiedNameRawContactId = c
> .getLong(JoinContactQuery._ID);
> }
> }
> }
> }
> } finally {
> c.close();
> }
>
> // For each pair of raw contacts, insert an aggregation
> exception
> ArrayList<ContentProviderOperation> operations = new
> ArrayList<ContentProviderOperation>();
> for (int i = 0; i < rawContactIds.length; i++) {
> for (int j = 0; j < rawContactIds.length; j++) {
> if (i != j) {
> buildJoinContactDiff(operations, rawContactIds[i],
> rawContactIds[j]);
> }
> }
> }
>
> // Mark the original contact as "name verified" to make sure
> that the
> // contact
> // display name does not change as a result of the join
> if (verifiedNameRawContactId != -1) {
> Builder builder =
> ContentProviderOperation.newUpdate(ContentUris
> .withAppendedId(RawContacts.CONTENT_URI,
> verifiedNameRawContactId));
> // FIXME Compiler breaks here
> builder.withValue(RawContacts.NAME_VERIFIED, 1);
> operations.add(builder.build());
> }
>
> boolean success = false;
> // Apply all aggregation exceptions as one batch
>
> // TODO add strings.
> try {
> resolver.applyBatch(ContactsContract.AUTHORITY,
> operations);
> // showToast(R.string.contactsJoinedMessage);
> success = true;
> } catch (RemoteException e) {
> Log.e(TAG, "Failed to apply aggregation exception batch",
> e);
> // showToast(R.string.contactSavedErrorToast);
> } catch (OperationApplicationException e) {
> Log.e(TAG, "Failed to apply aggregation exception batch",
> e);
> // showToast(R.string.contactSavedErrorToast);
> }
>
> // We dont need these lines
>
> // Intent callbackIntent = intent
> // .getParcelableExtra(EXTRA_CALLBACK_INTENT);
> // if (success) {
> // Uri uri = RawContacts.getContactLookupUri(resolver,
> ContentUris
> // .withAppendedId(RawContacts.CONTENT_URI, rawContactIds[0]));
> // callbackIntent.setData(uri);
> // }
> // deliverCallback(callbackIntent);
> }
>
> /**
> * Construct a {@link AggregationExceptions#TYPE_KEEP_TOGETHER}
> * ContentProviderOperation.
> */
> private void buildJoinContactDiff(
> ArrayList<ContentProviderOperation> operations, long
> rawContactId1,
> long rawContactId2) {
> Builder builder = ContentProviderOperation
> .newUpdate(AggregationExceptions.CONTENT_URI);
> builder.withValue(AggregationExceptions.TYPE,
> AggregationExceptions.TYPE_KEEP_TOGETHER);
> builder.withValue(AggregationExceptions.RAW_CONTACT_ID1,
> rawContactId1);
> builder.withValue(AggregationExceptions.RAW_CONTACT_ID2,
> rawContactId2);
> operations.add(builder.build());
> }
> }
>
--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en