Whenever I want to add new data to an existing Android contact, I use the following function to retrieve all RawContacts
IDs for the given contact ID:
protected ArrayList<Long> getRawContactID(String contact_id) {
ArrayList<Long> rawContactIDs = new ArrayList<Long>();
String[] projection = new String[] { ContactsContract.RawContacts._ID };
String where = ContactsContract.RawContacts.CONTACT_ID + " = ?";
String[] selection = new String[] { contact_id };
Cursor c = getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, projection, where, selection, null);
try {
while (c.moveToNext()) {
rawContactIDs.add(c.getLong(0));
}
}
finally {
c.close();
}
return rawContactIDs;
}
After that, I just insert the data using the ContentResolver
:
getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
This is done for all RawContacts
IDs that have been found previously. The effect is, of course, that all data is added repeatedly. Thus I want to return only one result now, but this has to meet special requirements.
I would like to adjust my function above so that its result meets the following requirements:
ContactsContract.RawContactsColumn.DELETED
must be 0RawContacts
entry must not be a secured one like Facebook'sContactsContract.SyncColumns.ACCOUNT_TYPE
is preferably "com.google". So if there is one entry that meets this requirement, it should be returned. If there is none, return any of the remaining entries.How can I do this (most efficiently)? I don't want to make the query to complex.
I have given this some thought, from my experience with contact r/w, and with your needs in mind. I hope this helps you solve the issue and or points you in the direction you are looking for. Please note that i have no device available with any sync adapters such as facebook so unfortunately i cannot confirm my answer viability (the read only bit mainly which might changeable to a simple != '' ).
Same getRawContactID
function with some adjustments
protected ArrayList<Long> getRawContactID(String contact_id) {
HashMap<String,Long> rawContactIDs = new HashMap<String,Long>();
String[] projection = new String[] { ContactsContract.RawContacts._ID, ContactsContract.RawContacts.ACCOUNT_TYPE };
String where = ContactsContract.RawContacts.CONTACT_ID + " = ? AND " + ContactsContract.RawContacts.DELETED + " != 1 AND " + ContactsContract.RawContacts.RAW_CONTACT_IS_READ_ONLY + " != 1" ;
String[] selection = new String[] { contact_id };
Cursor c = getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, projection, where, selection, null);
try {
while (c.moveToNext()) {
rawContactIDs.put(c.getString(1),c.getLong(0));
}
}
finally {
c.close();
}
return getBestRawID(rawContactIDs);
}
And another getBestRawID
function to find the best suited account -
protected ArrayList<Long> getBestRawID(Map<String,Long> rawContactIDs)
{
ArrayList<Long> out = new ArrayList<Long>();
for (String key : rawContactIDs.KeySet())
{
if (key.equals("com.google"))
{
out.clear(); // might be better to seperate handling of this to another function to prevent WW3.
out.add(rawContactIDs.get(key));
return out;
} else {
out.add(rawContactIDs.get(key));
}
}
return out;
}
Also note - I wrote most of the code without running / testing it. Apologies in advance.