Save Contacts as "Phone contact"
Asked Answered
A

2

1

Is there way to programmatically adds the contact to the internal phone contacts book as a "phone contact"?

I've tried:

list.add(ContentProviderOperation
                .newInsert(ContactsContract.RawContacts.CONTENT_URI)
                .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
                .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
                .build());

with this parameters contact successfully saves to the phone, but in case i set up filter to "display phone contacts only" - created contact not appears. btw, i've read that contacts with null type can be loses drying accounts synchronization (haven't remember the full case)

then i tried to retrieve ACCOUNT_TYPE and ACCOUNT_NAME from existing phone contact and gets Phone and Local Phone Account strings, but when i tried to save contact with same parameters:

list.add(ContentProviderOperation
                .newInsert(ContactsContract.RawContacts.CONTENT_URI)
                .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, "Phone")
                .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, "Local Phone Account")
                .build());

the result was the same to the first case with null type.

is there any constants (or it should be another way) to save data like "phone contact"?

Algonkian answered 28/6, 2017 at 10:2 Comment(0)
C
6

The "phone only" account is not fully supported by plain Android, it's usually added (or unlocked) by device makers.

Here are the ones I know of, feel free to add more in case you find more.
The format is <maker>: ACCOUNT_TYPE, ACCOUNT_NAME

  1. samsung: "vnd.sec.contact.phone: "vnd.sec.contact.phone"
  2. htc: "com.htc.android.pcsc: "pcsc"
  3. sony: "com.sonyericsson.localcontacts: "Phone contacts"
  4. lge: "com.lge.sync: "Phone"
  5. lge (option 2): "com.lge.phone"
  6. t-mobile: "vnd.tmobileus.contact.phone: "MobileLife Contacts"
  7. huawei: "com.android.huawei.phone: "Phone"
  8. lenovo: "Local Phone Account: "Phone"
  9. xiaomi: "com.xiaomi"
  10. oppo: "com.oppo.contacts.device"
  11. xiaomi (option 2): "com.android.contacts.default"
  12. Honor : "com.android.hihonor.phone": "Phone"
Conyers answered 28/6, 2017 at 12:9 Comment(0)
H
0

In addition to a list of found values for various OEMs of account-type and account-name, in order to find them on your device, you can do the following:

Use this code for Android R (API 30) and above (and hopefully the OEM follows the rules in implementing it, as Google warned about here):

val localAccountName = ContactsContract.RawContacts.getLocalAccountName(applicationContext)
val localAccountType = ContactsContract.RawContacts.getLocalAccountType(applicationContext)
Log.d("AppLog", "localAccountType:$localAccountType localAccountName:$localAccountName ")

Or do these in case you don't trust them or you test on older Android version (in addition to the list that was talked about on the other answer):

  1. Delete all contacts in the address book.
  2. Run the snippet below and save the list to see what's default.
  3. Create a new contact and save it on the device storage using the built-in Contacts app of your device.
  4. Run the snippet again to see what's different

I guess it's possible to have less steps by having the code create the new contact and then query it and delete it, but this method should work well too. I'd appreciate it if anyone can update this answer with the alternative snippet.

The code:

manifest:

<uses-permission android:name="android.permission.READ_CONTACTS" />

MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...
    val permissionsResultLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
        thread {
            contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null)!!.use { contactCursor ->
                val accountTypeColIdx =
                        contactCursor.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_TYPE)
                val accountNameColIdx =
                        contactCursor.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_NAME)
                val accountTypes = HashSet<String>()
                Log.d("AppLog", "found accounts by query of contacts in address book:")
                while (contactCursor.moveToNext()) {
                    val accountType = contactCursor.getString(accountTypeColIdx)
                    if (!accountTypes.add(accountType))
                        continue
                    val accountName = contactCursor.getString(accountNameColIdx)
                    Log.d("AppLog", "accountName:$accountName accountType:$accountType")
                }
            }
        }
    }
    permissionsResultLauncher.launch(arrayOf(Manifest.permission.READ_CONTACTS, Manifest.permission.GET_ACCOUNTS))
}
Hitchhike answered 8/2 at 23:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.