72

I have written following code to add new contact in android phone book, it is working but when i open contact menu, i cannot see the new contact added. Can anyone help me to find out what's wrong here?

import android.app.Activity;
import android.os.Bundle;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.provider.ContactsContract;

import android.widget.TextView;
import android.widget.Toast;

public class AddContacts extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        try {
            ContentResolver cr = this.getContentResolver();
            ContentValues cv = new ContentValues();
            cv.put(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, "New Name");
            cv.put(ContactsContract.CommonDataKinds.Phone.NUMBER, "1234567890");
            cv.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
            cr.insert(ContactsContract.RawContacts.CONTENT_URI, cv);

            Toast.makeText(this, "Contact added", Toast.LENGTH_LONG).show();
        } catch(Exception e) {
            TextView tv = new TextView(this);
            tv.setText(e.toString());
            setContentView(tv);
        }
    }
}
Mike
  • 4,550
  • 4
  • 33
  • 47
Aditya Mehta
  • 811
  • 3
  • 9
  • 8
  • 1
    this link may be usefuk to u http://saigeethamn.blogspot.com/2009/09/android-developer-tutorial-part-10.html – Parag Chauhan Jan 20 '11 at 07:15
  • 1
    Thank u Parag Saigeethamn's blog is also helpful – Aditya Mehta Jan 20 '11 at 10:42
  • but is for older versions of android – Aditya Mehta Jan 20 '11 at 10:53
  • 1
    This is for the new versions: http://saigeethamn.blogspot.in/2011/05/contacts-api-20-and-above-android.html – AndroidGuy Sep 21 '12 at 09:47
  • khawar ...ur answer is excellent for me also its working but i want to add contacts with ringtone plz post the code for ringtone i have some code but its not working if(ringtonepath != null) { ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) .withValue(ContactsContract.CommonDataKinds.Phone.CUSTOM_RINGTONE, ringtonepath) .build() ); } – AndroidRaji Sep 25 '12 at 06:16
  • i need a code to insert the ringtone with contacts into native app. Now i able to insert the new contact with name,phone number and email id. But i cant add ringtone. please help me – AndroidRaji Sep 25 '12 at 08:04
  • @AndroidRaji http://stackoverflow.com/questions/8593435/android-adding-ringtone-to-contact-doesnt-work-on-a-contact-i-just-added-but – Parag Chauhan Sep 25 '12 at 08:22
  • Is there any way, that after calling applyBatch(), i get the URI of the newly added contact, because I need to take the user to the Contact-Detail screen of the People app. – AndroidGuy Sep 25 '12 at 12:35

5 Answers5

184

Here I am posting a piece of code that i use to add a new contact. It works fine for me. I hope it will help you.

 String DisplayName = "XYZ";
 String MobileNumber = "123456";
 String HomeNumber = "1111";
 String WorkNumber = "2222";
 String emailID = "email@nomail.com";
 String company = "bad";
 String jobTitle = "abcd";

 ArrayList < ContentProviderOperation > ops = new ArrayList < ContentProviderOperation > ();

 ops.add(ContentProviderOperation.newInsert(
 ContactsContract.RawContacts.CONTENT_URI)
     .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
     .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
     .build());

 //------------------------------------------------------ Names
 if (DisplayName != null) {
     ops.add(ContentProviderOperation.newInsert(
     ContactsContract.Data.CONTENT_URI)
         .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
         .withValue(ContactsContract.Data.MIMETYPE,
     ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
         .withValue(
     ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
     DisplayName).build());
 }

 //------------------------------------------------------ Mobile Number                     
 if (MobileNumber != null) {
     ops.add(ContentProviderOperation.
     newInsert(ContactsContract.Data.CONTENT_URI)
         .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
         .withValue(ContactsContract.Data.MIMETYPE,
     ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
         .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, MobileNumber)
         .withValue(ContactsContract.CommonDataKinds.Phone.TYPE,
     ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
         .build());
 }

 //------------------------------------------------------ Home Numbers
 if (HomeNumber != null) {
     ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
         .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
         .withValue(ContactsContract.Data.MIMETYPE,
     ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
         .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, HomeNumber)
         .withValue(ContactsContract.CommonDataKinds.Phone.TYPE,
     ContactsContract.CommonDataKinds.Phone.TYPE_HOME)
         .build());
 }

 //------------------------------------------------------ Work Numbers
 if (WorkNumber != null) {
     ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
         .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
         .withValue(ContactsContract.Data.MIMETYPE,
     ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
         .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, WorkNumber)
         .withValue(ContactsContract.CommonDataKinds.Phone.TYPE,
     ContactsContract.CommonDataKinds.Phone.TYPE_WORK)
         .build());
 }

 //------------------------------------------------------ Email
 if (emailID != null) {
     ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
         .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
         .withValue(ContactsContract.Data.MIMETYPE,
     ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
         .withValue(ContactsContract.CommonDataKinds.Email.DATA, emailID)
         .withValue(ContactsContract.CommonDataKinds.Email.TYPE, ContactsContract.CommonDataKinds.Email.TYPE_WORK)
         .build());
 }

 //------------------------------------------------------ Organization
 if (!company.equals("") && !jobTitle.equals("")) {
     ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
         .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
         .withValue(ContactsContract.Data.MIMETYPE,
     ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE)
         .withValue(ContactsContract.CommonDataKinds.Organization.COMPANY, company)
         .withValue(ContactsContract.CommonDataKinds.Organization.TYPE, ContactsContract.CommonDataKinds.Organization.TYPE_WORK)
         .withValue(ContactsContract.CommonDataKinds.Organization.TITLE, jobTitle)
         .withValue(ContactsContract.CommonDataKinds.Organization.TYPE, ContactsContract.CommonDataKinds.Organization.TYPE_WORK)
         .build());
 }

 // Asking the Contact provider to create a new contact                 
 try {
     getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
 } catch (Exception e) {
     e.printStackTrace();
     Toast.makeText(myContext, "Exception: " + e.getMessage(), Toast.LENGTH_SHORT).show();
 } 

