I've created a contact in the Android address book programmatically, which has a name and phone number. Now I'd like to add a photo to this contact, but I can't seem to get this working. I don't receive an error message, but the photo doesn't seem to get added.
If I create a new contact WITH photo, the photo is added correctly, and I can update the exisiting photo of this contact as well. Only problem is a contact without photo.
I've already read several solutions here and here, and tried several variations based on these answers, but neither works. My best guess is that I'm doing something wrong with the RAW_CONTACT_ID. Anyone who can find my bug?
private void createNewContact()
{
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
builder.withValue(RawContacts.ACCOUNT_TYPE, MY_ACCOUNT_TYPE);
builder.withValue(RawContacts.ACCOUNT_NAME, MY_ACCOUNT_NAME);
ops.add(builder.build());
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withValueBackReference(Data.RAW_CONTACT_ID, 0);
builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
builder.withValue(StructuredName.GIVEN_NAME, myName);
ops.add(builder.build());
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withValueBackReference(Data.RAW_CONTACT_ID, 0);
builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
builder.withValue(Phone.TYPE, Phone.TYPE_WORK);
builder.withValue(Phone.NUMBER, myPhoneNumber);
ops.add(builder.build());
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withValueBackReference(Data.RAW_CONTACT_ID, 0);
builder.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
builder.withValue(Photo.PHOTO, myPhotoByteArray);
ops.add(builder.build());
try
{
context.getContentResolver().applyBatch(AUTHORITY, ops);
}
catch (Exception e)
{
// Handle exception
}
}
private static final String BASIC_SELECTION = RawContacts.ACCOUNT_TYPE + "='" + MY_ACCOUNT_TYPE + "'";
private void editContact() {
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
ContentProviderOperation.Builder builder = ContentProviderOperation.newUpdate(Data.CONTENT_URI);
builder.withSelection(BASIC_SELECTION + " AND " + Data.MIMETYPE + "='" + StructuredName.CONTENT_ITEM_TYPE + "'", null);
builder.withValue(StructuredName.GIVEN_NAME, myName);
ops.add(builder.build());
builder = ContentProviderOperation.newUpdate(Data.CONTENT_URI);
builder.withSelection(BASIC_SELECTION + " AND " + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'" + " AND " + Phone.TYPE + "='" + Phone.TYPE_WORK + "'", null);
builder.withValue(Phone.NUMBER, myPhoneNumber);
ops.add(builder.build());
if (isContactWithoutPhoto())
{
// Contact without photo: insert new photo
// TODO: this part doesn't work yet!
int rawContactId = getRawContactId();
if (rawContactId != -1)
{
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withValue(Data.RAW_CONTACT_ID, rawContactId);
builder.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
builder.withValue(Photo.PHOTO, myPhotoByteArray);
ops.add(builder.build());
}
}
else
{
// Contact already has a photo: update
builder = ContentProviderOperation.newUpdate(Data.CONTENT_URI);
builder.withSelection(BASIC_SELECTION + " AND " + Data.MIMETYPE + "='" + Photo.CONTENT_ITEM_TYPE + "'", null);
builder.withValue(Photo.PHOTO, myPhotoBytes);
ops.add(builder.build());
}
try
{
context.getContentResolver().applyBatch(AUTHORITY, ops);
}
catch (Exception e)
{
// Handle exception
}
}
private int getRawContactId()
{
int rawContactId = -1;
Cursor cursor = null;
try
{
cursor = App.getContext().getContentResolver().query(RawContacts.CONTENT_URI, null, ACCOUNT_TYPE_SELECTION, null, null);
if (cursor != null && cursor.moveToFirst())
{
rawContactId = cursor.getInt(cursor.getColumnIndex(RawContacts._ID));
}
}
finally
{
if (cursor != null)
{
cursor.close();
}
}
return rawContactId;
}
EDIT:
I only need a single contact, which is created a single time, after which it only needs to be updated regularly. This contact is saved on a self-created account with type MY_ACCOUNT_TYPE & name MY_ACCOUNT_NAME. Hence the builder.withSelection(BASIC_SELECTION for each update operation, which uses MY_ACCOUNT_TYPE rather than an id.
I have also tried to add that same selection on the 'update photo on existing contact' part, to implement it more like the other 'update' code, because I want to be sure I update the photo ONLY for that single contact:
int rawContactId = getRawContactId();
if (rawContactId != -1)
{
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withSelection(BASIC_SELECTION + " AND " + Data.MIMETYPE + "='" + Photo.CONTENT_ITEM_TYPE + "'", null);
builder.withValue(Data.RAW_CONTACT_ID, rawContactId);
builder.withValue(Photo.PHOTO, myPhotoByteArray);
ops.add(builder.build());
In this case the app obviously crashes with the error java.lang.IllegalArgumentException: only updates, deletes, and asserts can have selections. The id is already collected using the BASIC_SELECTION, so I expect the correct contact to be updated in this way anyway.
In case somebody wonders which (static) imports for ContactsContract are used:
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.PhoneLookup;
import static android.provider.ContactsContract.AUTHORITY;
import static android.provider.ContactsContract.CommonDataKinds.Note;
import static android.provider.ContactsContract.CommonDataKinds.Phone;
import static android.provider.ContactsContract.CommonDataKinds.StructuredName;
import static android.provider.ContactsContract.Data;
import static android.provider.ContactsContract.RawContacts;
Don't access CommonDataKinds.Photo directly, instead use the APIs supplied helper class DisplayPhoto.
This helper class will populate both PHOTO and PHOTO_FILE_ID which is what your code was missing.
try the following:
public void setPhoto(long rawContactId, byte[] photo) {
Uri rawContactPhotoUri = Uri.withAppendedPath(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
try {
AssetFileDescriptor fd = contentResolver.openAssetFileDescriptor(rawContactPhotoUri, "rw");
OutputStream os = fd.createOutputStream();
os.write(photo);
os.close();
fd.close();
} catch (IOException e) {
Log.e(TAG, "error", e);
}
}
With a lot of trial and error I found the RawContactId was not correct.
Finally I came up with this solution: retrieve the RawContacts.CONTACT_ID using PhoneLookup._ID, which can be retrieved by the phoneNumber.
// This code stays the same as described in the question (except for some error handling and closing cursors, which I left out for simplicity sake):
private void createNewContact() {
...
}
private static final String BASIC_SELECTION = RawContacts.ACCOUNT_TYPE + "='" + MY_ACCOUNT_TYPE + "'";
private void editContact() {
...
int rawContactId = getRawContactId();
...
}
// The different part is the way to retrieve the RawContactId:
private static final ContentResolver CONTENT_RESOLVER = context.getContentResolver();
private int getRawContactId()
{
String[] projection = {Phone.NUMBER};
Cursor cursor = CONTENT_RESOLVER.query(Phone.CONTENT_URI, projection, BASIC_SELECTION, null, null);
String phoneNumber = cursor.getString(cursor.getColumnIndex(Phone.NUMBER));
return getRawContactIdWithPhoneNumber(phoneNumber);
}
private int getRawContactIdWithPhoneNumber(String phoneNumber)
{
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
String[] projection = {PhoneLookup._ID, PhoneLookup.DISPLAY_NAME};
Cursor cursor = CONTENT_RESOLVER.query(uri, projection, BASIC_SELECTION, null, null);
int id = cursor.getInt(cursor.getColumnIndex(PhoneLookup._ID));
return getRawContactIdWithPhoneLookupId(id);
}
private int getRawContactIdWithPhoneLookupId(int id)
{
String[] projection = new String[]{RawContacts._ID};
String selection = RawContacts.CONTACT_ID + "=?";
String[] selectionArgs = new String[]{String.valueOf(id)};
Cursor cursor = CONTENT_RESOLVER.query(RawContacts.CONTENT_URI, projection, selection, selectionArgs, null);
return cursor.getInt(cursor.getColumnIndex(RawContacts._ID));
}
Related
I know how to retrieve a user profile from the ContentResolver. If I have a bitmap, how can I set it as a user profile picture (replace it OR set it, if none exists)?
I load the user profile like following:
Uri dataUri = Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI, ContactsContract.Contacts.Data.CONTENT_DIRECTORY);
String[] selection = new String[]
{
ContactsContract.Profile._ID,
ContactsContract.Profile.DISPLAY_NAME,
ContactsContract.Profile.PHOTO_URI,
ContactsContract.Profile.LOOKUP_KEY
};
Cursor cursor = MainApp.get().getContentResolver().query(
dataUri,
selection,
null,
null,
null);
if (cursor != null)
{
int id = cursor.getColumnIndex(ContactsContract.Profile._ID);
int name = cursor.getColumnIndex(ContactsContract.Profile.DISPLAY_NAME);
int photoUri = cursor.getColumnIndex(ContactsContract.Profile.PHOTO_URI);
int lookupKey = cursor.getColumnIndex(ContactsContract.Profile.LOOKUP_KEY);
try
{
if (cursor.moveToFirst())
{
int phId = cursor.getInt(id);
mName = cursor.getString(name);
mImageUri = cursor.getString(photoUri);
mLookupKey = cursor.getString(lookupKey);
mExists = true;
}
}
finally
{
cursor.close();
}
}
Here's how to update or create profile images, actually it's working the same way as updating normal contact pictures. I had a problem somewhere else...
Instead of using my UserProfile, just exchange them and hand on the raw id.
private static void updatePhoto(UserProfile profile, Bitmap bitmap, ...)
{
byte[] photo = ImageUtil.convertImageToByteArray(bitmap, true);
ContentValues values = new ContentValues();
int photoRow = -1;
String where = ContactsContract.Data.RAW_CONTACT_ID + " = " + profile.getRawId() + " AND " + ContactsContract.Data.MIMETYPE + "=='" + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'";
Cursor cursor = MainApp.get().getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, where, null, null);
int idIdx = cursor.getColumnIndexOrThrow(ContactsContract.Data._ID);
if (cursor.moveToFirst()) {
photoRow = cursor.getInt(idIdx);
}
cursor.close();
values.put(ContactsContract.Data.RAW_CONTACT_ID, profile.getRawId());
values.put(ContactsContract.Data.IS_SUPER_PRIMARY, 1);
values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, photo);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
if (photoRow >= 0) {
MainApp.get().getContentResolver().update(ContactsContract.Data.CONTENT_URI, values, ContactsContract.Data._ID + " = " + photoRow, null);
} else {
MainApp.get().getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
}
...
}
I am trying to create a app which will fetch details of Events and Attendees from Calendar app on device.
I am facing the problems which are:
1). In many of the events Title and their attendees does not match.
2). In many of the events I am getting 0 attendees (mainly for upcoming events).
Here is my code: (Please let me know the mistake).
public class ReadCalendar {
static Cursor cursor;
public static void readCalendar(Context context) {
ContentResolver contentResolver = context.getContentResolver();
// Fetch a list of all calendars synced with the device, their display names and whether the
cursor = contentResolver.query(Uri.parse("content://com.android.calendar/calendars"),
(new String[] { Calendars._ID, Calendars.NAME}), null, null, null);
HashSet<String> calendarIds = new HashSet<String>();
try
{
System.out.println("Count="+cursor.getCount());
if(cursor.getCount() > 0)
{
System.out.println("the control is just inside of the cursor.count loop");
while (cursor.moveToNext()) {
String _id = cursor.getString(0);
String displayName = cursor.getString(1);
//Boolean selected = !cursor.getString(2).equals("0");
System.out.println("Id: " + _id + " Display Name: " + displayName);
calendarIds.add(_id);
}
}
}
catch(AssertionError ex)
{
ex.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
// For each calendar, display all the events from the previous week to the end of next week.
for (String id : calendarIds) {
Uri.Builder builder = Uri.parse("content://com.android.calendar/instances/when").buildUpon();
//Uri.Builder builder = Uri.parse("content://com.android.calendar/calendars").buildUpon();
long now = new Date().getTime();
ContentUris.appendId(builder, now - DateUtils.DAY_IN_MILLIS * 10000);
ContentUris.appendId(builder, now + DateUtils.DAY_IN_MILLIS * 10000);
Log.e("123", "Calender ID---->>>>>>"+id);
Cursor eventCursor = contentResolver.query(builder.build(),
new String[] { Events.TITLE, "begin", "end", "allDay", Events._ID, Events.CALENDAR_ID}, Events.CALENDAR_ID+"=" + id,
null, "_id ASC");
Log.e("123","eventCursor count====="+eventCursor.getCount());
if(eventCursor.getCount()>0)
{
if(eventCursor.moveToFirst())
{
do
{
Object mbeg_date,beg_date,beg_time,end_date,end_time;
final String title = eventCursor.getString(0);
final Date begin = new Date(eventCursor.getLong(1));
final Date end = new Date(eventCursor.getLong(2));
final Boolean allDay = !eventCursor.getString(3).equals("0");
final String eventId = eventCursor.getString(4);
final String calendarID = eventCursor.getString(5);
Log.e("123", "Event Id----->>>>>"+eventId+"---------calendarId----->>>"+calendarID);
/* System.out.println("Title: " + title + " Begin: " + begin + " End: " + end +
" All Day: " + allDay);
*/
Log.e("123","Title:"+title);
Log.e("123","Begin:"+begin);
Log.e("123","End:"+end);
Log.e("123","All Day:"+allDay);
// Attendees Code
Cursor eventAttendeesCoursor = contentResolver.query(CalendarContract.Attendees.CONTENT_URI, new String []{ Attendees.ATTENDEE_NAME, Attendees.EVENT_ID}, Attendees.EVENT_ID +" = " + eventId, null, null);
Log.e("123", "Count of no of attendees-----"+eventAttendeesCoursor.getCount());
if(eventAttendeesCoursor.getCount()>0)
{
if(eventAttendeesCoursor.moveToFirst())
{
do {
// Log.e("123", "Attendees Name---->>>"+ eventAttendeesCoursor.getString(0));
Log.e("123", "Attendees Event ID---->>>"+ eventAttendeesCoursor.getString(1));
} while(eventAttendeesCoursor.moveToNext());
}
}
}
while(eventCursor.moveToNext());
}
}
break;
}
}
}
I didnt look in details into your code, but i just ran into the same issue - and it was because of a mixup between the instance id and the event id. I did see that your uri (builder) is based on instances, but the field you're requiring is event.id : these are distinct.
The important thing is that the attendees table is based on the EVENT id - and not the instance id - so it's likely to explain your issues.
Put it all in order, consistently (i.e. extracting the EVENT id from the INSTANCE table based on your URI and pass it on to the ATTENDEES table. See if that helps.
I was recently playing around with some code that goes through my contacts and creates an identicon for any contact that does not have a photo set. For the most part this ended up working quite well but for some reason I have a handful of contacts that will not update. Log output says it is creating the photo. The update() returns 1 indicating 1 row was updated and stepping through the code for a contact that never seems to show the new photo looks good.
The fact that only a select few are not updating is what is really bugging me and I'm guessing there must be something I am doing wrong or missing here.
private void processContacts() {
Cursor cursor = getContacts();
Log.d(TAG, "Processing " + cursor.getCount() + " contacts");
while(cursor.moveToNext()) {
final long contactId = cursor.getLong(0);
final String name = cursor.getString(1);
if (!TextUtils.isEmpty(name)) {
final Uri contactUri = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI,
contactId);
if(ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(),
contactUri, true) == null) {
Log.d(TAG, String.format("Creating identicon for %s", name));
generateIdenticon(contactId, name);
} else {
Log.i(TAG, String.format("%s already has a contact photo", name));
}
}
}
cursor.close();
}
private Cursor getContacts() {
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] { ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME };
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
+ " COLLATE LOCALIZED ASC";
return getContentResolver().query(uri, projection, null, null, sortOrder);
}
private void generateIdenticon(long contactId, String name) {
if (!TextUtils.isEmpty(name)) {
updateNotification(getString(R.string.identicons_creation_service_running_title),
String.format(getString(R.string.identicons_creation_service_contact_summary),
name));
final byte[] hash = Identicon.generateHash(name);
final byte[] identicon = Identicon.generateIdenticonByteArray(hash);
if (identicon == null) {
Log.e(TAG, "generateIdenticon() - identicon for " + name + " is null!");
} else {
if (!setContactPhoto(getContentResolver(), identicon, contactId)) {
Log.e(TAG, "Unable to save identicon for " + name);
}
}
}
}
private boolean setContactPhoto(ContentResolver resolver, byte[] bytes, long personId) {
ContentValues values = new ContentValues();
int photoRow = -1;
String where = ContactsContract.Data.RAW_CONTACT_ID + " == " +
String.valueOf(personId) + " AND " + ContactsContract.Data.MIMETYPE + "=='" +
ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'";
Cursor cursor = resolver.query(
ContactsContract.Data.CONTENT_URI,
null,
where,
null,
null);
int idIdx = cursor.getColumnIndexOrThrow(ContactsContract.Data._ID);
if(cursor.moveToFirst()){
photoRow = cursor.getInt(idIdx);
}
cursor.close();
values.put(ContactsContract.Data.RAW_CONTACT_ID, personId);
values.put(ContactsContract.Data.IS_PRIMARY, 1);
values.put(ContactsContract.Data.IS_SUPER_PRIMARY, 1);
values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, bytes);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
if (photoRow >= 0) {
final int rowsUpdated = resolver.update(ContactsContract.Data.CONTENT_URI,
values, ContactsContract.Data._ID + "=" + photoRow, null);
return rowsUpdated >= 1;
} else {
final Uri uri = resolver.insert(ContactsContract.Data.CONTENT_URI, values);
return uri != null && !TextUtils.isEmpty(uri.toString());
}
}
All this is being done inside a background service and all my contacts are synced via google. One last thing to note is that these select contacts always return null when I call ContactsContract.Contacts.openContactPhotoInputStream() to see if a photo is available (even after I've attempted to update the photo).
Any help or insight about what may be going on is greatly appreciated.
When a one of the contact have multiple numbers, for example:
Display name: GuessWho TYPE = home Number = homeNumber
TYPE = mobile Number = mobileNumber TYPE = other
Number = otherNumber ...
in conclusion ... one from those.
How I can remove a TYPE with number from this contact ( let's say "mobile" )? I have to update it using the userID acquired from the previous query, or how?
I just need to delete a single TYPE with number, other field of the contact must remain intact.
I am using this piece of code for obtaining contact :
int indexName = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int indexNumber = c
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int indexType = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
int indexID = c.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID);
String name = c.getString(indexName);
String number = c.getString(indexNumber);
String type = c.getString(indexType);
String typeStored = (String) Phone.getTypeLabel(mContext.getResources(), Integer.parseInt(type), "");
Log.i("TYPE READED : ", typeStored);
String id = c.getString(indexID);
where c is the cursor of the query.
Each number from same contact has it's own ID. You should use it for deleting. But you also need contact ID. You can get it using this line of code:
contactID = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
Then you delete the number using following code:
Cursor cur = contentResolver.query(RawContacts.CONTENT_URI,
new String[]{RawContacts._ID},
RawContacts.CONTACT_ID + "=?",
new String[] {contactID.toString()}, null);
int rowId=0;;
if(cur.moveToFirst()){
rowId = cur.getInt(cur.getColumnIndex(RawContacts._ID));
}
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
String selectPhone = Data.RAW_CONTACT_ID + " = ? AND " +
Data.MIMETYPE + " = ? AND " +
Phone._ID + " = ?";
String[] phoneArgs = new String[] { Integer.toString(rowId),
Phone.CONTENT_ITEM_TYPE,
ID.toString()};
ops.add(ContentProviderOperation.newDelete(Data.CONTENT_URI)
.withSelection(selectPhone, phoneArgs).build());
try {
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
e.printStackTrace();
} catch (OperationApplicationException e) {
e.printStackTrace();
}
The code to delete is a little long, the below does what it should with less lines of code
public static void deleteContact(ContentResolver contactHelper, String number) {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
String[] args = new String[] { String.valueOf(getContactID(contactHelper, number)) };
ops.add(ContentProviderOperation.newDelete(RawContacts.CONTENT_URI).withSelection(RawContacts.CONTACT_ID + "=?", args).build());
try {
contactHelper.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
e.printStackTrace();
} catch (OperationApplicationException e) {
e.printStackTrace();
}
}
I am making an android app, I want to remove a contact from a specific group not to delete contact just remove from the group, I have group id and contact id, can anyone please tell me the query to do this,
I want to implement something like Delete contact_id=1 from group_id=2
Contacts are linked to groups with ContactsContract.CommonDataKinds.GroupMembership records. You can use something like this to delete contact from group:
private void deleteContactFromGroup(long contactId, long groupId)
{
ContentResolver cr = getContentResolver();
String where = ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID + "=" + groupId + " AND "
+ ContactsContract.CommonDataKinds.GroupMembership.RAW_CONTACT_ID + "=?" + " AND "
+ ContactsContract.CommonDataKinds.GroupMembership.MIMETYPE + "='"
+ ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE + "'";
for (Long id : getRawContactIdsForContact(contactId))
{
try
{
cr.delete(ContactsContract.Data.CONTENT_URI, where,
new String[] { String.valueOf(id) });
} catch (Exception e)
{
e.printStackTrace();
}
}
}
private HashSet<Long> getRawContactIdsForContact(long contactId)
{
HashSet<Long> ids = new HashSet<Long>();
Cursor cursor = getContentResolver().query(RawContacts.CONTENT_URI,
new String[]{RawContacts._ID},
RawContacts.CONTACT_ID + "=?",
new String[]{String.valueOf(contactId)}, null);
if (cursor != null && cursor.moveToFirst())
{
do
{
ids.add(cursor.getLong(0));
} while (cursor.moveToNext());
cursor.close();
}
return ids;
}
Note that when you perform delete, you should specify RAW_CONTACT_ID instead of CONTACT_ID. So you need to query all raw contact ids for specified contact.
Also you may need to consider account data. In that case change querying for contact ids to something like that:
Uri rawContactUri = RawContacts.CONTENT_URI.buildUpon()
.appendQueryParameter(RawContacts.ACCOUNT_NAME, accountName)
.appendQueryParameter(RawContacts.ACCOUNT_TYPE, accountType).build();
Cursor cursor = getContentResolver().query(rawContactUri,
new String[] { RawContacts._ID }, RawContacts.CONTACT_ID + "=?",
new String[] { String.valueOf(contactId) }, null);
public static Uri addContactToGroup(String rawContactId,String groupId)
{
try
{
ContentValues values = new ContentValues();
values.put(Data.RAW_CONTACT_ID, rawContactId);
values.put(GroupMembership.GROUP_ROW_ID, groupId);
values.put(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
return getContentResolver.insert(Data.CONTENT_URI, values);
}
catch (Exception e)
{}
return Uri.EMPTY;
}
//-----------------------------------
public static int removeContactFromGroup(String contactId,String groupId)
{
try
{
String where = Data.CONTACT_ID + " = ? AND " + Data.MIMETYPE + " = ? AND " + GroupMembership.GROUP_ROW_ID + " = ?";
String[] args = {contactId, GroupMembership.CONTENT_ITEM_TYPE, groupId};
return getContentResolver.delete(Data.CONTENT_URI, where, args);
}
catch (Exception e)
{}
return 0;
}