基础总结篇之七:ContentProvider之读写短消息

古之成大事者,不惟有超世之才,亦有堅韌不拔之志。北宋.蘇軾《晁錯論》

我们的前辈中那些成就大事的人,不单单有过人的智慧和才能,也须有坚韧不拔的意志。试问没有坚韧的意志,如何写得出复杂的系统,如何创造出伟大的产品?作为程序员的我们,智慧和才能似乎不太欠缺,我们欠缺的也许是正是坚韧的意志,所以从今天起,锻炼自己的意志吧,在坚持理想的道路上,让这种意志给自己力量。

今天我们来讲一下如何利用ContentProvider读写短消息。

上次我们讲了如何通过ContentProvider机制读写联系人,通过读取联系人信息和添加联系人这两种方式对联系人进行操作,相信大家对ContentProvider的基本使用方法也有所了解了。在Android中ContentProvider应用场合还很多,读写短消息就是其中一个,今天我们就来探讨一下利用ContentProvider操作短消息的问题。

相对于联系人来说,短消息不是公开的,所以没有专门的API供我们调用,这就要求我们根据源代码进行分析研究,制定出一定的操作方案。

我们需要先找到短消息的数据源,打开/data/data/com.android.providers.telephony可以看到:


其中的mmssms.db就是短消息的数据源,朋友们可以导出一下这个文件,用专业工具软件查看一下表结构。为了方便大家理解,我简单介绍一下今天涉及到的两张表以及表中的常用字段:

如图所示,两张表分别是threads表和sms表,前者代表所有会话信息,每个会话代表和一个联系人之间短信的群组;后者代表短信的具体信息。在sms表中的thread_id指向了threads表中的_id,指定每条短信的会话id,以便对短信进行分组。下面介绍一下表中的每个字段的意义:

threads表:_id字段表示该会话id;date表示该会话最后一条短信的日期,一般用来对多个会话排序显示;message_count表示该会话所包含的短信数量;snippet表示该会话中最后一条短信的内容;read表示该会话是否已读(0:未读,1:已读),一般来说该会话中有了新短信但没查看时,该会话read变为未读状态,当查看过新短信后read就变为已读状态。

sms表:_id表示该短信的id;thread_id表示该短信所属的会话的id;date表示该短信的日期;read表示该短信是否已读;type表示该短信的类型,例如1表示接收类型,2表示发送类型,3表示草稿类型;body表示短信的内容。

下面我们会通过单元测试的方式演示一下读取会话信息和短信内容。在写代码之前,我们先初始化一些数据,具体过程是启动三个模拟器5554、5556、5558,让5554分别与5556和5558互发短信,如下:


我们看到5554这小子名叫Jack;5556名叫Lucy,可能认识有几天了,手机上存了她的号码;5558名叫Lisa,可能刚认识,还没来得及存号码。Jack这小子真狠啊,想同时泡两个妞,难道名字叫Jack的长得都很帅?下面是以上的两个会话信息:


可以看到,因为在联系人里存了Lucy,所以显示时并不再直接显示陌生的数字,而是其名字;括号内显示了该会话的短信数;下面文字显示了最后一条短信的内容和日期。

下面我们创建一个名为SMSTest的单元测试类,用于读取会话信息和短信内容,代码如下:

package com.scott.provider;

import java.text.SimpleDateFormat;

import android.content.ContentResolver;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;

public class SMSTest extends AndroidTestCase {
	
	private static final String TAG = "SMSTest";
	
	//会话
	private static final String CONVERSATIONS = "content://sms/conversations/";
	//查询联系人
	private static final String CONTACTS_LOOKUP = "content://com.android.contacts/phone_lookup/";
	//全部短信
	private static final String SMS_ALL   = "content://sms/";
	//收件箱
//	private static final String SMS_INBOX = "content://sms/inbox";
	//已发送
//	private static final String SMS_SENT  = "content://sms/sent";
	//草稿箱
//	private static final String SMS_DRAFT = "content://sms/draft";
	
	private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	/**
	 * 读取会话信息
	 */
	public void testReadConversation() {
		ContentResolver resolver = getContext().getContentResolver();
		Uri uri = Uri.parse(CONVERSATIONS);
		String[] projection = new String[]{"groups.group_thread_id AS group_id", "groups.msg_count AS msg_count",
						"groups.group_date AS last_date"
  • 2
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值