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

时间:2017-01-05 21:31:16

标签: java android android-contentresolver contactscontract

Bounty Award - 赏金将从仅使用Telephony.Sms.Inbox.PERSON表格填充到已填充的Contact值到关联的ContractsContact的答案。

我正在申请中以标准方式阅读短信:

    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文档声明:

  

键入:INTEGER(对内容中的项目的引用:// contacts / people)

我尝试在ContactsContract个id字段中查找到id的映射但未成功(但并不奇怪?),所以我不得不使用弃用的API来解析查询需要快速完成。

此类查询包括搜索特定联系人的消息,我只有该名称。联系人可能有多个号码,这些号码的格式可能不正确,可能与Telephony.Sms.Inbox.ADDRESS条目匹配.....

使用Telephony.Sms.Inbox.ADDRESSworkaroundContactsContract.PhoneLookup从数字到联系人不是世界末日,但我仍然觉得我必须遗漏某些东西此处

以下是我用来获取“Joe Bloggs”消息的过程。

1)查询ContactsContract表以确认设备上存在Joe Bloggs名称的联系人 - 或者如果联系人实际列为'Joe 博客,则获得近似匹配”。

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 优化解决方案来迭代整个消息表。

提前致谢。

3 个答案:

答案 0 :(得分:4)

我不会使用Telephony.Sms.Inbox.PERSON字段,如果我是你,肯定不会查询弃用的People apis。 People apis已经被弃用了很长时间,你不能指望我们那里的所有设备都能正常支持它。

您需要了解的第一件事是短信和联系人之间没有一对一的链接。 短信可以来自非联系电话号码,单个联系人,多个联系人,联系人和非联系人的混合,字母数字ID,甚至其他更罕见的选项。

接下来,您应该仔细阅读股票代码以及它如何处理您可以从SMS集合中获得的正确调用的“收件人ID”,这里有一个名为canonical-addresses(或canonical-address)的集合用作电话号码(或以逗号分隔的电话列表)与收件人ID之间的映射。 代码在启动时执行单个查询以将整个表缓存在内存中,然后使用它在手机和收件人ID之间进行映射。

这是mapping class

答案 1 :(得分:1)

  

为什么相对较新的Telephony API会使用弃用表而不是ContactsContract?

你指的不是新的。在Telephony.java中,您会发现它依赖于现有的content://sms提供商:

    public static final class Inbox implements BaseColumns, TextBasedSmsColumns {
        /**
         * The {@code content://} style URL for this table.
         */
        public static final Uri CONTENT_URI = Uri.parse("content://sms/inbox");

已经there in Donut(可能之前,但我没有检查过。)

Kitkat is the ability to change the SMS app中有什么新内容。

答案 2 :(得分:-1)

我不理解您的关注,但我正在开展类似的项目,这里是基本代码,以及用于获取和显示消息的基本,重要的列:

ContentResolver contentResolver = getContentResolver();
final String[] projection = new String[]{"*"};

Cursor SMSL = contentResolver.query(Telephony.Sms.CONTENT_URI, projection, null, null, "date ASC");
int msgscount = SMSL.getCount();

if (msgscount>0) {
msgs = new String[SMSL.getCount()][msgs_column_count];
    int i = 0;
    while (SMSL.moveToNext()) {
        progress.setProgress(i);

        msgs[i][0] = SMSL.getString(SMSL.getColumnIndex("address"));
        msgs[i][1] = SMSL.getString(SMSL.getColumnIndex("date_sent"));
        msgs[i][2] = SMSL.getString(SMSL.getColumnIndex("date"));
        msgs[i][3] = SMSL.getString(SMSL.getColumnIndex("type"));
        msgs[i][4] = SMSL.getString(SMSL.getColumnIndex("body"));
        msgs[i][5] = SMSL.getString(SMSL.getColumnIndex("read"));
        if (SMSL.getString(SMSL.getColumnIndex("service_center")) != null){
            msgs[i][6] = SMSL.getString(SMSL.getColumnIndex("service_center"));
        }else{
            msgs[i][6] = "";
        }
                    i++;
    }
    SMSL.close();
}else{
     msgs = new String[0][0];
     Toast.makeText(getApplicationContext(),"No messages found!",Toast.LENGTH_LONG).show();
}

如果您需要任何有关此消息或获取消息的帮助,请与我们联系。