20

I have one existing contact, I need to add a work address to that existing contact. I am using the following code, but it's not working.

String selectPhone = Data.CONTACT_ID + "=? AND " + Data.MIMETYPE + "='" + 
    ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE + 
    "'" + " AND " + ContactsContract.CommonDataKinds.StructuredPostal.TYPE + "=?"; 
String[] phoneArgs = new String[]
    {String.valueOf(ContactId), String.valueOf(
    ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK)}; 
ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI) 
    .withSelection(selectPhone, phoneArgs) 
    .withValue(ContactsContract.CommonDataKinds.StructuredPostal.STREET, STREET)
    .withValue(ContactsContract.CommonDataKinds.StructuredPostal.CITY, CITY) 
    .withValue(ContactsContract.CommonDataKinds.StructuredPostal.REGION, REGION)
    .withValue(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE, POSTCODE) 
    .withValue(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY, COUNTRY)  
    .build()); 
this.context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops); 

Any solution for this?

user788511
  • 1,586
  • 2
  • 29
  • 51
Baskar
  • 519
  • 2
  • 6
  • 12

6 Answers6

16
        /**
             * @param name name of the contact
             * @param number mobile phone number of contact
             * @param email work email address of contact
             * @param ContactId id of the contact which you want to update
             * @return true if contact is updated successfully<br/>
             *         false if contact is not updated <br/>
             *         false if phone number contains any characters(It should contain only digits)<br/>
             *         false if email Address is invalid <br/><br/>
             *         
             *  You can pass any one among the 3 parameters to update a contact.Passing all three parameters as <b>null</b> will not update the contact        
             *  <br/><br/><b>Note: </b>This method requires permission <b>android.permission.WRITE_CONTACTS</b><br/>
             */

            public boolean updateContact(String name, String number, String email,String ContactId) 
            {
                boolean success = true;
                String phnumexp = "^[0-9]*$";

                try
                {
                      name = name.trim();
                      email = email.trim();
                      number = number.trim();

                if(name.equals("")&&number.equals("")&&email.equals(""))
                 {
                    success = false;
                 }
                else if((!number.equals(""))&& (!match(number,phnumexp)) )
                 {
                    success = false;
                 }
                else if( (!email.equals("")) && (!isEmailValid(email)) )
                {
                    success = false;
                }
                else 
                {
                    ContentResolver contentResolver  = activity.getContentResolver();

                    String where = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?"; 

                    String[] emailParams = new String[]{ContactId, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE}; 
                    String[] nameParams = new String[]{ContactId, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE}; 
                    String[] numberParams = new String[]{ContactId, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE}; 

                    ArrayList<android.content.ContentProviderOperation> ops = new ArrayList<android.content.ContentProviderOperation>();

                 if(!email.equals(""))  
                 {
                     ops.add(android.content.ContentProviderOperation.newUpdate(android.provider.ContactsContract.Data.CONTENT_URI)
                          .withSelection(where,emailParams)
                          .withValue(Email.DATA, email)
                          .build());
                 }

                 if(!name.equals(""))
                 {
                     ops.add(android.content.ContentProviderOperation.newUpdate(android.provider.ContactsContract.Data.CONTENT_URI)
                          .withSelection(where,nameParams)
                          .withValue(StructuredName.DISPLAY_NAME, name)
                          .build());
                 }

                 if(!number.equals(""))
                 {

                     ops.add(android.content.ContentProviderOperation.newUpdate(android.provider.ContactsContract.Data.CONTENT_URI)
                          .withSelection(where,numberParams)
                          .withValue(Phone.NUMBER, number)
                          .build());
                 }
                    contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
                 }
                }
                catch (Exception e) 
                {
                 e.printStackTrace();
                 success = false;
                }
                return success;
            }



    // To get COntact Ids of all contact use the below method 

    /**
         * @return arraylist containing id's  of all contacts <br/> 
         *         empty arraylist if no contacts exist <br/><br/>
         * <b>Note: </b>This method requires permission <b>android.permission.READ_CONTACTS</b>
         */
        public ArrayList<String> getAllConactIds()
        {
            ArrayList<String> contactList = new ArrayList<String>();

             Cursor cursor = activity.managedQuery(ContactsContract.Contacts.CONTENT_URI, null, null, null, "display_name ASC");

                if (cursor != null) 
                {
                    if (cursor.moveToFirst()) 
                    {
                       do
                       {
                           int _id = cursor.getInt(cursor.getColumnIndex("_id"));
                           contactList.add(""+_id);

                       }
                       while(cursor.moveToNext());
                    }
                }

            return contactList;
        }


