如何使用 android 中的联系电话以编程方式删除本机联系人?

How to programatically delete a native contact using the contact number in android?

我需要仅使用 MSISDN 从本机联系人列表中删除联系人。目前,我正在浏览所有联系人并匹配号码以获取姓名。有没有更有效的方法来做到这一点?

这是我的代码:

获取所有本机联系人:

override fun nativeContactList(): Single<List<NativeContact>> {
    val contacts = ArrayList<NativeContact>()
    val cursor = context.contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, null,
            null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC")
    val normalizedNumbersAlreadyFound = HashSet<String>();
    val indexOfNormalizedNumber = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER)
    val indexOfDisplayName = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)
    val indexOfDisplayNumber = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
    cursor.use { cursor ->
        while (cursor.moveToNext()) {
            val normalizedNumber = cursor.getString(indexOfNormalizedNumber)
            if (normalizedNumbersAlreadyFound.add(normalizedNumber)) {
                val displayName = cursor.getString(indexOfDisplayName)
                val displayNumber = cursor.getString(indexOfDisplayNumber)
                Timber.d("Existing contact: $displayName $displayNumber")
                contacts.add(NativeContact(displayName, displayNumber, null, null))
            }
        }
        cursor.close()
    }
    return Single.fromCallable {
        contacts
    }
}

获得本机联系人列表后,我遍历列表并查找匹配项以获得名称:

   Observable.fromIterable(nativeContacts)
            .subscribeOn(processScheduler)
            .subscribe(object : DisposableObserver<NativeContact>() {
                override fun onComplete() {
                    Timber.d("Finished going thorough contacts")
                }


                override fun onError(e: Throwable) {
                    Timber.d("Warning: exception occurred while looping through native contacts list")
                }

                override fun onNext(nativeContact: NativeContact) {
                    if (contactToDelete.number == nativeContact.phoneNumber) {
                        contactToDelete.firstName = nativeContact.name
                        deprovisionContact(contactToDelete)
                    }
                }

            })

在我有了姓名和电话号码后,我删除了联系人:

        public Completable deleteContact(final ContactToDelete contactToDelete) {
        return Completable.fromAction(new Action() {
            @Override
            public void run() throws Exception {
                Timber.d("Attempting to delete " + contactToDelete.getNumber() + " " + contactToDelete.getName());
                Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(contactToDelete.getNumber()));
                Cursor cursor = context.getContentResolver().query(contactUri, null, null, null, null);
                try {
                    if (cursor.moveToFirst()) {
                        do {
String name = contactToDelete.getName();
  if (cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME)).equalsIgnoreCase(name)) {
                                String lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
                                Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey);
                                context.getContentResolver().delete(uri, null, null);
                                Timber.d("deleted " + contactToDelete.getNumber() + " " + contactToDelete.getName());
                            }

                        } while (cursor.moveToNext());
                    }

                } catch (Exception e) {
                    Timber.e("Error while attempting to delete contact " + e.getMessage());
                } finally {
                    cursor.close();
                }
            }
        });
    }

有没有更有效的方法来做到这一点?即不是每次我们要删除联系人时都循环遍历联系人列表吗?提前谢谢你。

我发现了一些问题。

  1. 首先你的要求不明确,是不是要删除所有包含这个phone号码的联系人? phone 号码不是唯一标识符,可以由多个联系人共享,您是否应该删除所有这些联系人?

  2. 您正在遍历所有联系人只是为了获取姓名?为什么你需要一个名字来删除一个联系人,这也是一个非唯一标识符,可能有多个联系人具有相同的名称和相同的号码。

  3. 你在这里做的步骤太多了,我看你已经很熟悉了 PHONE_LOOKUP table,你只需要使用它来删除与请求的 phone 号码联系。

代码示例(未测试):

// get all contact-ids of all deletion candidates
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
String[] projection = new String[]{ PhoneLookup.CONTACT_ID };
Cursor idsCursor = resolver.query(uri, projection, null, null, null); 

// iterate the cursor and delete all the contact-ids one-by-one
while (idsCursor != null && idsCursor.moveToNext()) {
    Long contactId = idsCursor.getLong(0);
    Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
    context.getContentResolver().delete(contactUri, null, null);
}
if (idsCursor != null) {
    idsCursor.close();
}