简体   繁体   中英

Adding custom rows to contact details, only works with one contact

In an android app, I added a custom row to contact details with a custom mimetype to open my app on a specific activity. It works well if I do it to one contact, but if I try to add it to all my contacts, the custom row doesn't appear.

I'm using the following code:

// TODO Adding multiple inst working
/*contacts.forEach { contact ->
    if (!contact.aliasName.isNullOrEmpty()) {
        ContactsManager.instance.addContact(context, contact)
    }
}*/

ContactsManager.addContact(context, contacts[0])

fun addContact(context: Context, contact: Contact) {
    val resolver = context.contentResolver
    resolver.delete(ContactsContract.RawContacts.CONTENT_URI,
           ContactsContract.RawContacts.ACCOUNT_TYPE + " = ?", arrayOf(AccountGeneral.ACCOUNT_TYPE))

    val names = contact.name?.split(" ")
    Logger.e(" #### CONTACT Updated", contact.name.toString())

    var givenName = contact.name
    var familyName = ""
    if (names?.size!! > 1) {
       givenName = names[0]
       familyName = names[1]
    }

    val ops = ArrayList<ContentProviderOperation>()

    ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.RawContacts.CONTENT_URI, true))
            .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, AccountGeneral.ACCOUNT_NAME)
            .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, AccountGeneral.ACCOUNT_TYPE)
            .build())

    ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(Settings.CONTENT_URI, true))
                .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, AccountGeneral.ACCOUNT_NAME)
                .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, AccountGeneral.ACCOUNT_TYPE)
                .withValue(Settings.UNGROUPED_VISIBLE, 1)
                .build())

        ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(Data.CONTENT_URI, true))
                .withValueBackReference(Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Contacts.Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
                .withValue(StructuredName.GIVEN_NAME, givenName)
                .withValue(StructuredName.FAMILY_NAME, familyName)
                .build())

        ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(Data.CONTENT_URI, true))
                .withValueBackReference(ContactsContract.Contacts.Data.RAW_CONTACT_ID, 0)
                .withValue(Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.aliasName.getFormattedPhoneNumber())
                .build())

        ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(Data.CONTENT_URI, true))
                .withValueBackReference(ContactsContract.Contacts.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Contacts.Data.MIMETYPE, MIMETYPE)
                .withValue(ContactsContract.Contacts.Data.DATA1, Integer.valueOf(14))
                .withValue(ContactsContract.Contacts.Data.DATA2, context.getString(R.string.transferSummaryActionSendMoney))
                .withValue(ContactsContract.Contacts.Data.DATA3, context.getString(R.string.transferSummaryActionSendMoney))
                .build())

        try {
            val results = resolver.applyBatch(ContactsContract.AUTHORITY, ops)
            if (results.isEmpty())
                return
        } catch (e: Exception) {
            e.printStackTrace()
        }

How can I add the custom row to all my contacts?

Another question that I have is, when I run this code to all my contacts it takes quite some time (the time between contacts increases by 1 sec between the initial contacts, and about 10 secs when it's reaching the end of the list) . How can I convert the applyBatch to a bulkInsert ?

well, at the first line of your addContact function you're basically deleting all other custom rows your app ever added ( resolver.delete(RawContacts.CONTENT_URI, RawContacts.ACCOUNT_TYPE + " = ?", ...) ),

So basically your loop keeps deleting the last row added, and then adding a new row in its place repeatedly...

To fix that, consider adding the specific rawContact ID to the selection of your resolver.delete call.

IMPROVING PERFORMANCE :

To improve performance of your code you can do two things:

  1. move the insert to Settings out of the loop, you probably don't need to repeat that line for each contact
  2. have your addContact function accept ops as a parameter, and only fill it with operations in the function itself, the calling loop should keep checking ops.size and when it increases over some number (try 100) you run applyBatch . this should significantly reduce the number of applyBatch calls you're doing, however, there's something tricky here, as you'll need to specify the correct index for RAW_CONTACT_ID, as 0 will point to the first raw contact created in the entire batch, you need to keep track of your created raws, and specify the correct index.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM