如何在android中以编程方式删除联系人

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/527216/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 02:15:37  来源:igfitidea点击:

How to remove a contact programmatically in android

androidandroid-contactsandroid-contentresolver

提问by yinglcs

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.

谢谢你。

回答by Prateek Jain

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!

希望能帮助到你!

回答by khaintt

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" />

回答by Reto Meier

Do you have the appropriate permissions declared in your manifest?

您是否在清单中声明了适当的权限?

You'll need the android.permission.READ_CONTACTSand android.permission.WRITE_CONTACTSuses-permission tags before Android will let you mess with the contacts provider:

在 Android 允许您使用联系人提供程序之前,您需要使用android.permission.READ_CONTACTSandroid.permission.WRITE_CONTACTS使用权限标签:

<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>

回答by Lena Schimmel

A late answer, but maybe it helps anyway:

一个迟到的答案,但也许无论如何它都有帮助:

If you look at the source code of ContactsProviderand 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.

如果您查看ContactsProvider源代码并搜索“matcher.addURI”(如果它在中间停止加载,请不要感到惊讶......它会在一两分钟后恢复加载),然后您会看到它有一个它可以处理的有限 URI 方案集。它有一个用于“phones/#”的处理程序,但没有用于“phones”的处理程序,而这正是您所需要的。

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.

这意味着,没有删除所有电话号码的代码,您必须先获取所有号码的 ID,然后一次删除一个。当然,这需要更多的 CPU 和内存资源,但至少它是有效的。

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/#"

以下代码删除特定号码。请注意,我没有测试此代码,但它与我用来删除给定人员的所有号码的代码 90% 相同,这需要类似的处理,因为 Android 无法删除“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 idsToDeletein an ArrayListand then deleting.

这两个假设都是通过首先将 存储idsToDelete在 an 中ArrayList然后删除来处理的。

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

您还可以考虑对搜索的数字进行规范化,并改用 Column People.Phones.NUMBER_KEY,因为它包含规范化形式的数字。

回答by Anish Bhandari

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

删除联系人的更好方法是使用联系人 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"/>

回答by Sergio Sánchez Sánchez

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

此代码非常适合我从其标识符(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()
                }
            }
}

回答by Tirtha

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.

我已使用此代码删除联系人。它将删除 sim 联系人以及电话联系人或仅存储在电话存储中的联系人。