【问题标题】:How to update multiple phone numbers using ContentProviderOperation如何使用 ContentProviderOperation 更新多个电话号码
【发布时间】:2021-04-05 01:56:45
【问题描述】:

首先,我的联系人插入代码:

    fun makeRawContact(): ContentProviderOperation.Builder {
        return ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
            .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, getString(R.string.account_type_contacts))
            .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, accountName)
    }

    fun makeData(mimeType: String): ContentProviderOperation.Builder {
        return ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(ContactsContract.Data.MIMETYPE, mimeType)
    }

    fun insert(): Int {
        val ops = ArrayList<ContentProviderOperation>()
        ops += makeRawContact().build()
        ops += makeData(ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
            .withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, "testinsert")
            .build()

        ops += makeData(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
            .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, "12345678")
            .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, 1)
            .withValue(ContactsContract.CommonDataKinds.Phone.LABEL, null)
            .build()

        val result = contentResolver.applyBatch(ContactsContract.AUTHORITY, ops)
    }

假设通过调用insert(),原始id 为8。

如果我想更新联系人姓名,我会这样打电话:

    fun updateData(rawId: Long, mimeType: String): ContentProviderOperation.Builder {
        return ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
            .withSelection(ContactsContract.Data.RAW_CONTACT_ID + "=?", arrayOf(rawId.toString()))
            .withValue(ContactsContract.Data.MIMETYPE, mimeType)
    }

    fun update() {
        val ops = ArrayList<ContentProviderOperation>()
        ops += updateData(8, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
            .withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, "testupdate")
            .build()
        val result = contentResolver.applyBatch(ContactsContract.AUTHORITY, ops)
    }

我想更新原始 ID 为 8 的联系人的两个电话号码,但它只有一个电话号码 12345678。 我认为应该更新一个,另一个应该插入,所以我试图通过ContentResolver和原始ID获取电话号码的数据ID。但这似乎很复杂,所以我提出问题。有没有更好的办法?我已经看到了如何删除所有并插入新的电话号码,但我相信有更好的方法。

谢谢。

【问题讨论】:

    标签: android android-contentprovider android-contacts android-contentresolver


    【解决方案1】:

    如果您正在实现一个完整的联系人编辑器,允许用户查看和编辑信息项,那么您应该在每一行附加一个标志,说明该行是否未触及/删除/插入/更新, 然后你遍历行并相应地更新数据库。

    如果您不这样做,我见过的最干净的方法是删除数据库中该原始联系人的任何现有电话,然后插入新的/更新的电话。

    尝试将删除操作和插入操作都放在同一个 applyBatch 调用中,这样就不会有任何其他应用程序/线程尝试更新相同的原始联系人的竞争条件。

    【讨论】:

    • 感谢您的回答。如果我实现联系人编辑器,我应该有数据 ID(例如电话、电子邮件、事件......),而不是标志的原始联系人 ID?
    • 这是你的电话,但我会这样做...更新Data._ID而不是RawContact._ID
    • 其实我正在实现联系人同步应用。服务器只有RawContact.SOURCE_ID,所以我应该找到Data._ID 使用它并像我的问题一样更新电话号码(更新一个,插入另一个)?
    • 如果服务器不存储 Data._ID 您将不知道要更新哪个以及插入哪个...您可能需要比较不是一个好路径的值...在这种情况下,我会采用 delete-all-then-insert-new 方法
    • 不管是更新和插入哪个,我都在考虑根据电话号码列表的大小插入和更新联系人。 google sync-adapter 同步联系人时,数据表的ID并没有快速增加。所以,我认为有一种更新的好方法......你认为谷歌同步适配器用来实现这一点是什么?感谢您回答无聊的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多