Search code examples
androidemailandroid-contentprovidercontactsandroid-contacts

How to update a particular email Address in contacts?


i use the following the code to update the number:

ContentValues mobilePhoneValues = new ContentValues();
        mobilePhoneValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, typePhone);
        mobilePhoneValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, binding.numberEdit.getText().toString());
        getContentResolver().update(ContactsContract.Data.CONTENT_URI, mobilePhoneValues,
       ContactsContract.CommonDataKinds.Phone.NUMBER + "=?", new String[]{mobilePhoneNumbers.get(0)});

It works perfectly but when i try to update the email using same logic it fails to update it. Code:

 ContentValues contentValues1 = new ContentValues();
        contentValues1.put(ContactsContract.CommonDataKinds.Email.TYPE, typeEmail);
        contentValues1.put(ContactsContract.CommonDataKinds.Email.DATA, binding.emailEdit.getText().toString());
        getContentResolver().update(ContactsContract.Data.CONTENT_URI, contentValues1,
        ContactsContract.CommonDataKinds.Email.DATA + "=?", new String[]{homeEmailNumbers.get(0)});

Why is it the same logic updates the number but fails to update the email ? Please help


Solution

  • There's a big problem in both examples.

    You are telling the API - change any occurrence of phone (or email) "X" to "Y" across all contacts.

    It depends on your use case, but I'm assuming you want to let users edit contact information.

    For that use case that's not what you intend to be doing. instead, you should tell the API - take row with ID "12345" and change its value to "Y".

    Adding the contact-id to the WHERE clause will also have unintended consequences when you consider a case where a certain contact has 2 duplicate phone numbers, and the user wants to edit one of them - you don't want to modify both numbers in this case.

    You should first change the way you read and present the data, so every data row for every contact also holds the specific Data table row ID (Data._ID) and then the code is:

    batch update approach (preferred):

    ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
    ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI)
              .withSelection(Data._ID + "=?", new String[]{String.valueOf(dataId)})
              .withValue(CommonColumns.TYPE, newType)
              .withValue(CommonColumns.DATA, newData)
              .build());
     getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
    

    single change approach:

    ContentValues values = new ContentValues();
    values.put(CommonColumns.TYPE, newType);
    values.put(CommonColumns.DATA, newData);
    getContentResolver().update(Data.CONTENT_URI, values,
           Data._ID + "=?", new String[]{String.valueOf(dataId)});
    

    The use of CommonColumns and Data._ID allows for the same code to work for both phones, emails, and some other common types.