Retrieve contacts faster from address book in android
I want to get all contact details like Phone Number, Display Name, Show Image and Email ID. I am using the method below and it works fine.
public void readContacts() {
Log.d("readcontacts", "::" + "true");
String phoneNumber = null;
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
// contactEntity = new ContactEntity();
final ContentValues values = new ContentValues();
String Contact_Id = cur.getString(cur
.getColumnIndex(ContactsContract.Contacts._ID));
values.put(KEY_ID, Integer.parseInt(Contact_Id));
int hasPhoneNumber = Integer
.parseInt(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));
/*
* contactEntity .setContactFirstName(cur.getString(cur
* .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
*/
if (Integer
.parseInt(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
// System.out.println("name : " + name + ", ID : " + id);
// sb.append("\n Contact Name:" + name);
Cursor pCur = cr
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = ?",
new String[] { Contact_Id }, null);
if (pCur.moveToFirst()) {
phoneNumber = pCur
.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
// sb.append("\n Phone number:" + phone);
// System.out.println("phone" + phone);
}
pCur.close();
Cursor emailCur = cr
.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID
+ " = ?",
new String[] { Contact_Id }, null);
if (emailCur.moveToFirst()) {
values.put(
KEY_CONTACTEMAIL,
(emailCur.getString(emailCur
.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA))));
// emailType = emailCur .getString(emailCur
// .getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
}
emailCur.close();
if (phoneNumber.length() >= 10) {
final Uri my_contact_Uri = Uri.withAppendedPath(
ContactsContract.Contacts.CONTENT_URI,
String.valueOf(Contact_Id));
InputStream photo_stream = ContactsContract.Contacts
.openContactPhotoInputStream(
getContentResolver(),
my_contact_Uri);
if (photo_stream != null) {
BufferedInputStream buf = new BufferedInputStream(
photo_stream);
Bitmap my_btmp = BitmapFactory
.decodeStream(buf);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
my_btmp.compress(Bitmap.CompressFormat.PNG,
100, bos);
byte[] bArray = bos.toByteArray();
values.put(KEY_CONTACTIMAGE, bArray);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// contactEntity.setBitmapContactImage(my_btmp);
values.put(
KEY_CONTACTNAME,
String.valueOf(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))));
values.put(KEY_CONTACTNUMBER,
String.valueOf(phoneNumber));
databaseHelperAssets.open();
databaseHelperAssets.addcontact(values);
databaseHelperAssets.close();
}
}
// values.put(KEY_TIMESWAP,
// String.valueOf(taskEnitiy.getTimeswap()));
// int SDK_INT = android.os.Build.VERSION.SDK_INT;
/*
* if (SDK_INT >= 11) { contactEntity
* .setImgUri(cur.getString(cur
* .getColumnIndex(ContactsContract.
* CommonDataKinds.Phone.PHOTO_URI))); }
*/
// alContactEntities.add(contactEntity);
}
}
}
But the problem is that it takes about 45 seconds to 1 minute to get 400 contact details. I can't keep my users waiting that long every time I need to get a contact. So can anyone help me to shorten the search time for a contact? and Yes, I use to store my contact in a database because I read my contacts for the first time only when I start the application. So I will find a better way to get it to avoid storing contacts in the database. Thanks in advance!
source to share
Thanks everyone for your help and hint, but finally I got my answer. I used the below code to get the rendered image:
InputStream photo_stream = ContactsContract.Contacts
.openContactPhotoInputStream(
getContentResolver(),
my_contact_Uri);
if (photo_stream != null) {
BufferedInputStream buf = new BufferedInputStream(
photo_stream);
Bitmap my_btmp = BitmapFactory
.decodeStream(buf);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
my_btmp.compress(Bitmap.CompressFormat.PNG,
100, bos);
byte[] bArray = bos.toByteArray();
values.put(KEY_CONTACTIMAGE, bArray);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
but i changed it to:
try {
String phototjumb = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI));
if(phototjumb != null && !phototjumb.toString().equalsIgnoreCase("")){
contactEntity.setImageURI(phototjumb);
Log.d("photojumb", "::" + phototjumb);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
and what I am using to show that photojumb on my image is like:
imgContactImg.setImageURI(Uri.parse(contactEntity.getImageURI()));
and what he is. Now it hardly takes me 2 seconds to show contacts on the fly directly in the custom list.
Don't worry, I am posting my complete method for getting contact. Here it is::
@SuppressLint("InlinedApi")
public void readContacts() {
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
contactEntity = new ContactEntity();
String Contact_Id = cur.getString(cur
.getColumnIndex(ContactsContract.Contacts._ID));
contactEntity
.setContactFirstName(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
try {
String phototjumb = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI));
if(phototjumb != null && !phototjumb.toString().equalsIgnoreCase("")){
contactEntity.setImageURI(phototjumb);
Log.d("photojumb", "::" + phototjumb);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
alContactEntities.add(contactEntity);
}
}
}
You have happy coding. :)
Please see below updated code to get contact number, display name, display image, email id, etc.
public ArrayList<ContactEntity> readContacts1() {
//Log.d("readcontacts", "::" + "true");
alContactEntities = new ArrayList<ContactEntity>();
String phoneNumber = null;
String tempPhoneNumber = null;
contactCount = 0;
ContentResolver cr = activity.getContentResolver();
Cursor cur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
contactEntity = new ContactEntity();
String Contact_Id = cur.getString(cur
.getColumnIndex(ContactsContract.Contacts._ID));
if (Integer
.parseInt(cur.getString(cur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER))) > 0) {
/*
* // System.out.println("name : " + name + ", ID : " + id);
* // sb.append("\n Contact Name:" + name);
*/
/*
* Cursor pCur = cr
* .query(ContactsContract.CommonDataKinds.Phone
* .CONTENT_URI, null,
* ContactsContract.CommonDataKinds.Phone.CONTACT_ID +
* " = ?", new String[] { Contact_Id }, null); if
* (pCur.moveToFirst()) {
*/
phoneNumber = cur
.getString(cur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
/*
* String regexStr = "^[0-9\\-\\+]*$"; phoneNumber =
* phoneNumber.replaceAll("\\D","");
*/
//Log.d("PohneNumber", "" + phoneNumber);
/*
* } pCur.close();
*/
// remove comment from below code to obtain email id
/*Cursor emailCur = cr
.query(ContactsContract.CommonDataKinds
.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID +
" = ?", new String[]{Contact_Id}, null);
if
(emailCur.moveToFirst()) {
contactEntity.setContactEmailId
((emailCur.getString(emailCur
.getColumnIndex(ContactsContract
.CommonDataKinds.Email.DATA))));
}
emailCur.close();*/
Uri uriBirthdate = ContactsContract.Data.CONTENT_URI;
String[] projectionBirthdate = new String[]{
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Event.CONTACT_ID,
ContactsContract.CommonDataKinds.Event.START_DATE
};
String whereBirthdateCaluse =
ContactsContract.CommonDataKinds.Event.CONTACT_ID + "= ? AND " +
ContactsContract.Data.MIMETYPE + "= ? AND " +
ContactsContract.CommonDataKinds.Event.TYPE + "=" +
ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY;
String[] selectionArgsBirthdate = new String[]{Contact_Id,
ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE
};
String sortOrder = null;
Cursor birthDayCur = cr.query(uriBirthdate, projectionBirthdate, whereBirthdateCaluse,
selectionArgsBirthdate, sortOrder);
if
(birthDayCur.moveToFirst()) {
int bDayColumn = birthDayCur.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE);
String bDay = birthDayCur.getString(bDayColumn);
Log.d("Birthday", " : " + bDay);
}
birthDayCur.close();
if (phoneNumber.length() >= 9
&& UDF.isValidPhoneNumber(phoneNumber)) {
/*
* Uri my_contact_Uri = Uri.withAppendedPath(
* ContactsContract.Contacts.CONTENT_URI,
* String.valueOf(Contact_Id));
*
* try { final InputStream photo_stream =
* ContactsContract.Contacts
* .openContactPhotoInputStream( activity.getContentResolver(),
* my_contact_Uri); if (photo_stream != null) { new
* Thread(new Runnable() {
*
* @Override public void run() { BufferedInputStream buf
* = new BufferedInputStream( photo_stream); Bitmap
* my_btmp = BitmapFactory .decodeStream(buf);
* ByteArrayOutputStream bos = new
* ByteArrayOutputStream();
* my_btmp.compress(Bitmap.CompressFormat.PNG, 100,
* bos); byte[] bArray = bos.toByteArray();
* values.put(KEY_CONTACTIMAGE, bArray);
*
* } }).start();
*
*
* } } catch (Exception e) { // TODO Auto-generated
* catch block e.printStackTrace(); } //
* contactEntity.setBitmapContactImage(my_btmp);
*/
try {
String phototjumb = null;
int SDK_INT = android.os.Build.VERSION.SDK_INT;
if (SDK_INT >= 11) {
phototjumb = cur
.getString(cur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI));
} else {
phototjumb = cur
.getString(cur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI));
}
if (phototjumb != null
&& !phototjumb.toString().equalsIgnoreCase(
"")) {
contactEntity.setImageURI(phototjumb);
//Log.d("photojumb", "::" + phototjumb);
}
/*if(eventEntity.getContactIndex() != -1 && contactCount == eventEntity.getContactIndex()){
if(eventEntity.getBlobImage() != null){
byte[] bb = eventEntity.getBlobImage();
String selectedImagePath = getRealPathFromURI(getImageUri(
activity,
BitmapFactory.decodeByteArray(bb, 0, bb.length)));
Bitmap vt = BitmapFactory.decodeFile(selectedImagePath);
Bitmap bitmap = Bitmap
.createScaledBitmap(vt, 50, 50, false);
//imgContactImg.setImageBitmap(UDF.getCroppedBitmap(bitmap));
contactEntity.setImageURI(
getImageUri(activity, vt).toString());
}
}*/
/*
* InputStream photo_stream =
* ContactsContract.Contacts
* .openContactPhotoInputStream
* (activity.getContentResolver(), my_contact_Uri);
* if(photo_stream != null){ // Use this method to
* set image using input stream
*
* contactEntity.setInputStreamImage(photo_stream);
*
* //Use this method to set image using bitmap (But
* it is time consuming)
*
* BufferedInputStream buf = new
* BufferedInputStream(photo_stream); Bitmap my_btmp
* = BitmapFactory.decodeStream(buf);
* contactEntity.setBitmapContactImage(my_btmp); }
*/
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (cur.getString(cur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)) == null
|| cur.getString(
cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
.trim().equalsIgnoreCase("")) {
contactEntity.setContactFirstName(String
.valueOf(phoneNumber));
} else {
contactEntity
.setContactFirstName(String.valueOf(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))));
}
contactEntity.setContactNumber(String
.valueOf(phoneNumber));
contactEntity.setUniquePosition(contactCount);
contactCount++;
alContactEntities.add(contactEntity);
}
}
// values.put(KEY_TIMESWAP,
// String.valueOf(taskEnitiy.getTimeswap()));
// int SDK_INT = android.os.Build.VERSION.SDK_INT;
/*
* if (SDK_INT >= 11) { contactEntity
* .setImgUri(cur.getString(cur
* .getColumnIndex(ContactsContract.
* CommonDataKinds.Phone.PHOTO_URI))); }
*/
// alContactEntities.add(contactEntity);
}
}
cur.close();
return alContactEntities;
}
And for UDF.isValidPhoneNumber (phone number)
/**
* Check if phone number is valid or not
*/
public static final boolean isValidPhoneNumber(CharSequence target) {
if (target == null || TextUtils.isEmpty(target)) {
return false;
} else {
return android.util.Patterns.PHONE.matcher(target).matches();
}
}
source to share