联系人:如何知道我可以将其转移到的帐户?

问题描述

我只想向用户显示他可以将其联系人转移到的帐户。

我可以从AccountsManager获取所有帐户,但是 并非我收到的所有帐户都可以接受联系人(例如WhatsApp ..)

要获取我正在使用此代码的所有帐户:

Account[] accounts = AccountManager.get(context).getAccounts();

要将所有联系人转移到我正在使用此代码的帐户中:

ArrayList<ContentProviderOperation> contact = new ArrayList<>();

contact.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI);
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME,accountName);
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE,accountType);
.build());

    contact.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)             .withValueBackReference(ContactsContract.RawContacts.Data.RAW_CONTACT_ID,0)
.withValue(ContactsContract.RawContacts.Data.MIMETYPE,ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,firstName)               .withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,lastName)
.build());

ContentProviderResult[] results = AppContext.get().getContentResolver().applyBatch(ContactsContract.AUTHORITY,contact);

是否有办法知道该帐户是否可以接受联系人,并且可以为用户过滤帐户列表?

感谢您的帮助:)

解决方法

同步联系人的帐户必须声明SyncAdapter,并具有某些属性,例如,SyncAdapter是否旨在同步联系人或其他数据(例如电子邮件),以及SyncAdapter是只读的,或支持将新内容上传到服务器(supportsUploading)。

要跳过所有根本不支持联系人或支持联系人但只读的帐户(例如Viber和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 a SyncAdapter that supports contacts: " + sync.accountType);
        if (sync.supportsUploading()) {
            Log.d(TAG,"found a 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);
            }
        }
    }
}

可以随意探索SyncAdapterType中的其他好东西,例如isUserVisible属性,也可能会有所帮助。

更新

从帐户类型获取应用名称很麻烦,因为并非所有帐户/同步适配器都链接到某些具有用户友好名称的用户可见应用。

但是,我相信可以通过从AccountManager获取AuthenticatorTypes的列表来做到这一点,就像这样:

AuthenticatorDescription[] ads = AccountManager.get(this).getAuthenticatorTypes();

然后,您需要遍历AuthenticatorDescriptions并将其类型与您从上述代码中获得的帐户类型进行匹配。

找到匹配项后,您可以从 AuthenticatorDescription,然后使用它来获取应用名称:

PackageManager pm = getPackageManager();
String appName = (String) pm.getApplicationLabel(pm.getApplicationInfo(packageName,PackageManager.GET_META_DATA));

不能保证此方法适用于所有应用程序,因为并非所有应用程序都将实现身份验证器。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...