关于Android中获取短信息会话(threads)表中的信息

最近因为项目的需要,需要处理android手机中的短信,在PC端读取手机上的短信信息。那么首先需要得到手机上的会话信息进行概要显示。

网上关于如何获取会话信息的文章不少,我也是以它们为参考。但是在测试中发现一些问题,以及处理的方法,记录如下:

一、刚开始根据网上的文章,使用sql注释的方式直接操作threads表。
参考文章地址:
http://blog.csdn.net/vennl/article/details/7079135
http://www.cnblogs.com/GnagWang/archive/2011/01/06/1929075.html

使用的代码片段:

String SMS_URI_ALL = "content://sms/";

cursor = cr.query(Uri.parse(SMS_URI_ALL),
        new String[]{"* from threads order by date desc--"}, null, null, null);

使用这段代码,开始视乎一切正常。在很多机器上测试也OK。但是在小米note3上会抛出异常:
E/AndroidRuntime(26724): android.database.sqlite.SQLiteException: near “FROM”: syntax error (code 1): , while compiling:
SELECT FROM sms
WHERE ((thread_id IN (select _id from threads where private_addr_ids is NULL AND sp_type=0)) AND (deleted=0)) ORDER BY date DESC

看异常提示发现 FROM后面的*号不见了。暂时还不知什么原因,或者是红米做了什么限制。

二、这时开始换第二种方法.
参考文章:
http://www.tuicool.com/articles/fyeEVb

private static final String[] PROJECTION = new String[]{
        //cursor 查询 需要_id
        "sms.thread_id AS _id",
        "sms.body AS snippet",
        "groups.msg_count AS msg_count",
        "sms.address AS address",
        "sms.date AS date"
    };

    //查询短信数据
    private void startQuery() {
        /**
         * 查询会话数据
         * token Sql id 查询结果的唯一标识  _ID 
         * cookie  用来传递数据  通常VIEW
         * uri  指定查询数据的地址
         * projection   相当于SQL查询中 select 中的字段  
         * selection    相当于SQL查询中 where id = ? 
         * selectionArgs ?
         * orderBy      排序
         */
        Uri uri = Uri.parse("content://sms/conversations/");
        queryHandler.startQuery(0, null, uri, PROJECTION, null, null, " date DESC");
    }

但是使用这段代码会有错误提示:
no such column: sms.thread_id (code 1): , while compiling:

SELECT sms.thread_id AS _id, sms.body AS snippet, groups.msg_count AS msg_count, sms.address AS address, sms.date AS date

FROM
(SELECT thread_id AS tid, date * 1000 AS normalized_date, NULL AS error_code, ct_t, recipient_cc_ids, msg_box, NULL AS reply_path_present, v, sub, rr, NULL AS status, retr_txt_cs, ct_l, ct_cls, NULL AS dest_port, phone_id, NULL AS subject, NULL AS format_data, _id, m_size, NULL AS type, exp, sub_cs, NULL AS address, st, NULL AS person, tr_id, read, resp_st, date, NULL AS body, m_id, date_sent, recipient_bcc_ids, NULL AS sms_pdu, pri, NULL AS expiry, m_type, thread_id, read_status, d_rpt, locked, NULL AS service_date, NULL AS priority, resp_txt, rpt_a, retr_st, m_cls, NULL AS service_center
FROM pdu_restricted
WHERE ((msg_box != 3 AND (m_type = 128 OR m_type = 132 OR m_type = 160 OR m_type = 161 OR m_type = 130)))
GROUP BY thread_id
HAVING date = MAX(date)
UNION
SELECT thread_id AS tid, date * 1 AS normalized_date, error_code, NULL AS ct_t, recipient_cc_ids, NULL AS msg_box, reply_path_present, NULL AS v, NULL AS sub, NULL AS rr, status, NULL AS retr_txt_cs, NULL AS ct_l, NULL AS ct_cls, dest_port, phone_id, subject, format_data, _id, NULL AS m_size, type, NULL AS exp, NULL AS sub_cs, address, NULL AS st, person, NULL AS tr_id, read, NULL AS resp_st, date, body, NULL AS m_id, date_sent, recipient_bcc_ids, sms_pdu, NULL AS pri, expiry, NULL AS m_type, thread_id, NULL AS read_status, NULL AS d_rpt, locked, service_date, priority, NULL AS resp_txt, NULL AS rpt_a, NULL AS retr_st, NULL AS m_cls, service_center
FROM sms_restricted
WHERE ((type != 3))
GROUP BY thread_id
HAVING date = MAX(date))
GROUP BY tid
HAVING normalized_date = MAX(normalized_date)
ORDER BY date DESC

我们从提示中也能看出android是如何读取短信数据库的。

根据错误提示,修改代码如下:

String[] PROJECTION = new String[]{
        "thread_id"
};

Uri uri = Uri.parse( "content://mms-sms/conversations" );
cursor = cr.query( uri, PROJECTION , null ,null, "date DESC" );

然后一切似乎都OK, 不过后来发现在mate 9 和部分moto机器上读不出会话信息。

三、终极解决方案,直接找源码
直接参考android中关于这部分的源码实现。
https://github.com/android/platform_packages_apps_mms

使用的代码片段如下:

Uri sAllThreadsUri =
        Threads.CONTENT_URI.buildUpon().appendQueryParameter("simple", "true").build();

String[] ALL_THREADS_PROJECTION = {
        Threads._ID, Threads.DATE, Threads.MESSAGE_COUNT, Threads.RECIPIENT_IDS,
        Threads.SNIPPET, Threads.SNIPPET_CHARSET, Threads.READ, Threads.ERROR,
        Threads.HAS_ATTACHMENT
};

cursor = cr.query( sAllThreadsUri, ALL_THREADS_PROJECTION , null ,null, "date DESC" );

和第二种方法的区别是多了参数simple=true

这种方式在现在手头有的机型中测试正常。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞天红猪侠001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值