如何以编程方式从电话中更改联系人?

问题描述 投票:0回答:1

这是我的代码:

FL.i(TAG, "Test Contact Creation editXelionContact")

    val shouldResetXelionContact = xelionContact.isDefault
    var editResult = if (shouldResetXelionContact) RESET_FAILED else NOT_CREATED_FAILED

    if (xelionContact.isAnonymous) {
        FL.i(TAG, "Test Contact Creation Do not edit XelionContact to anonymous: $xelionContact")
        return NOT_CREATED_ANONYMOUS
    }

    if (!xelionContact.isValid) {
        EXCEPTION_HANDLER.logAndReport("Test Contact Creation xelionContact not valid: name and/or number for XelionContact not set")
        FL.i(TAG,"Test Contact Creation xelionContact not valid: name and/or number for XelionContact not set")
        return editResult
    }

    if (!isCorrectNumberOfXelionContacts(1)) {
        EXCEPTION_HANDLER.logAndReport("Test Contact Creation Do not edit contact: invalid number of contacts (not 1)")
        FL.i(TAG,"Test Contact Creation Do not edit contact: invalid number of contacts (not 1)")
        return editResult
    }

    val existingXelionContact = existingXelionContact
    val shouldUpdateXelionContactConstantValues = !XelionContact.isLatestVersion
    if (shouldResetXelionContact && existingXelionContact.isDefault && !shouldUpdateXelionContactConstantValues) {
        FL.i(TAG, "Test Contact Creation Do not reset the XelionContact if it is already default: $xelionContact")
        return NOT_RESET_ALREADY_DEFAULT
    }

    if (shouldResetXelionContact && !TELEPHONY_MANAGER.isPhoneIdle) {
        FL.d(TAG, "Test Contact Creation Don't reset the XelionContact to default while the phone is ringing or while calling.")
        resetXelionContactAfterCallEnded = true // To reset directly when call ends
        startXelionContactResetTimer() // To be sure reset will always be called (when CallLogChanged is unregistered reset won't be called anymore)
        return NOT_RESET_CALL_BUSY
    }

    FL.i(TAG, "Test Contact Creation Edit contact. From: $existingXelionContact to: $xelionContact")

    val ops = ArrayList<ContentProviderOperation>()

    var builder = getNewOperationBuilderForUpdateWithSelection(SELECTION_NAME)
    builder.withValue(StructuredName.GIVEN_NAME, xelionContact.readableName)
    ops.add(builder.build())

    if (!shouldResetXelionContact) { // If the XelionContact should be reset, then do not save the default phone number, but remember the last received phoneNumber
        builder = getNewOperationBuilderForUpdateWithSelection(SELECTION_PHONE_NUMBER_WORK)
        builder.withValue(Phone.NUMBER, xelionContact.phoneNumber!!.number)
        ops.add(builder.build())
        FL.i(TAG, "Test Contact Creation Edit contact. If the XelionContact should be reset, then do not save the default phone number, but remember the last received phoneNumber")
    }

    if (shouldUpdateXelionContactConstantValues) {
        builder = getNewOperationBuilderForUpdateWithSelection(SELECTION_NOTE)
        builder.withValue(Note.NOTE, xelionContact.note)
        ops.add(builder.build())

        if (!existingXelionContact.hasPhoto()) {
            builder = getNewOperationBuilderForInsert(existingXelionContact.rawContactId, Photo.CONTENT_ITEM_TYPE)
        } else {
            builder = getNewOperationBuilderForUpdateWithSelection(SELECTION_PHOTO)
        }
        builder.withValue(Photo.PHOTO, xelionContact.photo)
        ops.add(builder.build())
    }

    try {
        FL.i("Test Contact Creation OPERATIONS ================")
        for (item in ops){
            FL.i("Test Contact Creation op: " + item.toString())
        }
        FL.i("Test Contact Creation OPERATIONS END")
        val result = contentResolver.applyBatch(AUTHORITY, ops)
        dumpResults("editXelionContact", result)
        if (result.size > 0 && result.size == ops.size) {
            editResult = if (shouldResetXelionContact) RESET else CREATED
        }
    } catch (e: Exception) {
        EXCEPTION_HANDLER.logAndReport(e)
        FL.i(TAG, "Test Contact Creation createXelionContact5: ${e.message}")
    }

    return editResult

