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.ADDRESS
和workaround的ContactsContract.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
优化解决方案来迭代整个消息表。
提前致谢。
答案 0 :(得分:4)
我不会使用Telephony.Sms.Inbox.PERSON
字段,如果我是你,肯定不会查询弃用的People
apis。
People
apis已经被弃用了很长时间,你不能指望我们那里的所有设备都能正常支持它。
您需要了解的第一件事是短信和联系人之间没有一对一的链接。 短信可以来自非联系电话号码,单个联系人,多个联系人,联系人和非联系人的混合,字母数字ID,甚至其他更罕见的选项。
接下来,您应该仔细阅读股票代码以及它如何处理您可以从SMS集合中获得的正确调用的“收件人ID”,这里有一个名为canonical-addresses
(或canonical-address
)的集合用作电话号码(或以逗号分隔的电话列表)与收件人ID之间的映射。
代码在启动时执行单个查询以将整个表缓存在内存中,然后使用它在手机和收件人ID之间进行映射。
答案 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(可能之前,但我没有检查过。)
答案 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();
}
如果您需要任何有关此消息或获取消息的帮助,请与我们联系。