我的 AccountManager 帐户没有联系人
No contacts for my AccountManager account
我目前正在做一个项目,我想在其中访问手机联系人,所以我已经成功地创建了 accountmanager
帐户,并且还能够执行 Syncadapter
操作。我可以看到我的帐户是在手机 settings->Accounts
中创建的。但是,当我尝试使用以下代码获取我帐户的所有联系人时,它不起作用。它显示了除我的应用程序帐户联系人之外的所有应用程序(google.com 和 WhatsApp.com)联系人。
Cursor cursor = getContext().getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI,
new String[]{ContactsContract.RawContacts.DIRTY, ContactsContract.RawContacts.ACCOUNT_TYPE},
null,
null,
null);
if (cursor != null && cursor.getCount() >0) {
cursor.moveToFirst();
while(!cursor.isAfterLast()) {
Log.d("Dirty",cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts.DIRTY)));
Log.d("ACCountType",cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_TYPE)));
cursor.moveToNext();
}
cursor.close();
}
我不明白的是,我是否需要代表我的帐户创建 ContentProvider
并将所有联系人插入回 Contactsprovider
?
不确定您是否完全理解 ContactsProvider 的工作原理。
有几件事你应该知道:
- 每个 RawContact 都被唯一分配给一个特定的帐户,它不能属于多个帐户(因此您的应用通常无法同步现有的联系人,因为他们已经有一个帐户)。
- 所有应用对所有联系人都有相同的视图,特别是所有应用都可以查看和修改所有联系人(前提是它们有权限),尽管该规则有一些例外。
当您将联系人同步到您的帐户时,您必须指定您的帐户,如 ContactsContract.RawContacts
所示
ContentValues values = new ContentValues();
values.put(RawContacts.ACCOUNT_TYPE, accountType);
values.put(RawContacts.ACCOUNT_NAME, accountName);
Uri rawContactUri = getContentResolver().insert(RawContacts.CONTENT_URI, values);
long rawContactId = ContentUris.parseId(rawContactUri);
当您读取联系人时,您将获得所有客户的联系人,除非您指定 Uri 查询参数或选择:
Uri rawContactUri = RawContacts.CONTENT_URI.buildUpon()
.appendQueryParameter(RawContacts.ACCOUNT_NAME, accountName)
.appendQueryParameter(RawContacts.ACCOUNT_TYPE, accountType)
.build();
Cursor c1 = getContentResolver().query(rawContactUri,
RawContacts.STARRED + "<>0", null, null, null)
本次查询returns指定账号所有已加星标的联系人。
如果您的代码作为同步适配器运行,您还必须添加 Uri 查询参数CALLER_IS_SYNC_ADAPTER
,否则多次操作可能会得到不同的结果。
我目前正在做一个项目,我想在其中访问手机联系人,所以我已经成功地创建了 accountmanager
帐户,并且还能够执行 Syncadapter
操作。我可以看到我的帐户是在手机 settings->Accounts
中创建的。但是,当我尝试使用以下代码获取我帐户的所有联系人时,它不起作用。它显示了除我的应用程序帐户联系人之外的所有应用程序(google.com 和 WhatsApp.com)联系人。
Cursor cursor = getContext().getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI,
new String[]{ContactsContract.RawContacts.DIRTY, ContactsContract.RawContacts.ACCOUNT_TYPE},
null,
null,
null);
if (cursor != null && cursor.getCount() >0) {
cursor.moveToFirst();
while(!cursor.isAfterLast()) {
Log.d("Dirty",cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts.DIRTY)));
Log.d("ACCountType",cursor.getString(cursor.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_TYPE)));
cursor.moveToNext();
}
cursor.close();
}
我不明白的是,我是否需要代表我的帐户创建 ContentProvider
并将所有联系人插入回 Contactsprovider
?
不确定您是否完全理解 ContactsProvider 的工作原理。
有几件事你应该知道:
- 每个 RawContact 都被唯一分配给一个特定的帐户,它不能属于多个帐户(因此您的应用通常无法同步现有的联系人,因为他们已经有一个帐户)。
- 所有应用对所有联系人都有相同的视图,特别是所有应用都可以查看和修改所有联系人(前提是它们有权限),尽管该规则有一些例外。
当您将联系人同步到您的帐户时,您必须指定您的帐户,如 ContactsContract.RawContacts
所示ContentValues values = new ContentValues(); values.put(RawContacts.ACCOUNT_TYPE, accountType); values.put(RawContacts.ACCOUNT_NAME, accountName); Uri rawContactUri = getContentResolver().insert(RawContacts.CONTENT_URI, values); long rawContactId = ContentUris.parseId(rawContactUri);
当您读取联系人时,您将获得所有客户的联系人,除非您指定 Uri 查询参数或选择:
Uri rawContactUri = RawContacts.CONTENT_URI.buildUpon() .appendQueryParameter(RawContacts.ACCOUNT_NAME, accountName) .appendQueryParameter(RawContacts.ACCOUNT_TYPE, accountType) .build(); Cursor c1 = getContentResolver().query(rawContactUri, RawContacts.STARRED + "<>0", null, null, null)
本次查询returns指定账号所有已加星标的联系人。
如果您的代码作为同步适配器运行,您还必须添加 Uri 查询参数
CALLER_IS_SYNC_ADAPTER
,否则多次操作可能会得到不同的结果。