赏金 - 赏金将授予从填充的 Telephony.Sms.Inbox.PERSON
值到关联的 Contact< 的答案
仅使用 ContractsContact
表。
我在我的应用程序中以标准方式阅读 SMS 消息:
final String[] projection = {Telephony.Sms.Inbox.BODY,
Telephony.Sms.Inbox.ADDRESS,
Telephony.Sms.Inbox.READ,
Telephony.Sms.Inbox.DATE,
Telephony.Sms.Inbox.PERSON};
final Cursor cursor = ctx.getContentResolver().query(Telephony.Sms.Inbox.CONTENT_URI,
projection, null, null, Telephony.Sms.Inbox.DEFAULT_SORT_ORDER);
填充后,从索引 Telephony.Sms.Inbox.PERSON
返回的 ID 与已弃用的 Contacts.People._ID
的 ID 相关,可用于通过以下方式查询更多联系方式:
final String[] projection = {Contacts.People.DISPLAY_NAME};
final String[] selectionArgs = {contactId};
final Cursor cursor = ctx.getContentResolver().query(Contacts.People.CONTENT_URI,
projection, Contacts.People._ID + " = ?", selectionArgs, null);
为什么相对较新的 Telephony API使用 deprecated tables , 而不是 ContactsContract ?
Telephony.Sms.Inbox.PERSON文档状态:
Type: INTEGER (reference to item in content://contacts/people)
我尝试在任何 ContactsContract
id 字段中找到到 id 的映射,但没有成功(但并非意料之中?),所以我不得不使用已弃用的 API 来解决我需要快速执行的查询。
此类查询包括搜索特定联系人的消息,我只有名字。联系人可能有多个号码,这些号码的格式可能不正确,无法匹配 Telephony.Sms.Inbox.ADDRESS
条目......
workaround使用 Telephony.Sms.Inbox.ADDRESS
和 ContactsContract.PhoneLookup从电话号码到联系方式并不是世界末日,但我仍然觉得我一定在这里遗漏了什么?
这是我用来获取“Joe Bloggs”消息的过程。
1) 查询 ContactsContract
表以确认设备上存在名为 Joe Bloggs 的联系人 - 或者如果该联系人实际列为“Joe Blogs<”则获得接近匹配/strong>'.
2) 使用已确认的姓名,我查询已弃用的 Contact.People
表以通过以下方式获取联系人的所有关联 ID:
final String selection = Contacts.People.DISPLAY_NAME + " LIKE ?";
final String[] projection = {Contacts.People.DISPLAY_NAME,
Contacts.People._ID};
final String[] selectionArgs = {contactName};
final Cursor cursor = ctx.getContentResolver().query(Contacts.People.CONTENT_URI,
projection, selection, selectionArgs, null);
3) 使用已弃用的联系人 ID 列表,我这样查询消息表:
final String[] referredArgs = new String[contactIdArray.size()];
for (int i = 0; i < contactIdArray.size(); i++) {
referredArgs[i] = contactIdArray.get(i);
}
final String referredSelection = Telephony.Sms.Inbox.PERSON + " IN "
+ "(" + TextUtils.join(",", referredArgs) + ")";
final String[] projection = {Telephony.Sms.Inbox.BODY,
Telephony.Sms.Inbox.ADDRESS,
Telephony.Sms.Inbox.READ,
Telephony.Sms.Inbox.DATE,
Telephony.Sms.Inbox.PERSON};
final Cursor cursor = ctx.getContentResolver().query(Telephony.Sms.Inbox.CONTENT_URI,
projection, referredSelection, null, Telephony.Sms.Inbox.DEFAULT_SORT_ORDER);
我希望有人会告诉我我正在绕过这里的房子,并且有一个使用当前 API 的更明显的解决方案。 我不考虑使用 ContactsContract.PhoneLookup
优化的解决方案迭代整个消息表。
提前致谢。
最佳答案
如果我是你,我不会使用 Telephony.Sms.Inbox.PERSON
字段,也绝对不会查询已弃用的 People
api。
People
api 已经弃用了很长时间,您不能指望我们那里的所有设备都能正确支持它了。
首先您需要了解的是,短信和联系人之间没有一对一的联系。 SMS 可以来自非联系人电话号码、单个联系人、多个联系人、联系人和非联系人的混合、字母数字 ID,甚至其他更罕见的选项。
接下来,您应该仔细阅读股票代码,以及它如何处理您可以从 SMS 集合中获得的正确调用的“收件人 ID”,有一个名为 canonical-addresses
的集合(或 canonical-address
) 用作电话号码(或逗号分隔的电话列表)和收件人 ID 之间的映射。
该代码在启动时执行单个查询以将整个表缓存在内存中,然后使用它在电话和收件人 ID 之间进行映射。
关于java - Telephony.Sms.Inbox.PERSON 使用已弃用的 Contacts.People._ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41495044/