为什么像Duo,whatsapp,Skype这样的应用程序在本机联系人的RawContact表中有条目



我正在使用ContactContractsAPI来获取RawContacts表中的条目

private void fetchRawContactEntries() {
String [] mProjectionColumns = new String [] {
RawContacts.CONTACT_ID, RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_TYPE, RawContacts.DISPLAY_NAME_PRIMARY
};
Cursor c = getContentResolver().query(RawContacts.CONTENT_URI, mProjectionColumns, null, null,
RawContacts.DISPLAY_NAME_PRIMARY + " ASC");
if(c != null) {
while(c.moveToNext()) {
long contactId = c.getLong(0);
String accountName = c.getString(1);
String accountType = c.getString(2);
String displayName = c.getString(3);
Log.d("Logs", contactId +  ", accountName:" + accountName + ", Display Name : " + displayName);
}
}
}

我观察到每个联系人在raw_contacts表中有多个条目。(Gmail,Duo等)

2019-05-28 19:21:15.483 5458-5458/com.example.kartikaysingh.cs d/logs: 2227, accountName:kartikayemail@gmail.com, 显示名称 : Abhay Y 2019-05-28 19:21:15.483 5458-5458/com.example.kartikaysingh.cs D/Logs: 2227, 帐户名称:WhatsApp, 显示名称 : Abhay Y 2019-05-28 19:21:15.483 5458-5458/com.example.kartikaysingh.cs D/Logs: 2227, 帐户名称:Duo, 显示名称 : Abhay Y 2019-05-28 19:21:15.483 5458-5458/com.example.kartikaysingh.cs D/Logs: 2227, 帐户名称:Duo, 显示名称 : Abhay Y 2019-05-28 19:21:15.483 5458-5458/com.example.kartikaysingh.cs D/Logs: 2140, accountName:kartik@gmail.com, 显示名称 : Abhayuday 2019-05-28 19:21:15.483 5458-5458/com.example.kartikaysingh.cs d/logs: 2140, 帐户名称:WhatsApp, 显示名称 : Abhayuday 2019-05-28 19:21:15.484 5458-5458/com.example.kartikaysingh.cs D/Logs: 2140, 帐户名称:Duo, 显示名称 : Abhayuday 2019-05-28 19:21:15.484 5458-5458/com.example.kartikaysingh.cs D/Logs: 2140, 帐户名称:Duo, 显示名称 : Abhayuday

事实上Duo在 RawContact 表中创建两个不同的条目。native contact应用如何区分这些条目。
我知道他们显示联系人表的条目,但是在修改他们raw_contact_id从Duo or Whatsapp or gmail中选择的数据时。 他们从哪里得到这些原始raw_contact_id

以下是我已经知道的事情:

  1. 无论联系人提供商处理的来源如何,重复条目的联系人 ID 都将相同。看看这个联系人聚合器
  2. 联系人表有一个列name_raw_contact_id,它给出了 RawContacts 表的相应_ID(但是我不确定这是否可以被视为 RawContacts 表中联系人的主要条目)。

下面给出了我想知道的事情列表:

  1. 我们可以从ContactsContract.Contact表中获取唯一的联系人,但为了使用联系人提供程序修改/删除数据值(如电话、电子邮件等),我们可以选择哪个raw_contact_id?或者我可以直接在ContactContract.Data表中修改。
  2. whatsapp如何检测联系人的添加/修改。据我所知,联系人提供商不提供新联系人添加_ID。他们是在每次应用程序启动后刷新联系人列表还是以相同的时间间隔刷新联系人列表?
  3. 如何获取联系人的原始来源(在我的情况下可能是gmail/native),并省略由Duo,skype,whatsapp等应用程序使用联系人提供商创建的副本。

如果有人帮助我理解这一点,那就太好了。随时推荐我可以询问这些问题的任何其他渠道

投影确实不正确。

联系人数据库分为三个主要表:

  1. Contacts- 每个条目代表一个联系人,并将一个或多个联系人组合在一起RawContacts
  2. RawContacts- 每个条目表示由某些SyncAdapter(例如Whatsapp,Google,Facebook,Viber)同步的联系人的数据,这将多个数据条目分组
  3. Data- 有关联系人、电子邮件、电话等的实际数据,每行都是属于单个RawContact的单个数据

Google Play上具有足够权限的每个应用程序都可以添加新联系人或新的RawContact,并将其聚合到现有联系人中,就像Whatsapp/Duo一样,这允许每个应用程序存储有关特定联系人的信息,例如Whatsapp ID,或任何其他对应用程序有用的信息。

你有一个错误的假设,认为有一个"主要"RawContact是重要的,而其他的都附加到它。 相反,代表单个联系人的 RawContacts 列表可以包含多个具有同等重要性的 Google RawContacts,或者根本没有 Google RawContacts,有一个区别可以帮助您选择要编辑的 RawContact,即应用程序创建的 RawContacts 是只读的还是可写的。

以下是循环访问设备上所有帐户的代码,并查看哪些帐户是只读的,哪些是可修改的(supportsUploading):

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);
}
}
}
}

探索SyncAdapterType中的其他好东西,比如isUserVisible,你也可以帮助你。

最新更新