-
-
Save srayhunter/47ab2816b01f0b00b79150150feb2eb2 to your computer and use it in GitHub Desktop.
private class FetchContacts extends AsyncTask<Void, Void, ArrayList<Contact>> { | |
private final String DISPLAY_NAME = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? | |
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY : ContactsContract.Contacts.DISPLAY_NAME; | |
private final String FILTER = DISPLAY_NAME + " NOT LIKE '%@%'"; | |
private final String ORDER = String.format("%1$s COLLATE NOCASE", DISPLAY_NAME); | |
@SuppressLint("InlinedApi") | |
private final String[] PROJECTION = { | |
ContactsContract.Contacts._ID, | |
DISPLAY_NAME, | |
ContactsContract.Contacts.HAS_PHONE_NUMBER | |
}; | |
@Override | |
protected ArrayList<Contact> doInBackground(Void... params) { | |
try { | |
ArrayList<Contact> contacts = new ArrayList<>(); | |
ContentResolver cr = getContentResolver(); | |
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, PROJECTION, FILTER, null, ORDER); | |
if (cursor != null && cursor.moveToFirst()) { | |
do { | |
// get the contact's information | |
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); | |
String name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME)); | |
Integer hasPhone = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)); | |
// get the user's email address | |
String email = null; | |
Cursor ce = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, | |
ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{id}, null); | |
if (ce != null && ce.moveToFirst()) { | |
email = ce.getString(ce.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)); | |
ce.close(); | |
} | |
// get the user's phone number | |
String phone = null; | |
if (hasPhone > 0) { | |
Cursor cp = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, | |
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null); | |
if (cp != null && cp.moveToFirst()) { | |
phone = cp.getString(cp.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); | |
cp.close(); | |
} | |
} | |
// if the user user has an email or phone then add it to contacts | |
if ((!TextUtils.isEmpty(email) && android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches() | |
&& !email.equalsIgnoreCase(name)) || (!TextUtils.isEmpty(phone))) { | |
Contact contact = new Contact(); | |
contact.name = name; | |
contact.email = email; | |
contact.phoneNumber = phone; | |
contacts.add(contact); | |
} | |
} while (cursor.moveToNext()); | |
// clean up cursor | |
cursor.close(); | |
} | |
return contacts; | |
} catch (Exception ex) { | |
return null; | |
} | |
} | |
@Override | |
protected void onPostExecute(ArrayList<Contact> contacts) { | |
if (contacts != null) { | |
// success | |
mContacts = contacts; | |
} else { | |
// show failure | |
// syncFailed(); | |
} | |
} | |
} |
@lokhandesh the queries are different URIs so that is why there are the different queries. So, I would try and do the first query and then do the 2 other queries each on separate threads and then merge them together. With rxjava you can look at merging and with kotlin coroutines you can look at flow combine. Then you can move this async task to a coroutine or rxjava observable.
This loops through each contact and then does the 2 queries. You could get all the contacts and then do the queries async and update your list as they are retrieved for each contact id.
@srayhunter looks like with above approach it will save around half time, that means 3.5 seconds in my scenario.
Okay will try with approach mentioned by you.
Can we fetch deleted contacts?
@nishi13tiwari I dont think deleted contacts will be fetched. I think once they are deleted, they are removed from the device.
Thanks @srayhunter for reply.
I agree with your point like access contact on different thread. Currently I am following same thing.
Yes I want all the contacts. In my mobile having 700-800 contact,that's why it is taking 7 seconds.
Is there Any other approach where using single query we can get phone number and email of all contact?