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

Reply via email to