How to add one contact with multiple numbers on android phone programmatically?
This is how we can do this
pass Name and Array of numbers to this method.
public static void addToContactList(Context context, String strDisplayName, String[] strNumber) throws Exception {
ArrayList<ContentProviderOperation> cntProOper = new ArrayList<>();
int contactIndex = cntProOper.size();//ContactSize
ContentResolver contactHelper = context.getContentResolver();
cntProOper.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)//Step1
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null).build());
//Display name will be inserted in ContactsContract.Data table
cntProOper.add(ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI)//Step2
.withValueBackReference(android.provider.ContactsContract.Data.RAW_CONTACT_ID, contactIndex)
.withValue(android.provider.ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, strDisplayName) // Name of the contact
.build());
for (String s : strNumber) {
//Mobile number will be inserted in ContactsContract.Data table
cntProOper.add(ContentProviderOperation.newInsert(android.provider.ContactsContract.Data.CONTENT_URI)//Step 3
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, contactIndex)
.withValue(android.provider.ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, s) // Number to be added
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE).build()); //Type like HOME, MOBILE etc
}
ContentProviderResult[] s = context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, cntProOper); //apply above data insertion into contacts list
for (ContentProviderResult r : s) {
Log.i(TAG, "addToContactList: " + r.uri);
}
}
Related
Want to add thousands of contacts in phonebook through a content provider in Android.
I have implemented of adding a contact in the following way:
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
int rawContactID = ops.size();
// Adding insert operation to operations list
// to insert a new raw contact in the table ContactsContract.RawContacts
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
.build());
// Adding insert operation to operations list
// to insert display name in the table ContactsContract.Data
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, contact.getContactName())
.build());
// Adding insert operation to operations list
// to insert Mobile Number in the table ContactsContract.Data
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.phone)
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
.build());
// Adding insert operation to operations list
// to insert Home Email in the table ContactsContract.Data
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, contact.email)
.withValue(ContactsContract.CommonDataKinds.Email.TYPE, ContactsContract.CommonDataKinds.Email.TYPE_HOME)
.build());
try {
// Executing all the insert operations as a single database transaction
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
e.printStackTrace();
} catch (OperationApplicationException e) {
e.printStackTrace();
}
It takes ~175 seconds per 1000 contacts.
And when I use executor service with a thread pool 10, still it takes ~155 seconds per 1000 contacts. (Not much efficient)
Is there any other way to make contacts saving faster?
Ok, so the good thing about your code is that you apply your ops in batches.
The not-optimal thing about your code is that your batches are very small, 4 ops each.
You can instead gather bigger batches (i would recommend around 500 a batch, but you can play with the number.
Here's some untested code:
private static final int BATCH_SIZE = 500;
private void addThousandContacts() {
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
addSingleContact(ops);
if (ops.size() >= BATCH_SIZE) {
try {
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
ops.clear(); // remove all applied operations and start a new batch
} catch (RemoteException e) {
e.printStackTrace();
} catch (OperationApplicationException e) {
e.printStackTrace();
}
}
}
}
private void addSingleContact(ArrayList<ContentProviderOperation> ops) {
int rawInsertIndex = ops.size();
// Adding insert operation to operations list
// to insert a new raw contact in the table ContactsContract.RawContacts
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
.build());
// Adding insert operation to operations list
// to insert display name in the table ContactsContract.Data
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawInsertIndex) // tells the system the index of the operation that contains the current RawContactId
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, contact.getContactName())
.build());
... // add more operations email, phone, etc.
}
I don't know what I am doing wrong while inserting contact into phonebook.
here is the code to insert.
public static void AddMultipleContact(Context context, String name , String numbers, String Data4){
ContentResolver resolver = context.getContentResolver();
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
int rawContactInsertIndex = ops.size();
ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.RawContacts.CONTENT_URI, true))
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, AccountGeneral.ACCOUNT_NAME)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, AccountGeneral.ACCOUNT_TYPE)
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT)
.withValue(ContactsContract.RawContacts.SOURCE_ID, sourceId)
.build());
ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
.withValueBackReference(Data.RAW_CONTACT_ID, rawContactInsertIndex)
.withValue(RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, numbers) // Number of the person
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
.build()); // Type of mobile number
android.util.Log.e(TAG, "AddMultipleContact:-------------- NAME = " + name);
ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
.withValueBackReference(ContactsContract.RawContacts.Data.RAW_CONTACT_ID, rawContactInsertIndex)
.withValue(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name)
.build());
ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
.withValueBackReference(ContactsContract.RawContacts.Data.RAW_CONTACT_ID, rawContactInsertIndex)
.withValue(ContactsContract.RawContacts.Data.MIMETYPE,MIMETYPE)
.withValue(Data.DATA1, sourceId)
.withValue(Data.DATA3, Data4)
.build());
try {
ContentProviderResult[] results = resolver.applyBatch(ContactsContract.AUTHORITY, ops);
}
catch (Exception e) {
e.printStackTrace();
}
}
As you can see i am also printing log for name.
android.util.Log.e(TAG, "AddMultipleContact:-------------- NAME = " + name);
Here i am sending contactName and contactNumber to this method.
the name what I am passing is suppose ex: "A.Bcdef"
but the name what I am seeing in the phonebook is "A. Bcdef"
It is adding extra space after period(.).
Please help me. I am not getting any solution on google, or not able to search exactly what I want to search.
Thanks in advance.
I SOLVED THIS BY Changing this line
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name)
to
.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name)
GIVEN_NAME is taking the same name what we passed as value
There are other parameters like
DISPLAY_NAME, GIVEN_NAME, FAMILY_NAME, PREFIX, MIDDLE_NAME, SUFFIX, PHONETIC_GIVEN_NAME, PHONETIC_MIDDLE_NAME, PHONETIC_FAMILY_NAME, FULL_NAME_STYLE, PHONETIC_NAME_STYLE
I really don't know what actually these all means.
But when i added name as 'Testing,123' while creating a contact, then the name appears to be like '123 Testing'.
So I thought it is automatically thinking like what is 'middleName' and 'lastName' based on SpecialCharacters.
I developing an app in which I need to store data related to a contact.
I list the contacts in a recycleView using a cursor and each itemView has a star button to set the contact as favorite (not the same as the system).
I managed to store the data in ContactsContract.Data, doing this:
private void addContactData(long contactId, String displayName, boolean favorite) {
// displayName same as the value for Contacts.DISPLAY_NAME_PRIMARY
ArrayList<ContentProviderOperation> ops =
new ArrayList<>();
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, CUSTOM_ACCOUNT_TYPE)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, CUSTOM_ACCOUNT_NAME)
.withValue(ContactsContract.RawContacts.CONTACT_ID, contactId)
.build());
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());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE, CustomData.CONTENT_ITEM_TYPE)
.withValue(CustomData.IS_FAVORITE, favorite)
.build());
try {
ContentProviderResult[] contentProviderResults = cr.applyBatch(ContactsContract.AUTHORITY, ops);
return contactUri;
} catch (RemoteException | OperationApplicationException e) {
Log.e(getClass().getSimpleName(), e.getMessage(), e);
return null;
}
}
The problem I have is when two contacts have the exact same name ej. "Tom" and "Tom" if I press the fav button, is adding a third contact that is even listed in the device contacts app.
Some search guied me to add more data to distinguish the contacts using:
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, phone)
.build());
// OR
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.ADDRESS, email)
.build());
And it worked just fine, except if the fields are equals in both contacts. What do I need to avoid this behavior, and Why the CONTACT_ID isn't enough to do this kind of operations?
You need to tell Android to merge the new RawContact you've just created with some (one or more) existing RawContacts.
You do that using the AggregationException table, adding a row for each such "link".
See: https://stackoverflow.com/a/40869351/819355
Code snippet:
Builder builder = ContentProviderOperation.newUpdate(AggregationExceptions.CONTENT_URI);
builder.withValue(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_TOGETHER);
builder.withValue(AggregationExceptions.RAW_CONTACT_ID1, yourNewRawContact);
builder.withValue(AggregationExceptions.RAW_CONTACT_ID2, someExistingRawContact);
ContentProviderOperation op = builder.build();
/**
* Account type id
*/
public static final String ACCOUNT_TYPE = "com.test.app";
/**
* Account name
*/
public static final String ACCOUNT_NAME = "Test";
public static void addContact(Context context, User contact) {
ContentResolver resolver = context.getContentResolver();
resolver.delete(RawContacts.CONTENT_URI, RawContacts.ACCOUNT_TYPE
+ " = ?", new String[] { AccountConstants.ACCOUNT_TYPE });
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation
.newInsert(
addCallerIsSyncAdapterParameter(
RawContacts.CONTENT_URI, true))
.withValue(RawContacts.ACCOUNT_NAME,
AccountConstants.ACCOUNT_NAME)
.withValue(RawContacts.ACCOUNT_TYPE,
AccountConstants.ACCOUNT_TYPE)
// .withValue(RawContacts.SOURCE_ID, 12345)
// .withValue(RawContacts.AGGREGATION_MODE,
// RawContacts.AGGREGATION_MODE_DISABLED)
.build());
ops.add(ContentProviderOperation
.newInsert(
addCallerIsSyncAdapterParameter(Settings.CONTENT_URI,
true))
.withValue(RawContacts.ACCOUNT_NAME,
AccountConstants.ACCOUNT_NAME)
.withValue(RawContacts.ACCOUNT_TYPE,
AccountConstants.ACCOUNT_TYPE)
.withValue(Settings.UNGROUPED_VISIBLE, 1).build());
ops.add(ContentProviderOperation
.newInsert(
addCallerIsSyncAdapterParameter(Data.CONTENT_URI, true))
.withValueBackReference(Data.RAW_CONTACT_ID, 0)
.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
.withValue(StructuredName.GIVEN_NAME, contact.getFullname())
.withValue(StructuredName.FAMILY_NAME, contact.getFullname())
.build());
ops.add(ContentProviderOperation
.newInsert(
addCallerIsSyncAdapterParameter(Data.CONTENT_URI, true))
.withValueBackReference(Data.RAW_CONTACT_ID, 0)
.withValue(
ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER,
contact.getPhoneNumber()).build());
ops.add(ContentProviderOperation
.newInsert(
addCallerIsSyncAdapterParameter(Data.CONTENT_URI, true))
.withValueBackReference(Data.RAW_CONTACT_ID, 0)
.withValue(
ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Email.DATA,
contact.getEmail()).build());
ops.add(ContentProviderOperation
.newInsert(
addCallerIsSyncAdapterParameter(Data.CONTENT_URI, true))
.withValueBackReference(Data.RAW_CONTACT_ID, 0)
.withValue(Data.MIMETYPE, MIMETYPE)
.withValue(Data.DATA1, contact.getFullname())
.withValue(Data.DATA2, contact.getEmail())
.withValue(Data.DATA3, contact.getHomeAddress()).build());
try {
ContentProviderResult[] results = resolver.applyBatch(
ContactsContract.AUTHORITY, ops);
if (results.length == 0)
AppLog.d(TAG, "Failed to add.");
} catch (Exception e) {
AppLog.e(TAG, e.getMessage(), e);
}
}
Problem - Currently the code is adding new contact but not merging it into existing contact based on Phone number. Is there anything I have to do before adding the contact? I would like to display my app account inside Contact same as Whats App.
I have implemented SyncService, SyncAdapter, Authenticator, contacts.xml and other classes required for the project. The only thing not working is showing contact inside the default Contact app instead of creating new contact.
<ContactsSource xmlns:android="http://schemas.android.com/apk/res/android" >
<ContactsDataKind
android:detailColumn="data2"
android:detailSocialSummary="true"
android:icon="#drawable/ic_launcher"
android:mimeType="vnd.android.cursor.item/com.test.app"
android:summaryColumn="data3" />
</ContactsSource>
I had the same problem on Android 6.1 and as I heard, this issue is present since Lollipop. Every implementation on the web shows that the contact matching should work based on phone number. And it works on earlier systems - I tried it on KitKat and it works like a charm. But since Android 5.0 contacts don't match somehow.
Fortunately phone number is not the only parameter the matching depends on - there is also displayname. So the working implementation should look like this:
// as displayName pass the retrieved ContactsContract.Contacts.DISPLAY_NAME
#Override
public void addContact(#Nonnull final String displayName, #Nonnull final String phone) {
final ContentResolver resolver = context.getContentResolver();
final ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation
.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.RawContacts.CONTENT_URI, true))
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, ACCOUNT_NAME)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE,
ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT)
.build());
ops.add(ContentProviderOperation
.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
.build());
ops.add(ContentProviderOperation
.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
.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());
ops.add(ContentProviderOperation
.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI, true))
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
.withValue(ContactsContract.Data.MIMETYPE, YOUR_MIMETYPE)
.withValue(ContactsContract.Data.DATA1, 12345)
.withValue(ContactsContract.Data.DATA2, "user")
.withValue(ContactsContract.Data.DATA3, "action")
.build());
try {
resolver.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (Exception e) {
e.printStackTrace();
}
}
I left the phoneNumber in case the contact doesn't have any displayname - then it would at least match on earlier Android versions.
I am developing a backup application for Android, mainly contacts and SMS messages. Backing up isn't a problem, but writing the contacts back to the Android database is proving problematic.
This is what I have so far:
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());
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID, 1)
.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
.withValue(StructuredName.GIVEN_NAME, "Joe")
.withValue(StructuredName.FAMILY_NAME, "Bloggs")
.build());
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID,1)
.withValue(ContactsContract.Data.MIMETYPE,ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, "086555555")
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE,ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
.build());
try{
ctx.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
}catch(Exception e){
e.printStackTrace();
}
It all seems to hinge on the RAW_CONTACT_ID. I'm using the emulator, with no contacts at the start. It works for the first contact creation(RAW_CONTACT_ID = 0), but no contacts seem to be created after that initial one, where RAW_CONTACT_ID is 1 upwards. Anybody got any ideas as to how this is the case?
What I did was I created my contact first and then grabbed the ID of that newly created contact and added all the other contact details to that ID
Here is my frist step, create the new contact, then find the ID of that contact
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());
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.PREFIX, prefix)
.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, givenName)
.withValue(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME, middleName)
.withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, familyName)
.withValue(ContactsContract.CommonDataKinds.StructuredName.SUFFIX, suffix)
.build());
resolver.applyBatch(ContactsContract.AUTHORITY, ops);
Cursor cursor = null;
try
{
cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI, baseProjection, ContactsContract.Contacts.DISPLAY_NAME + " = ? ", new String[] {displayname}, __DEFAULT_SORT_ORDER);
if (cursor.moveToFirst())
{
String val;
val = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
return val;
}
}
...
Then I add any detail to the contact I want like this:
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValue(ContactsContract.Data.CONTACT_ID, contactId)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.Data.DATA5, poBox)
.withValue(ContactsContract.Data.DATA4, street)
.withValue(ContactsContract.Data.DATA7, city)
.withValue(ContactsContract.Data.DATA8, region)
.withValue(ContactsContract.Data.DATA9, postCode)
.withValue(ContactsContract.Data.DATA10, country)
.withValue(ContactsContract.Data.DATA2, type)
.withValue(ContactsContract.Data.DATA3, label)
.build());