tags:

views:

4187

answers:

5

I try the following code to remove contact with a specified number:

private void removeContact(Context context, String phone) {
    //context.getContentResolver().delete(Contacts.Phones.CONTENT_URI, phone, null);
    context.getContentResolver().delete(Contacts.Phones.CONTENT_URI,
          Contacts.PhonesColumns.NUMBER+"=?", new String[] {phone});
}

But I get this exception:

java.lang.UnsupportedOperationException: Cannot delete that URL: content://contacts/phones
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:130)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:110)
    at android.content.ContentProviderProxy.delete(ContentProviderNative.java:362)
    at android.content.ContentResolver.delete(ContentResolver.java:386)

Can you please tell me how to fix my problem?

Thank you.

+2  A: 

Do you have the appropriate permissions declared in your manifest?

You'll need the android.permission.READ_CONTACTS and android.permission.WRITE_CONTACTS uses-permission tags before Android will let you mess with the contacts provider:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.android.app.myapp" >

  <uses-permission android:name="android.permission.READ_CONTACTS" />
  <uses-permission android:name="android.permission.WRITE_CONTACTS" />

</manifest>
Reto Meier
Permission problems are what kill me the most. There was once I went a week trying to figure out why my vibrate code kept crashing until I figured out you needed a permission to vibrate...
num1
A: 

did you solve it? I tried it, but still get the same error too, I have the permissions in place, still get the same error.... and ideas ?

thanx

+1  A: 

A late answer, but maybe it helps anyway:

If you look at the source code of ContactsProvider and search for "matcher.addURI" (don't be surprised if it stops loading in the middle... it resumes loading after a minute or two), then you see that it has a finite set of URI schemes that it can handle. It has a handler for "phones/#" but not for "phones", which is what you would need.

This means, there is just no code to delete all phone numbers, you have to get the IDs of all numbers first, and then delete each one at a time. Of course this takes a lot more CPU and memory resources, but at least it works.

The following code deletes a specific number. Please be aware that I did not test this code, but it is 90% identical to the code I use to delete all numbers of a given person, which needs similar treatment beacause Android can't delete "people/#/phones" but "people/#/phones/#"

EDIT: I just realized that I misunderstood the question. I thought you would like to delete the phone number, which my code does. But now I see you want to delete the contanct.

private void deletePhoneNumber(Uri peopleUri, String numberToDelete) {

 Uri.Builder builder = peopleUri.buildUpon();
 builder.appendEncodedPath(People.Phones.CONTENT_DIRECTORY);
 Uri phoneNumbersUri = builder.build();


 String[] mPhoneNumberProjection = { People.Phones._ID, People.Phones.NUMBER };
 Cursor cur = resolver.query(phoneNumbersUri, mPhoneNumberProjection,
   null, null, null);

 ArrayList<String> idsToDelete = new ArrayList<String>();

 if (cur.moveToFirst()) {
  final int colId = cur.getColumnIndex(People.Phones._ID);
  final int colNumber = cur.getColumnIndex(People.Phones.NUMBER);

  do {
   String id = cur.getString(colId);
   String number = cur.getString(colNumber);
   if(number.equals(numberToDelete))
    idsToDelete.add(id);
  } while (cur.moveToNext());
 }
 cur.close();

 for (String id : idsToDelete) {
  builder.encodedPath(People.Phones.CONTENT_DIRECTORY + "/" + id);
  phoneNumbersUri = builder.build();
  resolver.delete(phoneNumbersUri, "1 = 1", null);
 }
}

The code is a bit verbose because it makes two assumptions:

  • there could be multiple lines to delete (e.g. the number is stored twice)
  • it might be unsafe to get a cursor, delete a row, and keep using the cursor

Both assumptions are handled by first storing the idsToDelete in an ArrayList and then deleting.

You might also consider to normalize the number you search for, and use the Column People.Phones.NUMBER_KEY instead, because it contains the numbers in normalized form.

Brian Schimmel
Maybe it was me being stupid, but it took me a while to figure out that a call to this function needed to be like deletePhoneNumber(Contacts.CONTENT_URI,"555"); to work. Otherwise a great answer, thanks!
sandis
great, thanks for sharing this
Tom Dignan
A: 

I was not able to delete a contact with phone number in the WHERE clause. I think it is because of some JOIN.

But, to delete a contact with name you can use this code:

getContentResolver().delete(People.CONTENT_URI, People.NAME+"=?", new String[] {"Dummy"});

Pria
A: 

Hi

getContentResolver().delete(People.CONTENT_URI, People.NAME+"=?", new String[] {"Test Name"});

This code will delete "Test Name" contact name in your contact list.

I run it and got the result.

Dhrumil Shah

Dhrumil Shah
it does not delete
mikedroid