Search code examples
androidcontactscontactscontract

Selecting an account for saving contacts


I am making a phone book application.

I can see some of contacts has different ACCOUNT_TYPE_AND_DATA_SET (com.whatsapp, com.viber.voip, com.google, com.android.huawei.sim, com.android.huawei.phone etc).

Here is the question: how can I get the list of available accounts (Authorities) for saving contacts?


Solution

  • You can use the AccountManager service for that:

    Account[] accounts = AccountManager.get(this).getAccounts();
    for (Account account : accounts) {
       Log.d(TAG, account.type + " / " + account.name);
    }
    

    Note, requires the GET_ACCOUNTS permission, if you're targeting Android M and above, you'll alse need to ask the user for this permission via the Runtime Permissions model.

    UPDATE

    To skip all accounts that don't support contacts at all, or do support contacts but are read only (like Viber and Whatsapp):

    final SyncAdapterType[] syncs = ContentResolver.getSyncAdapterTypes();
    for (SyncAdapterType sync : syncs) {
        Log.d(TAG, "found SyncAdapter: " + sync.accountType);
        if (ContactsContract.AUTHORITY.equals(sync.authority)) {
            Log.d(TAG, "found SyncAdapter that supports contacts: " + sync.accountType);
            if (sync.supportsUploading()) {
                Log.d(TAG, "found SyncAdapter that supports contacts and is not read-only: " + sync.accountType);
                // we'll now get a list of all accounts under that accountType:
                Account[] accounts = AccountManager.get(this).getAccountsByType(sync.accountType);
                for (Account account : accounts) {
                   Log.d(TAG, account.type + " / " + account.name);
                }
            }
        }
    }
    

    Feel free to explore the other good stuff in SyncAdapterType like isUserVisible that you might wanna check as well.