I saving a around 250 contacts in phonebook. And each contact is taking around 1 second to save in contact list. In my app, I might have to save more than 10,000 contacts. Then it will take hours to save them. So, I want a method to quickly save all the contacts. Your answer would really help me a lot :)
Here is the method I am using with a for loop to save a contact -
public static String saveNewContact(String name, String number, ContentResolver contentResolver){
ContentValues values = new ContentValues();
values.put(Contacts.People.NUMBER, number);
values.put(Contacts.People.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM);
values.put(Contacts.People.LABEL, name);
values.put(Contacts.People.NAME, name);
Uri dataUri = contentResolver.insert(Contacts.People.CONTENT_URI, values);
Uri updateUri = Uri.withAppendedPath(dataUri, Contacts.People.Phones.CONTENT_DIRECTORY);
values.clear();
values.put(Contacts.People.Phones.TYPE, Contacts.People.TYPE_MOBILE);
values.put(Contacts.People.NUMBER, number);
updateUri = contentResolver.insert(updateUri, values);
return getContactID(updateUri, contentResolver);
}
public static String getContactID(Uri contactUri, ContentResolver contentResolver){
String id = "";
Cursor cursor = contentResolver.query(contactUri, null,
null, null, null);
if (cursor != null && cursor.moveToFirst()) {
int idx = cursor.getColumnIndex(ContactsContract.Contacts._ID);
id = cursor.getString(idx);
}
return id;
}
EDIT - Tried this code as well, but the results are same
ArrayList<ContentProviderOperation> cntProOper = new ArrayList<>();
int contactIndex = cntProOper.size();
cntProOper.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null).build());
cntProOper.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.RawContacts.Data.RAW_CONTACT_ID, contactIndex)
.withValue(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name)
.build());
cntProOper.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, contactIndex)
.withValue(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, number)
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE).build()); //Type like HOME, MOBILE etc
try {
contentResolver.applyBatch(ContactsContract.AUTHORITY, cntProOper);
} catch (RemoteException | OperationApplicationException exp) {}
Ok, many things to mention here...
For your first code, NEVER EVER USE
Contacts.People.XXAPIs, seriously, for anything anywhere, make sure you do not import anything fromPeopleor use any of its APIs, this is a very very old API that had been deprecated many years ago and is even not supported for some devices.Regarding your second code, lots of bugs and issues there which I tried to fix in my code below, but specifically for your performance requirement, note that you don't have to
applyBatchfor each and every contact, if you're creating many contacts at once, it's ok to put many operations within youropsArrayListand apply them all in one go - much faster!Notes:
ACCOUNT_TYPE/ACCOUNT_NAMEvalues with something related to your app, I've added to this code two const valuesMY_ACCOUNT_TYPE/MY_ACCOUNT_NAMEthat you'll need to define.