private boolean isEmailValid(String email) 
    {
        String emailAddress = email.toString().trim();
        if (emailAddress == null)
            return false;
        else if (emailAddress.equals(""))
            return false;
        else if (emailAddress.length() <= 6)
            return false;
        else {
            String expression = "^[a-z][a-z|0-9|]*([_][a-z|0-9]+)*([.][a-z|0-9]+([_][a-z|0-9]+)*)?@[a-z][a-z|0-9|]*\\.([a-z][a-z|0-9]*(\\.[a-z][a-z|0-9]*)?)$";
            CharSequence inputStr = emailAddress;
            Pattern pattern = Pattern.compile(expression,
                    Pattern.CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(inputStr);
            if (matcher.matches())
                return true;
            else
                return false;
        }
    }

    private boolean match(String stringToCompare,String regularExpression)
    {
        boolean success = false;
        Pattern pattern = Pattern.compile(regularExpression);
        Matcher matcher = pattern.matcher(stringToCompare);
        if(matcher.matches())
            success =true;
        return success;
    }
KK_07k11A0585
  • 2,313
  • 3
  • 23
  • 31
  • 1
    This answer is correct if there is only 1 phone number or name or email. If there are more than one phone number. for example you should add `String where = ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.CommonDataKinds.Phone.NUMBER + " = ?"; String[] numberParams = new String[]{ContactId, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE, oldPhoneNumber};` to modify all the phone numbers in one contact_id correctly – TranHieu Jun 25 '18 at 08:51
4

//Sorry for my bad english // It seems that in the first post you forgot to add the MimeType in operation.

String selectPhone = Data.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "='" + 
                    ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE +  "'" ; 
                String[] phoneArgs = new String[]{String.valueOf(rawContactId)}; 
                ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI) 
                    .withSelection(selectPhone, phoneArgs) 
                    .withValue(ContactsContract.CommonDataKinds.StructuredPostal.TYPE, ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK)
                    .withValue(ContactsContract.CommonDataKinds.StructuredPostal.STREET, STREET)
                    .withValue(ContactsContract.CommonDataKinds.StructuredPostal.CITY, CITY) 
                    .withValue(ContactsContract.CommonDataKinds.StructuredPostal.REGION, REGION)
                    .withValue(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE, POSTCODE) 
                    .withValue(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY, POSTCODE) 

**

//Just add this line .withValue(Data.MIMETYPE, "vnd.android.cursor.item/postal-address_v2")

**

     .build());
this.context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);

Please check this and let me know the result

Jack
  • 10,783
  • 12
  • 46
  • 65
Ruchit Mittal
  • 312
  • 1
  • 9
1

Finally I found the appropriate solution..Much thanks to this How to modify existing Contact

The secret is that you have to pass two values for .withSelection as shown below:

.withSelection(Data.RAW_CONTACT_ID + " = ?", new String[] {String.valueOf(id)})
.withSelection(Data._ID + " = ?", new String[] {mDataId})

where by Data._ID value mDataId is obtained this way:

Cursor mDataCursor = this.context.getContentResolver().query(
                        Data.CONTENT_URI,
                        null,
                        Data.RAW_CONTACT_ID + " = ? AND " + Data.MIMETYPE + " = ?",
                        new String[] { String.valueOf(id), ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE},
                        null);

                if(mDataCursor.getCount() > 0) {
                    mDataCursor.moveToFirst();
                    mDataId = getCursorString(mDataCursor, Data._ID);
                    MLog.v("Data", "Found data item with MIMETYPE");                            
                    mDataCursor.close();

                } else {
                    MLog.v("Data", "Data doesn't contain MIMETYPE");
                    result = ERROR;
                    mDataCursor.close();
                } 

And getCursorString method is something like:

private static String getCursorString(Cursor cursor, String columnName) {
        int index = cursor.getColumnIndex(columnName);
        if(index != -1) return cursor.getString(index);
        return null;
    }

This and only this is the trick..

Community
  • 1
  • 1
user788511
  • 1,586
  • 2
  • 29
  • 51
1

Each field (email, name, adreess) has its own mime type, which you should use in order to update the field.

We will work with Data table, where each Data.RAW_CONTACT_ID represents a detail about some contact.

So, we need to find the Data.RAW_CONTACT_ID where the id is the id of the contact you want to edit.

I hope this code should be helpful to you.

    String selectPhone = Data.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "='" + 
                        ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE +  "'" ; 
                    String[] phoneArgs = new String[]{String.valueOf(rawContactId)}; 
                    ops.add(ContentProviderOperation.newUpdate(Data.CONTENT_URI) 
                        .withSelection(selectPhone, phoneArgs) 
                        .withValue(ContactsContract.CommonDataKinds.StructuredPostal.TYPE, ContactsContract.CommonDataKinds.StructuredPostal.TYPE_WORK)
                        .withValue(ContactsContract.CommonDataKinds.StructuredPostal.STREET, STREET)
                        .withValue(ContactsContract.CommonDataKinds.StructuredPostal.CITY, CITY) 
                        .withValue(ContactsContract.CommonDataKinds.StructuredPostal.REGION, REGION)
                        .withValue(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE, POSTCODE) 
                        .withValue(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY, POSTCODE)  
                        .build());
this.context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);

If a new contact has been created, but without address, and now you want to add an address to that contcat. In this case use the same query as above, but just change newUpdate to newInsert, since such row isn't exist yet.

Jitendra
  • 883
  • 7
  • 22
0

you should use "Data.RAW_CONTACT_ID" instead of "Data.CONTACT_ID" in the clause of selection.

Zephyr
  • 5,408
  • 31
  • 32
-1

Maybe you could use Intent and its ACTION_EDIT to get your user Edit the work address...

turbodoom
  • 225
  • 1
  • 3
  • 14