I am maintaining a list of contacts for my application. First I pick contact using ACTION_PICK with an intent. I am saving these contacts in my local database along with CONTACT_ID. Now user may choose to edit any contact to add some extra information that my app needs. I fire that edit intent with ACTION_EDIT. I have two questions here
I am saving CONTACT_ID to my database in order to use in edit intent. First question is does this id changes after edition ? because It so happens that I am unable to open contact editor for same contact again.
Second question is how can I read back all the details of this edited contact ? I am getting this back in my onActivityResult(). I have tried to use same code which i am using in case of picking but data structure returned in case of edit is different it seems.
you can get any data from contacts using a cursor like
String[] projection = new String[] {
ContactsContract.PhoneLookup.DISPLAY_NAME,
ContactsContract.PhoneLookup._ID};
// query time
Cursor cursor = _context.getContentResolver()
.query("ContactsContract.Contacts.CONTENT_URI",
projection, null, null, null);
if(cursor != null) {
while ( cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex(
ContactsContract.PhoneLookup.DISPLAY_NAME));
// do other stuff
}
}
cursor.close();
take a look at https://developer.android.com/training/contacts-provider/retrieve-details.html
Related
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've pulled out most of my hair now and really needs some help
before I go completely bold
I'm trying to launch an action picker to select a Contact that has a phone number.
When that contact is selected, I want to extract the name and phone number.
But this only happens for some contacts, not all.
The code is rougly as follows:
Select contact:
Intent contactPicker = new Intent(Intent.ACTION_PICK, contactsContract.CommonDataKinds.Phone.CONTENT_URI);
startActivityForResult(contactPicker, REQ_PICK_CONTACT);
Extract id (notice getData().getLastPathSegment():
onContactForImportPicked(intent.getData().getLastPathSegment());
and then I try to fetch this contact:
String[] fields = new String[] {
ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY
};
Cursor cursor = content.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
fields,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=?", new String[] { id }, // SEE BELOW
null);
It this point, many contacts are fetched correctly, but a lot is
also non-existing. cursor.getCount() == 0. In the 'SEE BELOW'
section above, I've tried various other fields, linke
Contact._ID, Phone._ID etc etc.
Any idea why some contacts are not fetched with this method?
When I use your code, I don't even get the contact I selected correctly. The intent data contains the URI to the data you want, so you can use that directly.
Try --
Cursor cursor = content.query(data.getData(),
fields,
null,
null,
null);
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");
This question should be a starting point to all of us who want to manipulate contacts in Android.
First things first
As I am aware, since API level 5 the Contacts API has changed, so in order to make the application work correct I need to check what android os is on the phone and if prior 5 use one content provider or else use the newer one. The only annoyance in this case is the warnings of deprecated I get. The application is build against Android 2.3.3 but needs to work from 1.5+
1. Querying contacts
This is the easiest part to do. Usually querying means getting data like Contact name, phones, picture, email and displaying it on a listview. For instance here is how I've done it in API prior 5
String[] projectionPeople = new String[] {People._ID, People.NAME,};
String[] projectionPhone = new String[] {Phones.NUMBER};
try {
// Get the base URI for People table in Contacts content provider.
// which is: content://contacts/people/
Uri contactUri = People.CONTENT_URI;
ContentResolver resolver = getContentResolver();
Cursor phonesCursor = null;
Cursor peopleCursor = resolver.query (contactUri,
projectionPeople, //Which columns to return.
"People.NAME is not null", // WHERE clause--we won't specify.
null, // Selection Args??
People.DEFAULT_SORT_ORDER); // Order-by name
if (peopleCursor != null && peopleCursor.getCount() >0)
{
// go to the beginning of the list
peopleCursor.moveToFirst();
do
{
//do something with current contact info
phoneUri= Uri.withAppendedPath(personUri, Contacts.People.Phones.CONTENT_DIRECTORY);
phonesCursor = resolver.query(phoneUri,
projectionPhone,
null,
null,
Phones.DEFAULT_SORT_ORDER);
if (phonesCursor!=null && phonesCursor.getCount()>0)
{
phonesCursor.moveToFirst();
lstPhones = new ArrayList<String>();
do
{
//add phone numbers to a List<String> for instance
} while (phonesCursor.moveToNext());
if (phonesCursor != null && !phonesCursor.isClosed())
phonesCursor.close();
} while (peopleCursor.moveToNext());
if (peopleCursor != null && !peopleCursor.isClosed())
peopleCursor.close();
}
}
catch (Exception ex)
{
}
}
Haven't tried it yet on the new api but the cursor should be like
final String[] projection = new String[] {
RawContacts.CONTACT_ID, // the contact id column
RawContacts.DELETED // column if this contact is deleted
};
final Cursor rawContacts = managedQuery(RawContacts.CONTENT_URI, // the URI for raw contact provider
projection
null, // selection = null, retrieve all entries
null, // selection is without parameters
null); // do not order
Sure, this needs to be elaborated a bit more, but it should provide the basics of simple query against Contacts content provider
2. Backup
My first thought on this was: if I know the Id of a Contact, I create tables in a sqlite database exactly how the cursor columns are and insert all the data into my tables. This is not an easy task as it requires a lot of codding not to mention that different apis have different table structures. What would be the best solution to backup one contact or multiple contacts ?
3. Delete
This should work on all apis using content providers, but data is spread on many packages and uris and I'm not sure from where to delete
4. Insert
After a contact is backed up, I may need to restore/insert it again. As in case of deletion, on which uris do I need to insert ?
Please, let's try to elaborate this issues so in the futures, who needs to use Contacts in Android apps could take this question as a solid starting point. Thank you stackoverflow community.
Here is a good starting point
http://developer.android.com/resources/samples/BusinessCard/index.html
I'm reading contact data from ContractContacts, and can lookup TIMES_CONTACTED (which is useful to me), but this field only applies to calls to that contact. I'm also interested in the number of times a contact has been contacted via SMS or email.
Does anyone know if this information is available? I've been searching but haven't come across anything.
For SMS, you'll want to access the inbox located at content://sms/inbox directly and perform a database query to count the number of rows corresponding to the matching contact.
Something like:
String personAddress = addressFromContact();
Uri smsUri = new Uri("content://sms");
if (smsUri != null) {
Cursor smsCursor = getContentResolver().query(smsUri, null, "address=?", new String[] {personAddress}, null);
int smsCount = smsCursor.getCount();
}