Как программно изменить контакт с телефона? - PullRequest
0 голосов
/ 20 февраля 2020

Это мой код:

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)

Это работает правильно на всех других телефонах, кроме Samsung, Samsung как-то обрабатывает контакты. другой? Что я делаю? Кроме того, почему мой 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. Я исправил это с помощью обходного пути, удалив контакт при получении моего уведомления pu sh, и это снова создало его. По какой-то причине на устройствах Samsung его редактирование не работало, но с созданием работало нормально. Но все равно хотелось бы выяснить, почему это происходит. Это потому, что телефоны Samsung могут использовать другой столбец «имя». для отображения? Как "имя_символа" или "имя_отображения"?

1 Ответ

2 голосов
/ 23 февраля 2020

Ну, вы не опубликовали код для: getNewOperationBuilderForUpdateWithSelection(SELECTION_NAME), но из журналов я предполагаю, что это выбирает account_type='com.xelion.android.account' AND mimetype='vnd.android.cursor.item/name', в котором отсутствует какое-либо условие для указания, какой контакт вы пытаетесь редактировать.

Это в основном говорит, что обновите ВСЕ строки в учетной записи X с помощью mimetype "name" и обновите их ВСЕ до Alin. Это может изменить многие контакты, а не только тот, который вы сейчас пытаетесь редактировать. Возможно, вам следует добавить AND CONTACT_ID = X к вашему выбору.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...