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
Related
Given a phone number, I first find out the LOOKUP_KEY of the Contact that has this number. From there, is there a way to retrieve the list of raw contacts with a single query?
I tried the following approach
ContentResolver cr = context.getContentResolver();
// Get all RawContacts associated with lookupKey
Cursor contactCursor = cr.query(
Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookup_key),
new String[]{ContactsContract.RawContacts._ID},
null,
null,
null);
But contactCursor always contains a single entry, even when the queried contract has multiple raw contacts.
To be honest, I do not understand very well why the query above even returns anything, since there is no RawContacts entry in the table ContactsContract.Contacts. I guess that it just returns the _ID entry of this table, which is the Contact_ID (not the Id of a RawContact).
Don't use LOOKUP_KEY in this scenario, instead get the Contacts._ID from the phone number, and then get all RawContacts by CONTACT_ID:
cr.query(RawContacts.CONTENT_URI,
new String[]{ RawContacts._ID },
RawContacts.CONTACT_ID + "=" + theContactId,
null,
null);
I'm trying to get "notes" from a single contact. It added fine but retrieving it has been a problem.
String selection = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+" like'%" + sender +"%'";
String[] projection = new String[] { ContactsContract.CommonDataKinds.Note.NOTE};
Cursor c2 = getContentResolver().query(ContactsContract.Data.CONTENT_URI, projection, selection, null, null);
if (c2.moveToFirst()) {
notes = c2.getString(0);
}
It works fine with other values like name or phone number but can't seem to get notes to retrieve correctly. It retrieves a random value like email instead.
I believe that your problem is that not all rows in the table represent contact types that have notes. You have to request the proper MIME Type.
ContactsContract.CommonDataKinds.Note is an alias for the 'data1' column that is present on all rows, so when you get a row of a different MIME Type, it represents different data.
How to get contacts in Android should give you an idea of how to do this.
I am working on the displaying the contacts group wise in android application. So I got all the group contacts from the particular group but now I want to get the contacts those are not in any of the group (NOT ASSIGNED).
So what can be the value of GROUP_ROW_ID in the contacts's in case of no group ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID ?
If there any solution you know please let me know.
Any suggestion will be appreciated.
Please use,
ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID = null;
This will get non-group contacts.
you can retrieve all contacts as a cursor.
Cursor cursor = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,null, null);
now we have cusror with contacts and get diffrent value from cusror.
while (cursor.moveToNext()) {
String name =cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
see this one http://samir-mangroliya.blogspot.in/p/android-read-contact-and-display-in.html
my question seems silly but it makes me headache by below code. Below code print contactId and telephone number to Screen.
It works well, but something I need to know more clearer:
ContentResolver solver = getContentResolver();
String mess="";
Cursor cursor = solver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while (cursor.moveToNext()){
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
mess = mess + "ID: "+contactId+"\n";
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));
mess = mess + phoneNumber + "\n";
}
}
The thing I don't know is this line of above code:
Cursor phones = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId, null, null);
As in Android Development about third parameter:
selection : A filter declaring which rows to return, formatted as an
SQL WHERE clause (excluding the WHERE itself). Passing null will
return all rows for the given URI.
So, as this defination, CONTACT_ID acts as "A ROW". (because it filter which row to return),
but as this line, CONTACT_ID acts as "A COLUMN":
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Please explain for me this point.
thanks :)
It's a column (declared like this INTEGER PRIMARY KEY AUTOINCREMENT). In:
Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId,
null, null);
you query the ContentProvider but use the _ID column to filter the results. You are saying: "I want the rows from the ContentProvider where in the column _ID I find only the value contactId". In:
String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
_ID is used to get the column index integer(to get the values from that column) so you don't have to use simple numbers like 0, 1, 2 and possible avoid mistakes.
Edit:
The second parameter(also referred as projection) represents the columns of data that you want to retrieve from the provider(null = get all columns). You could look at the second parameter as a filter, you only get those column that you specified in the array(for example maybe you don't want several columns because you will not use them, so for the second parameter you set a string array with the columns that you do want and omit the ones that you don't need). The third parameter filter the rows, the second parameter filter the columns you retrieved()
You should take a look of sql queries, if we want to select column column1 from table A, with filtering if its value is 5, then we would write this query as:
SELECT column1 From A WHERE column1=5
It means Selecting values from table with column1 value equal to 5. So nothing is unusual here.
CONTACT_ID is a column.
when you use "CONTACT_ID = 10" filter expression for example
you will get all the rows that have the value 10 in their CONTACT_ID cell.
see the following link about where clause in SQL :
http://www.w3schools.com/sql/sql_where.asp
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.