I want to get all phone contacts from device in android.i have used the following code.but the problem is it takes more time to return the results.is there any solution?
ContentResolver cr = getContentResolver();
int index=0;
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
if (cur.getCount() > 0)
{
phoneNames=new String[cur.getCount()];
phoneNumbers=new String[cur.getCount()];
while (cur.moveToNext())
{
String id = cur.getString(
cur.getColumnIndex(ContactsContract.Contacts._ID));
name = cur.getString(
cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
phoneNames[index]=name;
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
new String[]{id}, null);
while (pCur.moveToNext())
{
phoneIndex++;
phoneNumbers[index] = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
index++;
}
pCur.close();
}
}
After reading the code i assume that what you want is a list of contacts with DISPLAY NAMES and their respective phone numbers.
If you are specifically looking for data related to phone numbers i suggest you query on
android.provider.ContactsContract.PhoneLookup and fetch the results using a single cursor.
The following are the fields that you would be interested in:
DISPLAY_NAME
HAS_PHONE_NUMBER
NUMBER
TYPE
e.g
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
resolver.query(uri, new String[]{PhoneLookup.DISPLAY_NAME,...
Further details please refer this
Please post your requirement if the assumptions are not true.
Some of quick checks:
Select only the required columns and not all in the first query.
Instead of using Integer.parseInt(cur.getString) use
cur.getInt()
Use PhoneLookup whenever dealing with phone numbers ( the number
field gives the raw phone number
instead of the value stored in
the database which can contain
-,),( appended with it)
Avoid using Cursor within a cursor. Use the API's which includes
joins already implemented in it like
RawContactsEntity, PhoneLookup.
Hope that helps.
Don't do complex database queries on the UI thread. What are you trying to do with the results? If you are displaying things in a list, use a CursorAdapter so that you only pull out what you need when you need it.
Related
I'm trying to use the implementation of the code found in this question post: How to read contacts on Android 2.0 but I can't figure out how to get it also run through the given, family, or display name columns. How can I get this implementation (the large one in the linked question) to give me the given and display names of the contacts as it loops through each row? I want to use this implementation specifically because it loops through the specified columns in each row and returns the information in the order it is in the row.
Here is the implementation from the other question that I'm referring to:\
Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);
while (cursor.moveToNext()) {
String contactId = cursor.getString(cursor.getColumnIndex(
ContactsContract.Contacts._ID));
String hasPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
if (Boolean.parseBoolean(hasPhone)) {
// You know it has a number so now query it like this
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId, null, null);
while (phones.moveToNext()) {
String phoneNumber = phones.getString(phones.getColumnIndex( ContactsContract.CommonDataKinds.Phone.NUMBER));
}
phones.close();
}
Cursor emails = getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + contactId, null, null);
while (emails.moveToNext()) {
// This would allow you get several email addresses
String emailAddress = emails.getString(
emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
}
emails.close();
}
cursor.close();
First of all, the answer in the linked post is a bit obsolete, because there now is documentation for Contacts Provider at developer.android.com.
Second, the problem you're having is that you're querying the "data" table with a contact ID for the contacts table, and that won't work.
The Contacts Provider is a three-tiered arrangement of tables. The top level is the Contacts table, whose constants are defined in ContactsContract.Contacts. One of its columns is
ContactsContract.Contacts._ID, which identifies a contact row. HOWEVER, a row in this table is an aggregation of individual contacts from various sources.
The individual contacts are stored in ContactsContract.RawContacts. For each ContactsContract.Contacts._ID, there can be more than one row in ContactsContract.RawContacts.
For each row in ContactsContract.RawContacts, there are one or more rows in ContactsContract.Data. Each row has a MIME type that tells you what type of data it is. For example, a row in ContactsContract.RawContacts can have three rows in ContactsContract.Data that have the MIME type for phone numbers. Each of the three "data" rows is a different type of phone number (home, mobile, work) for the contact in ContactsContract.RawContacts.
You can see why looking for ContactsContract.Contacts._ID in ContactsContract.Data won't work; that's the wrong ID to look for.
Rather than re-write the documentation here, I suggest you take a look at it. It has some nice illustrations that help explain what I'm getting at:
Contacts Provider
I want to get some basic info of all contacts(I use api lvl 8). Currently i use this code snippet
private List<ContactInfo> readContacts() {
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, Phone.DISPLAY_NAME + " ASC");
for (int i = 0; i < cur.getColumnCount(); i++) {
Log.v("COlum", cur.getColumnName(i));
}
List<ContactInfo> temp = new ArrayList<ContactInfo>();
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
ContactInfo mContactInfo = new ContactInfo();
String id = cur.getString(cur
.getColumnIndex(ContactsContract.Contacts._ID));
mContactInfo.setId(Long.parseLong(id));
String name = cur
.getString(cur
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer
.parseInt(cur.getString(cur
.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
mContactInfo.setmDisplayName(name);
// get the <span class="IL_AD" id="IL_AD7">phone
// number</span>
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = ?", new String[] { id }, null);
while (pCur.moveToNext()) {
String phone = pCur
.getString(pCur
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
mContactInfo.setmPhoneNumber(phone);
}
pCur.close();
// get email and type
Cursor emailCur = cr.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID
+ " = ?", new String[] { id }, null);
while (emailCur.moveToNext()) {
// This would allow you get several email <span
// class="IL_AD" id="IL_AD9">addresses</span>
// if the email addresses were stored in an array
String email = emailCur
.getString(emailCur
.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
mContactInfo.setmEmail(email);
}
emailCur.close();
temp.add(mContactInfo);
}
}
}
return temp;
}
and pass to custom adapter (extended baseadapter). I get contact's photo using:
public static Bitmap loadContactPhoto(ContentResolver cr, long id) {
Uri uri = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI, id);
InputStream input = openContactPhotoInputStream1(cr, uri);
if (input == null) {
return null;
}
return BitmapFactory.decodeStream(input);
}
I tested on my phone with 2x contacts (had photo). I took ~ 10s to fetch all contact at 1st runtime. I try force close in application settings and run again. This time it took ~2s to get data.So i want to know the most effective way to get contacts info.
I found some similar SO questions but they dont need photo. contacts in android
I tried use cursor and cursor adapter but i dont know what query to get photo_uri + contact name at the same time.
Edit: i removed all getColumnIndex i can out of loop and project only column i want. The performance is better(10s => 5s).
What i want to know :
Better way to query info and set to my ContactInfo model or the query which get name, phone number, email, photo at the same time to pass to cursor adapter.
Thanks in advance
I changed to CusorAdapter and use ContactsPhotoLoader from Contacts app and performance is improved.
To get contact info you have to work with the Android Contact API. Also you have to keep in min that you have to handle this Api in a different way for android api below API 4 (1.6)and for the Android API 5 (2.0) and higher:
I will provide you some good links that will help you:
Working With Android Contacts
Handling Contact Photos (All API Levels)
Using the Contact Picker API 2.0 and above
Retrieving Contact Information (Name, Number, and Profile Picture)
API4 and lower
Thes also some SO thread similar to yours that must b helpful for you
get contact info from android contact picker
Getting a Photo from a Contact
I want to store contact information in an arraylist hash map so that i writ that information in .csv file.
I am able to get contact information but how to make consistency means if i store information "name" in an array and contactno also in array than if any name not contains any contactno then inconsistency would occurs so please tell me how to overcome this.
My code is:
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
//Query phone here. Covered next
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
new String[]{id}, null);
while (pCur.moveToNext()) {
// Do something with phones
String phoneno = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
//Log.i("phonenos",phoneno);
}
pCur.close();
}
}
}
}
I don't quite get the question, could you explain it a little better, than I might be able to help.
You want 2 Hashmaps, 1 with contact his name, one with their number, and then you have problems when a contact hasn't got a number or..?
edit:
If you're looking for exporting into an csv, you should see this related topic
Android - Generate CSV file from table values
Hope this helps.
I know how to retrieve contact data for specific contacts. However, i can't find a way to get all contacts plus some of their details in a single query. The following code gets all contacts having a postal address:
Uri uri = ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI;
String[] projection = new String[] {
StructuredPostal._ID,
StructuredPostal.LOOKUP_KEY,
StructuredPostal.DISPLAY_NAME,
StructuredPostal.STREET,
StructuredPostal.CITY
};
String sortOrder = StructuredPostal.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
Cursor c = getContentResolver().query(uri, projection, null, null, sortOrder);
But what i need are all contacts, whether they have postal address or not. Is this doable using the ContatsContract API, or do i need to create custom outer join query? Any hints on how?
if You have a contact ID and you want to fetch the Postal Address then use this :
Uri postal_uri = ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI;
Cursor postal_cursor = getContentResolver().query(postal_uri,null, ContactsContract.Data.CONTACT_ID + "="+contactId.toString(), null,null);
while(postal_cursor.moveToNext())
{
String Strt = postal_cursor.getString(postal_cursor.getColumnIndex(StructuredPostal.STREET));
String Cty = postal_cursor.getString(postal_cursor.getColumnIndex(StructuredPostal.CITY));
String cntry = postal_cursor.getString(postal_cursor.getColumnIndex(StructuredPostal.COUNTRY));
}
postal_cursor.close();
All contact information in Android 2.0 is stored in a single database table. So you can get all the information you need in a single query:
Cursor c = getContentResolver().query(ContactsContract.Data.CONTENT_URI,
null, null, null, sortOrder);
The just iterate through the data and check Data.MIMETYPE column. For example, if this column has StructuredPostal.CONTENT_ITEM_TYPE value, then you can get StructuredPostal fields from this column.
Well, I've been looking around and can't find a specific way to actually DISPLAY the contacts list. I've found tutorials such as higher pass's but it never actually discusses how to display them, just how to get them. I simply want to display the contacts list in a listView or something similar. I know it has to be a lot more simple than I'm making it out to be, because it seems to be a common thing. Specifically, all I want is the contact's name and phone numbers. I have my query set up, which I got the above mentioned tutorial, and I think it's right:
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String id = cur.getString(
cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(
cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
Cursor pCur = cr.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
new String[]{id}, null);
while (pCur.moveToNext()) {
}
pCur.close();
}
}
}
There is a built-in activity for this:
startActivity(new Intent(Intent.ACTION_VIEW, ContactsContract.Contacts.CONTENT_URI));
If you use startActivityForResult(), you can even get the user's chosen contact back.
If that's not what you're looking for, you want to cut back to a single query if possible, then create an Adapter for your ListView. Here is a sample project that shows querying the contacts to populate a ListView, showing either the contact's name, name and phone number, or name and email address. This gets a bit more complicated because the sample shows both the Android 1.6-and-lower and Android 2.0-and-higher contacts APIs.