Here is the code. Integrate it according to your need. I hope it will help.

Vipul
  • 27,808
  • 7
  • 60
  • 75
Khawar
  • 5,197
  • 4
  • 28
  • 52
  • help please... still it is not showing newly added contact in contact menu – Aditya Mehta Jan 20 '11 at 13:41
  • also it has started throwing exception "OperationApplicationException: insert failed" at "getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);" – Aditya Mehta Jan 20 '11 at 13:50
  • 12
    Hi Aditya, I just checked the code in Android2.1 & Android 2.2. It worked fine for me. I just added "android.permission.WRITE_CONTACTS". I hope you are using this permission. If not please add this and try again =) – Khawar Jan 21 '11 at 07:20
  • Thanks Khawar, it worked for me too, actually i was making two mistakes- 1. To add person's name i was writing "ContentProviderOperation.newInsert(ContactsContract.RawContact.CONTENT_URI)" instead of "ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)". 2. among one of the phone number i forgot to write MIMETYPE. Anway... now it has also worked for me, Thanks a lot. – Aditya Mehta Jan 21 '11 at 10:39
  • 5
    you welcome... please vote or accept the answer as it worked for you :) – Khawar Jan 31 '11 at 15:04
  • 1
    Is there any way, that after calling applyBatch(), i get the URI of the newly added contact, because I need to take the user to the Contact-Detail screen of the People app. – AndroidGuy Sep 25 '12 at 12:29
  • **Above example** String DisplayName = "XYZ; String MobileNumber = "123456"; ------------- I corrupted my whole contact list when I was trying it on Samsung G550 with Android v3.1, Beware that such code is not safe, it replaced all first name to value "1", only my backup saved me. **AGAIN DO NOT TRY ON PRODUCTION UNIT WITHOUT HAVING PROPER BACKUP OF CONTACTS OTHERWISE your LIFE WILL BE MISERABLE.** – Devang Modi Oct 06 '12 at 11:45
  • 1
    if email address or some other attributes are more than once than how to handle them – Supreet Apr 12 '13 at 13:05
  • @Khawar if we don't put the null check it will give insert failed error. ! – Rachit Mishra Nov 26 '13 at 15:20
  • Perfect ans...nice one – Hiren Patel May 24 '14 at 09:50
  • How to Add Website URL in contact ? – ckpatel Aug 20 '14 at 09:57
  • @Khawar, would you like to help me out for connecting existing contact with my app ? like we have social app contacts. – Abdul Wahab Nov 12 '14 at 22:59
  • How do I open the contact's screen right after creating it here? – android developer Jun 02 '15 at 10:57
  • It works but if I run this code multiple times there would be multiple contacts with the same display name created. Is there any method to avoid this? – DYS Jun 11 '15 at 02:58
  • Remember to request the contact permissions both read and write using the manifest or requesting at runtime with https://developer.android.com/training/permissions/requesting.html – Ollegn Apr 09 '18 at 13:20
26

These examples are fine, I wanted to point out that you can achieve the same result using an Intent. The intent opens the Contacts app with the fields you provide already filled in.

It's up to the user to save the newly created contact.

You can read about it here: https://developer.android.com/training/contacts-provider/modify-data.html

Intent contactIntent = new Intent(ContactsContract.Intents.Insert.ACTION);
contactIntent.setType(ContactsContract.RawContacts.CONTENT_TYPE);

