Some Contacts duplicate when adding custom MIME-Type to the Contact using Authenticator Service

Viewed 71

I wrote the Sync Adapter and Authenticator Service to Add my custom MimeType (Which are used to enable calling feature within our app, so when user clicks on it in the contacts, it opens our application just like Whatsapp/Telegram does).

Authenticator service and sync performing methods are working fine the only problem is the on some devices like Pixel 3a (Android 11) some of the contacts are getting duplicated. And all the duplicated contacts have no details other than name and the calling button to our app. Also for some Devices like POCO F1 (Android 10) its Not duplicating anything at all.

Duplication is not random as same contacts are being duplicated If I remove the app and re-install and perform sync.

See the following image :

Duplicate contacts in Contacts App

This is how I am editing the contact (took reference from the SO as well).


    fun addContact(context: Context, user: User) {
        if (user.phoneNo.isNullOrEmpty()) {
            Log.e("IS EMPTY", "phone = ${user.phoneNo} email : ${user.email}")
            return
        }
        val resolver: ContentResolver = context.contentResolver
        val ops = ArrayList<ContentProviderOperation>()
        ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(RawContacts.CONTENT_URI))
                .withValue(RawContacts.ACCOUNT_NAME, context.applicationInfo.loadLabel(context.packageManager).toString())
                .withValue(RawContacts.ACCOUNT_TYPE, AccountConstants.ACCOUNT_TYPE)
                .build())
        ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Settings.CONTENT_URI))
                .withValue(RawContacts.ACCOUNT_NAME, context.applicationInfo.loadLabel(context.packageManager).toString())
                .withValue(RawContacts.ACCOUNT_TYPE, AccountConstants.ACCOUNT_TYPE)
                .withValue(ContactsContract.Settings.UNGROUPED_VISIBLE, 1)
                .build())
        ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(Data.CONTENT_URI))
                .withValueBackReference(Data.RAW_CONTACT_ID, 0)
                .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
                .withValue(StructuredName.GIVEN_NAME, user.name)
                .build())

        if (!user.phoneNo.isNullOrEmpty())
            ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(Data.CONTENT_URI))
                    .withValueBackReference(Data.RAW_CONTACT_ID, 0)
                    .withValue(Data.MIMETYPE, MIMETYPE_CALL)
                    .withValue(Data.DATA1, user.phoneNo)
                    .withValue(Data.DATA2, "Call")
                    .withValue(Data.DATA3, "Make a Call")
                    .build())
//Disregard Message and Email MIME Type
        if (!user.phoneNo.isNullOrEmpty())
            ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(Data.CONTENT_URI))
                    .withValueBackReference(Data.RAW_CONTACT_ID, 0)
                    .withValue(Data.MIMETYPE, MIMETYPE_MESSAGE)
                    .withValue(Data.DATA1, user.phoneNo)
                    .withValue(Data.DATA2, "Message")
                    .withValue(Data.DATA3, "Send a Message")
                    .build())

        if (!user.email.isNullOrEmpty())
            ops.add(ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(Data.CONTENT_URI))
                    .withValueBackReference(Data.RAW_CONTACT_ID, 0)
                    .withValue(Data.MIMETYPE, MIMETYPE_EMAIL)
                    .withValue(Data.DATA1, user.email)
                    .withValue(Data.DATA2, "Email")
                    .withValue(Data.DATA3, "Send an Email")
                    .build())
        try {
            Log.d("voice", "Add Phone Number: " + user.phoneNo
                    + " id = " + user.id)
            resolver.applyBatch(ContactsContract.AUTHORITY, ops)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

   private fun addCallerIsSyncAdapterParameter(uri: Uri): Uri {
        return uri.buildUpon()
                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
                .build()
   }

More points to add are that I tried that on Emulator (pixel 3a with A-12) with exact information but duplication didn't happen on it.

If feel like I am missing some thing in the code but couldn't figure out what.

Any help is appreciated.

0 Answers
Related