How to remove a contact programmatically in android

不羁的心 提交于 2019-11-26 12:19:10

问题


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.


回答1:


To delete all contacts use the following code:

ContentResolver cr = getContentResolver();
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
            null, null, null, null);
    while (cur.moveToNext()) {
        try{
            String lookupKey = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
            Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey);
            System.out.println("The uri is " + uri.toString());
            cr.delete(uri, null, null);
        }
        catch(Exception e)
        {
            System.out.println(e.getStackTrace());
        }
    }

To delete any specific contact modify the query

cr.delete(uri, null, null);

Hope it helps!




回答2:


This is all we need. To delete Contact with phone number and name given

public static boolean deleteContact(Context ctx, String phone, String name) {
    Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phone));
    Cursor cur = ctx.getContentResolver().query(contactUri, null, null, null, null);
    try {
        if (cur.moveToFirst()) {
            do {
                if (cur.getString(cur.getColumnIndex(PhoneLookup.DISPLAY_NAME)).equalsIgnoreCase(name)) {
                    String lookupKey = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
                    Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey);
                    ctx.getContentResolver().delete(uri, null, null);
                    return true;
                }

            } while (cur.moveToNext());
        }

    } catch (Exception e) {
        System.out.println(e.getStackTrace());
    } finally {
        cur.close();
    }
    return false;
}

And remind to add read/write contact permission

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



回答3:


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>



回答4:


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.




回答5:


A better way to delete a contact is by removing all raw contacts using contact id

    final ArrayList ops = new ArrayList();
    final ContentResolver cr = getContentResolver();
    ops.add(ContentProviderOperation
            .newDelete(ContactsContract.RawContacts.CONTENT_URI)
            .withSelection(
                    ContactsContract.RawContacts.CONTACT_ID
                            + " = ?",
                    new String[] { allId.get(i) })
            .build());

        try {
            cr.applyBatch(ContactsContract.AUTHORITY, ops);
            int deletecontact = serialList.get(allId.get(i));

        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (OperationApplicationException e) {
            e.printStackTrace();
        }
        //background_process();
        ops.clear();
    }

and dont forget to add permissions

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



回答6:


ContentResolver cr = getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
        null, null, null, null);
while (cur.moveToNext()) {
    try{
        String lookupKey = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
        Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey);
        System.out.println("The uri is " + uri.toString());
        cr.delete(uri, null, null);
    }
    catch(Exception e)
    {
        System.out.println(e.getStackTrace());
    }
}

I have used this code to delete contacts.It will delete sim contacts as well phone contacts or only contacts stored in phone storage.




回答7:


This code works perfect for me to remove the contact from its identifier (ContactsContract.Contacts._ID)

Telephone registration for all numbers of that contact must be removed independently

  fun deleteContactById(id: String) {
      val cr = context.contentResolver
      val cur = cr.query(ContactsContract.Contacts.CONTENT_URI,
                    null, null, null, null)
      cur?.let {
          try {
                    if (it.moveToFirst()) {
                        do {
                            if (cur.getString(cur.getColumnIndex(ContactsContract.PhoneLookup._ID)) == id) {
                                val lookupKey = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY))
                                val uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey)
                                cr.delete(uri, null, null)
                                break
                            }

                        } while (it.moveToNext())
                    }

                } catch (e: Exception) {
                    println(e.stackTrace)
                } finally {
                    it.close()
                }
            }
}


来源:https://stackoverflow.com/questions/527216/how-to-remove-a-contact-programmatically-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!