I need to retrieve all data for a single contact which was chosen by a user (Action.Pick). I want to use LOOKUP KEY as suggested by developer.android.com. Can I do it by a simple query without creating Loader etc. as suggested by the documentation ?
I wrote this method for my application:
public static Cursor getContactCursorByLookUpKey(Context context,String lookUpKey)
{
ContentResolver contentResolver = context.getContentResolver();
Uri lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI,lookUpKey);
return contentResolver.query(lookupUri,null,null,null,null);
}
To get the data simply read data from the cursor. For example :
Cursor data = ContactManager.getContactCursorByLookUpKey(ContactDetailsActivity.this,lookUpKey);
String name = data.getString(data.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String photoPath = data.getString(data.getColumnIndex(ContactsContract.Contacts.PHOTO_URI));
You can query the Contacts provider using ContentResolver directly, if you have the READ_CONTACTS permission. You will receive a cursor with multiple rows of raw contact details (phones, emails, etc.). Iterate over the cursor to read them and don't forget to close the cursor.
Related
On top of contacts id, Android also got LOOK_UP key. Since id of contact can change, you can obtain user uri, using LOOK_UP key.
public static Uri lookupContactUri(String lookup, Context context){
ContentResolver contentResolver = context.getContentResolver();
Uri lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookup);
return ContactsContract.Contacts.lookupContact(contentResolver, lookupUri);
}
But how does it work? The source code of the Contacts.lookupContact doesn't tell much about the actual implementation. So can anyone explain how does they manage to pull this up?
/**
* Computes a content URI (see {#link #CONTENT_URI}) given a lookup URI.
* <p>
* Returns null if the contact cannot be found.
*/
public static Uri lookupContact(ContentResolver resolver, Uri lookupUri) {
if (lookupUri == null) {
return null;
}
Cursor c = resolver.query(lookupUri, new String[]{Contacts._ID}, null, null, null);
if (c == null) {
return null;
}
try {
if (c.moveToFirst()) {
long contactId = c.getLong(0);
return ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
}
} finally {
c.close();
}
return null;
}
Another thing I tested, is merging two contacts using ContactsContract.AggregationExceptions and then quarrying for contact uri. Both of the LOOK_UP keys yield with the same contact uri as expected.
So how are they doing it?
Since contact ids can change from time to time (e.g. when contacts sync is corrupted and contacts needs to be resynced from server), Android introduced the concept of LookupKeys and LookupUris.
A LookupKey is an opaque value, that internally can be translated by the Contacts framework to a set of fields: contact-id, raw-contact-ids, primary-display-names, etc.
Whenever you try to access a contact via a LookupUri, the system, extracts the LookupKey from the Uri, tries to access the contact-id, and compares the other fields (raw-ids, names, etc.) to the found contact, if it seems the right contact, it returns it.
If the contact-id wasn't found, or the system detects it's the wrong contact, a query is made over all contacts to find the right one (using the auxiliary fields stored on that key).
So the LookupKey acts as a quick method to either return the contact-id, or search for it in case something bad happened.
I tried to read the complete profile information such a (Full name, phone, adresse, mail .... ).
I have searched everywhere for a good example code. I tried many ways (Uri => Cursor) to access the Profile.
At this time I can fetch just the Full name (of the Profile contact), nothing more.
I can fetch data of other contacts using an Intent, sending to the Contacts app, BUT I CAN'T READ THE PROFILE CONTACT (JUST FULL NAME).
I have added the READ_PROFILE permission in the manifest file.
With the following code I get the Full Name (I can also access first and last name separately ):
Uri uriProfile = Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI,
ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
Cursor cursorProfile = this.getContentResolver().query(uriProfile,
null, null, null, null);
String projection = Profile.DISPLAY_NAME;
String profileName = cursorProfile.getString(cursorProfile.getColumnIndex(projection);
But when I use this the following projection to get Phone Number, it returns an error and the app stops working:
String projection = ContactsContract.CommonDataKinds.Phone.NUMBER
I found a solution using this code:
Get an URI Profile
Crate a cursor pointing to the URI content with null projection. Because for the profile, data are saved differently than a normal contact.
Point the cursor to the wanted data using MIMETYPE.
Uri uriProfile = Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI,
ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
Cursor cursorProfile = getApplicationContext().getContentResolver().query(uriProfile,
null, null, null, null);
String cursorProfile_MIMIETYPE = cursorProfile.getString(cursorProfile.getColumnIndex("MIMETYPE"));
I have two applications and I want to create a query from App A to get App B's info.
This is a very simple process as shown below, but i wanted to double check with the community and get some constructive criticism. Is there a better way?
Thank you.
This code gets the name of someone in my DB.
private Cursor getData() {
final Uri uri = Uri.parse("content://" + AUTHORITY + "/" + TABLE_PATH);
String[] projection = new String[] { "_id", "foo" };
String selection = null;
String[] selectionArgs = null;
String sortOrder = null;;
ContentResolver resolver = getContentResolver();
return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
}
Well, it should work if the system is aware of a content provider that has the authority you've specified, and that provider recognizes TABLE_PATH, and the provider recognizes "_id" and "foo" as valid column names.
However, you seem to be asking several different questions:
Is this a safe way to query another app's content provider? Oh yes; It is by far the most preferred way to get data from another app.
"This code gets the name of someone in my DB". Actually, that's a slight misstatement. The code runs a query against the content provider that has the authority AUTHORITY, and against an entity in the provider that is named TABLE_PATH. No database is necessary, although content providers often store their data in an SQLite database. All that the CP has to do is establish an authority and respond to incoming content URIs.
I am using android sample sync-adapter example code to sync my application's contacts database with the phone-book and I need to update my contacts database with the Contact_Id allotted to them as soon as they are inserted by the sync-adapter.
If you're using the ContentResolver.insert operation, the id is embedded in the returned URI. You can get it this way:
Uri resultUri = ContentResolver.insert(ContactsContract.RawContacts.CONTENT_URI, contentValues);
if (rawContactId != null) {
String rawContactId = String.valueOf(ContentUris.parseId(resultUri);
}
Is there an accepted/received way of checking to see if a person (phone number) is in the Contact List?
I'm hoping there's something I can call like this:
bool bInContactList = InContactList("1415922353");
It is not as simple as you want but you can query a Contacts content provider for the contact associated with a phone number:
Uri lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor c = getContentResolver().query(lookupUri, new String[] {PhoneLookup._ID}, null, null, null);
if (c.getCount() > 0) {
// there is some contact
} else {
// there is no contacts with phoneNumber
}
The application needs android.permission.READ_CONTACTS permission to access contacts data.
You can check Android Developer site for further references about content providers and android.providers package documentation for the list of available standard providers in Android.
I am afraid you did not provide enough information about the language you are talking about. If you use Java -for example- you have a contains method (common to all collections) so, if you want to know if a certain String is contained in a collection you could do it by invoking this method:
boolean found = someCollection.conmtains("1415922353");