I'm tring to get all the contact data at one. I need : * First name * Last name * Phone numberS * Version etc.
for that i'm doing a query on the whole contacts and then, for each contact id, i get the relevant data.
the problem is that it takes a lot of time, more than 10 sec for ~400 contacts. (Running on Samsung i9300 with 4.4.2)
I DONT need to show anything to the user, i'm just syncing the contacts to with my server in the background, so i dont have any UI issues... just iterate over the contacts, see how needs an update and add him to my ArrayList, then POST it to the server.
public static void getAllContactsFromDevice() {
long startTime = System.currentTimeMillis();
Log.d(TAG, "startTime: " + startTime);
// Get all contacts by cursor
ContentResolver cr = getContext().getContentResolver();
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, null);
if (cursor.moveToFirst() && cursor.getCount() > 0) {
while (cursor.isAfterLast() == false) {
// get contact id on the device DB.
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String contactNumber = null;
// Get all phone numbers.
Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null);
// if the user has numbers
// get just the first one for now
if (phones.moveToNext())
contactNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
// close the cursor to prevent leak
phones.close();
// if we dont have a phone number, continue to next contact.
if (contactNumber == null) {
cursor.moveToNext();
continue;
}
// get first and last name by contact id
String[] projection = new String[]{ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME};
String where = ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?";
String[] whereParameters = new String[]{contactId, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE};
Cursor nameCur = cr.query(ContactsContract.Data.CONTENT_URI, projection, where, whereParameters, null);
String given = null;
String family = null;
try {
if (nameCur.getCount() > 0) {
nameCur.moveToFirst();
given = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME));
family = nameCur.getString(nameCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME));
nameCur.close();
}
// if there is no name, continue to next contact.
else {
nameCur.close();
cursor.moveToNext();
continue;
}
} catch (Exception e) {
e.printStackTrace();
nameCur.close();
}
if (given == null || given == "null")
given = "";
if (family == null || family == "null")
family = "";
String[] mProjection = new String[]{ContactsContract.RawContacts.VERSION};
String[] mWhereParameters = new String[]{contactId};
String mWhere = ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID + " = ? ";
Cursor mCursor = cr.query(ContactsContract.RawContacts.CONTENT_URI, mProjection, mWhere, mWhereParameters, null);
int contactVersion = 0;
try {
if (mCursor.getCount() > 0) {
mCursor.moveToFirst();
contactVersion = mCursor.getInt(mCursor.getColumnIndex(ContactsContract.RawContacts.VERSION));
mCursor.close();
} else {
mCursor.close();
}
} catch (Exception e) {
e.printStackTrace();
mCursor.close();
}
cursor.moveToNext();
}
}
cursor.close();
long endTime = System.currentTimeMillis();
Log.d(TAG, "endTime: " + endTime);
Log.d(TAG, "total time: " + (endTime - startTime));
}
total time: 18280 ms
i looked HERE developer.android.com but didnt find anything useful.
also this answer did not helped much.