短信模块(一)
来源:互联网 发布:world of tank mac 编辑:程序博客网 时间:2023/11/29 02:45
最近在学习短信模块,写点东西以免以后又忘记了。
在看这个模块前,个人认为先了解一下短信的数据存储会容易一些。首先,短信信息肯定是存储在数据库中,那么这些数据库中都有些什么表?存储的是什么东西呢?我们可以把手机连上电脑,打开eclipse,用DDMS模式查看一下手机里的文件。如下:
短信模块的数据库就是图中的mmssms.db文件,点击右上角的导出功能,把db文件导到电脑中,用Navicat for SQLite软件查看这个db文件。这个db数据库文件中包含的表如下:
其中,sms是存放短信的表,pdu和part是存放彩信的表,canonical_addresses是存放手机号码的表,threads是存放会话信息的表,pending_msgs用于存储待发送或下载的短信与彩信的表(有待证实),使用pdu中的触发器进行插入和删除。raw表用于存储接收中的长短信或分段彩信通知。drm用于彩信权限管理。words开头的表存储了短彩信中的单词,用于搜索时使用。attachments、rate、sr_pending表作用未知。android_metadata表存储的是语言信息,就一条记录。
重点看一下sms,pdu,part,threads四个表。(后面补上后三个表)
下面是sms表,表中的属性是:
_id: 主键,唯一
thread_id: 会话id(和thread表关联),这个会话是指:我跟A互发短信,这是一个会话;我跟B互发短信,这是一个会话;我和A,B群发短信,这是另一个会话。会话包含了所
有的短信信息(多条),我们手机短信列表里的每一项就是一个会话。如下图中的,三个thread_id都为1,表明这三个消息都是属于同一个会话的,两个
thread_id为4,这两个是同属于一个会话。
address: 地址,也就是收件人的手机号码。如下图,有个加号的+8618521564884是别人发过来的短信,没有加号的是从本机发送过去的短信。Null的是编辑的草稿信息
person: 联系人地址,(跟通讯录有关)
data: 发送短信时间
data_sent: 接受短信时间
protecd: 协议,分为: 0 SMS_RPOTO, 1 MMS_PROTO
read: 是否阅读 0未读, 1已读
status: 状态 -1接收,0 complete, 64 pending, 128 failed
type: ALL=0; 表示所有短信
INBOX=1; 表示这个短信属于收件箱
SENT=2; 表示短信已经发送成功
DRAFT=3; 表示短信属于草稿箱
OUTBOX=4; 表示短信属于发件箱(正在发送)
FAILED=5; 表示发送失败
QUEUED=6; 表示短信在待发送队列中
这里的type 很重要,一个信息的type在发送或者接收的整个过程中会不断的被改变,以区分这个信息处于什么阶段。
body: 短信内容
service_center: 短信服务中心号码编号
subject: 短信的主题
reply_path_present: TP-Reply-Path
locked: 此条短信是否已由用户锁定,0-未锁定,1-已锁定
send: 用于指明该消息是否已被用户看到(非阅读,点开会话列表即可,不用打开会话),仅对收到的消息有用
下面是thread表,表中的属性为:
_id: 主键,唯一
date_sent: 会话最新更新时间
message_count: 当前会话所包含的消息数量
recipient_ids: 接收者(canonical_addresses表的id)列表,所有接收者以空格隔开
snippet: 最新更新的消息的内容(彩信为主题,短信为正文)
read: 是否有未读信息:0-未读,1-已读
type: 会话类型,0-普通会话(只有一个接收者),1-广播会话(多个接收者)
has_attachment: 是否有附件:0-无,1-有
知道了短信数据库中的表结构,那么怎样操作数据库呢?
我们先看一下数据库的创建是在什么地方,找到
packages/providers/TelephonyProvider/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java
这个MmsSmsDatabaseHelper继承了SQLiteOpenHelper类,用来创建数据库和数据表。其中创建sms表的代码如下:
private void createSmsTables(SQLiteDatabase db) { // N.B.: Whenever the columns here are changed, the columns in // {@ref MmsSmsProvider} must be changed to match. db.execSQL("CREATE TABLE sms (" + "_id INTEGER PRIMARY KEY," + "thread_id INTEGER," + "address TEXT," + /// M: Code analyze 016, unknown, new column in sms table. "m_size INTEGER," + "person INTEGER," + "date INTEGER," + "date_sent INTEGER DEFAULT 0," + "protocol INTEGER," + "read INTEGER DEFAULT 0," + "status INTEGER DEFAULT -1," + // a TP-Status value // or -1 if it // status hasn't // been received "type INTEGER," + "reply_path_present INTEGER," + "subject TEXT," + "body TEXT," + "service_center TEXT," + "locked INTEGER DEFAULT 0," + /// M: Code analyze 015, new feature, support for gemini. "sim_id INTEGER DEFAULT -1," + "error_code INTEGER DEFAULT 0," + "seen INTEGER DEFAULT 0," + /// M: Add for ip message "ipmsg_id INTEGER DEFAULT 0," + /// M: for ct new feature of concatenated sms @{ // ref_id: the unique id for specific contatenated sms // total_len: the total parts of concatenated sms // rec_len: the number of parts that have received "ref_id INTEGER," + "total_len INTEGER," + "rec_len INTEGER" + /// M: @} ");"); /** * This table is used by the SMS dispatcher to hold * incomplete partial messages until all the parts arrive. */ db.execSQL("CREATE TABLE raw (" + "_id INTEGER PRIMARY KEY," + "date INTEGER," + "reference_number INTEGER," + // one per full message "count INTEGER," + // the number of parts "sequence INTEGER," + // the part number of this message "destination_port INTEGER," + "address TEXT," + /// M: Code analyze 015, new feature, support for gemini. "sim_id INTEGER DEFAULT 0," + "pdu TEXT," + /// M: for ct new feature of concatenated sms @{ "recv_time INTEGER," + "upload_flag INTEGER" + /// M: @} ");"); // the raw PDU for this part db.execSQL("CREATE TABLE attachments (" + "sms_id INTEGER," + "content_url TEXT," + "offset INTEGER);"); /** * This table is used by the SMS dispatcher to hold pending * delivery status report intents. */ db.execSQL("CREATE TABLE sr_pending (" + "reference_number INTEGER," + "action TEXT," + "data TEXT);"); }
既然找到了创建数据库的相关类,那么我们可以看看它在哪里被调用的。这里可以追溯到SmsProvider。如下:
@Override public Cursor query(Uri url, String[] projectionIn, String selection, String[] selectionArgs, String sort) { MmsLog.d(TAG, "query begin, uri = " + url + ", selection = " + selection); SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); // Generate the body of the query. int match = sURLMatcher.match(url); switch (match) { case SMS_ALL: constructQueryForBox(qb, Sms.MESSAGE_TYPE_ALL); break; case SMS_UNDELIVERED: constructQueryForUndelivered(qb); break; case SMS_FAILED: constructQueryForBox(qb, Sms.MESSAGE_TYPE_FAILED); break; case SMS_QUEUED: constructQueryForBox(qb, Sms.MESSAGE_TYPE_QUEUED); break; case SMS_INBOX: constructQueryForBox(qb, Sms.MESSAGE_TYPE_INBOX); break; case SMS_SENT: constructQueryForBox(qb, Sms.MESSAGE_TYPE_SENT); break; case SMS_DRAFT: constructQueryForBox(qb, Sms.MESSAGE_TYPE_DRAFT); break; case SMS_OUTBOX: constructQueryForBox(qb, Sms.MESSAGE_TYPE_OUTBOX); break; case SMS_ALL_ID: qb.setTables(TABLE_SMS); qb.appendWhere("(_id = " + url.getPathSegments().get(0) + ")"); break; 。。。。 }}
可以看到,SmsProvider是通过解析uri来决定查询什么类型的短信数据,如:收件箱,发件箱,草稿箱等。
ContentProvider(内容提供器)用来管理和共享数据库。对于
ContentProvider,这里有一篇文章可以了解一下ContentProvider,ContentResolver,uri三者之间的关系。
sms中有关的uri如下: 对应以上 SmsProvider中的Sms.MESSAGE_TYPE_FAILED,Sms.MESSAGE_TYPE_QUEUED,Sms.MESSAGE_TYPE_DRAFT等等。
public final static String SMS_URI_ALL = "content://sms/"; //0 表示所有短信 public final static String SMS_URI_INBOX = "content://sms/inbox";//1 收件箱public final static String SMS_URI_SEND = "content://sms/sent";//2 已发送public final static String SMS_URI_DRAFT = "content://sms/draft";//3 草稿public final static String SMS_URI_OUTBOX = "content://sms/outbox";//4 发件箱public final static String SMS_URI_FAILED = "content://sms/failed";//5 发送失败public final static String SMS_URI_QUEUED = "content://sms/queued";//6 待发送列表比如使用了ContentProvider来查询发件箱的所有信息时,需要提供的地址就是:
content://sms/inbox
短信模块的ContentProvider提供了三个子类:SmsProvider、MmsProvider、MmsSmsProvider,以及一个辅助类Telephony。其中,SmsProvider用于短信相关数据的存取,MmsProvider用于彩信相关数据的存取,MmsSmsProvider则用于短彩信通用数据的存取,如会话信息、接收者、草稿(公共属性)等。Telephony则提供了一系列Uri、常量字符串列名数组、方法以便用户使用这三个ContentProvider。Telephony里面定义了很多的内部类:sms,mms....而 sms,mms里面又定义了Outbox,inbox,draft等内部类。分别提供对短彩信数据库的各种操作。详情参考源码。
- 短信模块(一)
- MTK短信模块分析(一)
- 短信模块开发 tpdu格式(一)
- 短信模块开发 tpdu格式(一)
- 短信模块开发 tpdu格式(一)
- 免费短信控件(支持Wavecom模块)
- 短信模块开发 tpdu格式(二)
- 短信模块开发 tpdu格式(三)
- MC8630模块(EVDO)成功发送短信
- 短信模块开发 tpdu格式(二)
- 短信数据库分析(一)
- 中文短信编码(一)
- 短信(一)
- Android 拦截短信并且删除短信(一)
- cmpp短信平台模块
- 短信模块开发
- MTK短信模块研究
- GSM模块发送短信
- Java---Socket编程基础理论
- poj 2524 Ubiquitous Religions(无所不在的宗教)
- Sublime Text3中字体设置
- LeetCode——Valid Number
- Eclipse 改变背景色
- 短信模块(一)
- java项目中引入Junit测试库
- 问题集一:view.setLayoutParams(layoutParams)不起作用
- n个骰子各点数和出现的概率--动态规划
- android Wifi热点
- C语言socket编程---udp通信及广播
- java反射获得类的字段和值
- 《Java TCP/IP Socket编程》读书笔记(1)
- 在使用 ST_Geometry 空间索引时优化 Oracle 查询性能和存储