问题描述
我只想向用户显示他可以将其联系人转移到的帐户。
我可以从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));
不能保证此方法适用于所有应用程序,因为并非所有应用程序都将实现身份验证器。