I use the following code to retrieve all phone number from contacts.
Cursor c = context.getContentResolver().query(
Data.CONTENT_URI,
new String[] { Phone.NUMBER },
Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE
+ "'", null, null);
It works perfectly in my Android phone.
But some users say my app doesn't get all phone numbers from contacts and just part of them. I can't figure out the reason.. why?
This will get the cursor holding base contact data, and will loop through the phone numbers the contact has, can have multiple.
Uri uri = data.getData();
Cursor cursor=ctx.getContentResolver().query(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 have the 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();
}
}
Related
I am reading contact names and phone numbers from the contacts list in Android. I am reading the names successfully. However, when I go to look up a contact phone number by name (which are all unique in this case, it's just a test), it works perfectly for only one contact, gets no phone number for others, and gets the wrong phone number for one.
Here is the code in my getNumbers method:
private String getNumber(String name){
String returnMe="";
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, null,
"DISPLAY_NAME = '" + getIntent().getStringExtra("name") + "'", null, null);
if(cursor.moveToFirst()){
String identifier = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Cursor phones = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, ContactsContract.CommonDataKinds.Phone._ID + " = " + identifier, null, null);
while(phones.moveToNext()){
returnMe = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
int type = phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
switch(type){
case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE:
System.out.println("mobile number found"); break;
default:
System.out.println("nothing found."); break;
}
}
}
return returnMe;
}
You're doing a few things wrong:
1) The second query must target the Data table, not the Phone table:
Cursor phones = contentResolver.query(ContactsContract.Data.CONTENT_URI, ...
and specify that you want the Phone number in the DATA1 column in the where clause:
Data.MIMETYPE = Phone.CONTENT_ITEM_TYPE
2) You need to filter the results by the RawContact's _ID
This compares the _ID of the Contact row with the _ID of the Phone row, which have very little chance to be the same:
ContactsContract.CommonDataKinds.Phone._ID + " = " + identifier
This compares the Data.CONTACT_ID with the cursor's Contact._ID property
Data.CONTACT_ID + " = " + identifier
The example on the Data javadoc page gives a more complete example:
Finding all Data of a given type for a given contact
Cursor c = getContentResolver().query(Data.CONTENT_URI,
new String[] {Data._ID, Phone.NUMBER, Phone.TYPE, Phone.LABEL},
Data.CONTACT_ID + "=?" + " AND "
+ Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'",
new String[] {String.valueOf(contactId)}, null);
See my answer:
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) {
//Query phone here
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()) {
// Get phone numbers here
}
pCur.close();
}
}
}
}
i have created one listview.now i want to show data(contact no.,name) from contactlist of android(Phonebook) on my listview.
i got it for android 1.5 but i want to do it for android2.1updated.
How to do it?can any one guide me or give some sample code?
Thanks in advance---
If you have achieved it in 1.5 then there can be a small difference of URI. You should go for updated/changed URI of Contacts in 2.1. For further understanding here is a sample code for 2.1updated:
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while (cur.moveToNext())
{
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
//---------------------------------------- Contact Names
//------------------------------------------------------
String DisplayName = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Cursor names = cr.query(ContactsContract.Data.CONTENT_URI, null,ContactsContract.Data.CONTACT_ID + " = " + id, null, null);
names.moveToNext();
String GivenName = names.getString(names.getColumnIndex(ContactsContract.Data.DATA2));
String FamilyName = names.getString(names.getColumnIndex(ContactsContract.Data.DATA3));
String MiddleName = names.getString(names.getColumnIndex(ContactsContract.Data.DATA5));
names.close();
//----------------------------------------- Phone Numbers
//-------------------------------------------------------
String hasPhoneNumber = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
if (hasPhoneNumber.equals("1"))
{
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ id,null, null);
while (phones.moveToNext())
{
......
}
}
} // AND SO ON.... Get which ever data you need.
so above is just a sample code that I used for my task. You can get what you need by making changes accordingly. I hope it helps.
This will help you getting contacts.
Cursor contactList = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,null, null,null, null);
For getting phone number of a particular contact,you need to use:
String id = contactList.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
Cursor phoneCursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER},
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
new String[]{id}, null);
I am trying to run the following code.
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()) {
String phoneNo = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Toast.makeText(NativeContentProvider.this, "Name: " + name + ", Phone No: " + phoneNo, Toast.LENGTH_SHORT).show();
}
pCur.close();
}
}
}
}
So basically I query Contacts.URI and then on the basis of returned data if HAS_PHONE_NUMBER >0 , I query Phone.URI.
When I run this on my phone, I see 3 contacts that get displayed, who don't have corresponding entry in PHONE content URI. These 3 contacts have phone number for sure, as I can see those phone numbers when I go to my phone dialer screen.
How this is possible for a contact to have HAS_PHONE_NUMBER > 0 and still not have corresponding row in PHONE Content URI. Is it not weired, and how to get rid of this.
Please let me know.
Thanks.
This small method gets the contacts based on an option string search parameter. It only fetches contacts that include phone numbers.
private Cursor getContactsCursor(String searchPattern){
String selection = ContactsContract.Contacts.DISPLAY_NAME + " LIKE ? and " + ContactsContract.Contacts.HAS_PHONE_NUMBER + " > 0 ";
String queryArguments = "%" + searchPattern + "%";
String[] selectionArgs = new String[] { queryArguments };
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
return getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, selection, selectionArgs, sortOrder);
}
I'm trying to retrieve both the display names and the phone numbers of all my contacts but I want it to return only the rows that have a number.
Currently I have it like this and it works:
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,null, null, ContactsContract.Contacts.DISPLAY_NAME+ " COLLATE NOCASE");
while (cur.moveToNext())
{
if ( Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
{
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
contacts[index] = name;
Cursor pCur = cr.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{id}, null);
pCur.moveToFirst();
numbers[index] = pCur.getString( pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
index++;
pCur.close();
}
The thing is that it takes something like 4-5 seconds to load as it is running the cr.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{id}, null); like 400 times.
Now my understanding is that the name and number of a contact are held in different tables and you need the id of the name in order to get the number.
Can this be done in any other way faster?
Thanks in advance
#mixkat
I have figured out one more solution.
It is possible to get Name and Phone data using just one query.
Here is the code:
String WHERE_CONDITION = ContactsContract.Data.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'";
String[] PROJECTION = {ContactsContract.Data.DISPLAY_NAME, ContactsContract.Data.DATA1};
String SORT_ORDER = ContactsContract.Data.DISPLAY_NAME;
Cursor cur = context.getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
PROJECTION,
WHERE_CONDITION,
null,
SORT_ORDER);
In this case you query not Contact provider but Data provider directly.
I have the same problem. I resolved it by saving contacts in db first time user open app. And than I update data (it is up to you when app should update contacts).
So application uses contacts from my db table where name and number are in one row. It takes much less time.
Alright so I'm just learning how to work with contacts and such. I would like to have my contacts listed out in a ListView, with custom adapter (I think thats what it is called, where I can have ImageViews, TextViews, all that such, in one ListView entry). How would I be able to do that with the following code that I have?
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 have the 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.close();
Check out ContactManager samplecode. It explains exactly how to do what you are looking for:
http://developer.android.com/resources/samples/ContactManager/index.html