java - Telephony.Sms.Inbox.PERSON 使用已弃用的 Contacts.People._ID

标签 java android android-contentresolver contactscontract

赏金 - 赏金将授予从填充的 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.ADDRESSContactsContract.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 之间进行映射。

这是 mapping class

关于java - Telephony.Sms.Inbox.PERSON 使用已弃用的 Contacts.People._ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41495044/

相关文章:

android - 具有褪色边缘的水平回收 View

Android:通过 content://URI 从第三方应用程序(例如 WhatsApp)获取图像位图

android - 仅显示一定数量的联系人

android - 内容观察者是观察者模式的实现吗?

Java <-> Scala 转换 - "value is not a member of"

java - 由于 handshake_failure,IOS 推送通知失败

android - 15dp 是否代表每个设备中相同的物理尺寸(例如屏幕上的 7 毫米)? (安卓)

java - 授予单一类权限

java - 如何使用apache csv读取excel的csv文件

android 相机错误 1001 - 那到底是什么?