LOG:

Test Contact Creation OPERATIONS ================
Test Contact Creation op: mType: 2, mUri: content://com.android.contacts/data, mSelection: 
account_type='com.xelion.android.account' AND mimetype='vnd.android.cursor.item/name', mExpectedCount: null, mYieldAllowed: false, mValues: data2=Alin Rosu via Xelion, mValuesBackReferences: null, mSelectionArgsBackReferences: null
I/Xelion7 dev: Test Contact Creation op: mType: 2, mUri: content://com.android.contacts/data, mSelection: account_type='com.xelion.android.account' AND mimetype='vnd.android.cursor.item/phone_v2' AND data2='3', mExpectedCount: null, mYieldAllowed: false, mValues: data1=+31157630779, mValuesBackReferences: null, mSelectionArgsBackReferences: null
Test Contact Creation OPERATIONS END
V/_PHONE_CONTACT_ XelionContactManager: Test Contact editXelionContact ContentProviderResult: dumpResults
V/_PHONE_CONTACT_ XelionContactManager: Test Contact editXelionContact ContentProviderResult:ContentProviderResult(count=0)
V/_PHONE_CONTACT_ XelionContactManager: Test Contact editXelionContact ContentProviderResult:ContentProviderResult(count=0)

此功能在三星以外的所有其他手机上均可正常使用,三星是否以某种方式处理了通讯录。不同?我在做什么另外为什么我的ContentProviderResult被发现为0?

编辑:

缺少代码:

 private fun getNewOperationBuilderForUpdateWithSelection(selectionName: String): ContentProviderOperation.Builder {
    val builder = ContentProviderOperation.newUpdate(Data.CONTENT_URI)
    builder.withSelection(getSelectionWithXelionContact(selectionName), null)
    return builder
}

  private fun getSelectionWithXelionContact(vararg extraSelections: String): String {
    val selection = StringBuilder(SELECTION_XELION_CONTACT)
    for (extraSelection in extraSelections) {
        StringFormatter.addOptionalDelimiterAndString(selection, " AND ", extraSelection)
    }
    return selection.toString()
}

   private val SELECTION_XELION_CONTACT = RawContacts.ACCOUNT_TYPE + "='" + XelionAccountManager.XELION_ACCOUNT_TYPE + "'"

    private val SELECTION_NAME = Data.MIMETYPE + "='" + StructuredName.CONTENT_ITEM_TYPE + "'"

And I Do use the mime type and account type as Marmor assumes in his answer down.

注意:这适用于大多数手机。我亲自测试了一些Google Pixel 3,Huawei Mate 10 Pro,Vivo S1 Pro,One plus 6T。仅在三星上不起作用。注意2:我确实通过一种解决方法来解决此问题,方法是在获取推送通知时删除联系人,然后再次创建联系人。由于某些原因,在三星设备上进行编辑无法正常工作,但在创建时效果很好。但仍想找出原因。是因为三星手机可能使用其他“名称”列。显示?像“给定名称”或“显示名称”一样?

android sql database contacts android-contacts
1个回答
1
投票

[嗯,您没有发布getNewOperationBuilderForUpdateWithSelection(SELECTION_NAME)的代码,但是从日志中,我认为这是在account_type='com.xelion.android.account' AND mimetype='vnd.android.cursor.item/name'上选择的,它缺少某些条件来指定您要编辑的联系人。

这基本上是说,用模拟类型“名称”更新帐户X中的所有行,并将它们全部更新为Alin。这可能会更改许多联系人,而不仅仅是您当前正在尝试编辑的联系人。您可能应该在选择中添加AND CONTACT_ID = X

© www.soinside.com 2019 - 2024. All rights reserved.