contactIntent
        .putExtra(ContactsContract.Intents.Insert.NAME, "Contact Name")
        .putExtra(ContactsContract.Intents.Insert.PHONE, "5555555555");

startActivityForResult(contactIntent, 1);

startActivityForResult() gives you the opportunity to see the result.

I've noticed the resultCode works on >5.0 devices,

but I have an older Samsung (<5) that always returns RESULT_CANCELLED (0).

Which I understand is the default return if an activity doesn't expect to return anything.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);

    if (requestCode == 1)
    {
        if (resultCode == Activity.RESULT_OK) {
            Toast.makeText(this, "Added Contact", Toast.LENGTH_SHORT).show();
        }
        if (resultCode == Activity.RESULT_CANCELED) {
            Toast.makeText(this, "Cancelled Added Contact", Toast.LENGTH_SHORT).show();
        }
    }
}
Mr. Sajid Shaikh
  • 7,051
  • 4
  • 21
  • 35
jj.
  • 2,210
  • 3
  • 21
  • 22
23

This is working fine for me:

ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
            int rawContactInsertIndex = ops.size();

            ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
                    .withValue(RawContacts.ACCOUNT_TYPE, null)
                    .withValue(RawContacts.ACCOUNT_NAME, null).build());
            ops.add(ContentProviderOperation
                    .newInsert(Data.CONTENT_URI)
                    .withValueBackReference(Data.RAW_CONTACT_ID,rawContactInsertIndex)
                    .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
                    .withValue(StructuredName.DISPLAY_NAME, "Vikas Patidar") // Name of the person
                    .build());
            ops.add(ContentProviderOperation
                    .newInsert(Data.CONTENT_URI)
                    .withValueBackReference(
                            ContactsContract.Data.RAW_CONTACT_ID,   rawContactInsertIndex)
                    .withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
                    .withValue(Phone.NUMBER, "9999999999") // Number of the person
                    .withValue(Phone.TYPE, Phone.TYPE_MOBILE).build()); // Type of mobile number                    
            try
            {
                ContentProviderResult[] res = getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
            }
            catch (RemoteException e)
            { 
                // error
            }
            catch (OperationApplicationException e) 
            {
                // error
            }       
Vikas Patidar
  • 42,865
  • 22
  • 93
  • 106
3

It's not that above answers are incorrect, but I find this code extremely easy to understand and therefore I am sharing it here with everyone. And there is also the check for WRITE_CONTACTS permission.

Here is the complete code for how to add phone number, email, website etc to an existing contact.

public static void addNumberToContact(Context context, Long contactRawId, String number) throws RemoteException, OperationApplicationException {
    addInfoToAddressBookContact(
            context,
            contactRawId,
            ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
            ContactsContract.CommonDataKinds.Phone.NUMBER,
            ContactsContract.CommonDataKinds.Phone.TYPE,
            ContactsContract.CommonDataKinds.Phone.TYPE_OTHER,
            number
    );
}

public static void addEmailToContact(Context context, Long contactRawId, String email) throws RemoteException, OperationApplicationException {
    addInfoToAddressBookContact(
            context,
            contactRawId,
            ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
            ContactsContract.CommonDataKinds.Email.ADDRESS,
            ContactsContract.CommonDataKinds.Email.TYPE,
            ContactsContract.CommonDataKinds.Email.TYPE_OTHER,
            email
    );
}

public static void addURLToContact(Context context, Long contactRawId, String url) throws RemoteException, OperationApplicationException {
    addInfoToAddressBookContact(
            context,
            contactRawId,
            ContactsContract.CommonDataKinds.Website.CONTENT_ITEM_TYPE,
            ContactsContract.CommonDataKinds.Website.URL,
            ContactsContract.CommonDataKinds.Website.TYPE,
            ContactsContract.CommonDataKinds.Website.TYPE_OTHER,
            url
    );
}

private static void addInfoToAddressBookContact(Context context, Long contactRawId, String mimeType, String whatToAdd, String typeKey, int type, String data) throws RemoteException, OperationApplicationException {
    if(ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_DENIED) {
        return;
    }
    ArrayList<ContentProviderOperation> ops = new ArrayList<>();
    ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            .withValue(ContactsContract.Data.RAW_CONTACT_ID, contactRawId)
            .withValue(ContactsContract.Data.MIMETYPE, mimeType)
            .withValue(whatToAdd, data)
            .withValue(typeKey, type)
            .build());
    getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
}
Bugs Happen
  • 2,169
  • 4
  • 33
  • 59
0

With this intent you can save phone number in the contacts easily:

Intent intent = new Intent(Intent.ACTION_INSERT);
intent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
intent.putExtra(ContactsContract.Intents.Insert.PHONE, yourPhoneNumber);
startActivity(intent);
Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263