android短信的数据库的Uri是不公开的, 读取起来时灰常不方便的, 这里做了下总结.
用adb指令将mmssms.db从/data/data/com.android.providers.telephony/databases中pull出来
经常使用到的表有
canonical_addresses, sms, threads三个表格
sms是存储着所有的短信, 主要的列有_id, thread_id, address, person, date, read, type, body
关于的sms的Uri有
发件箱 content://sms/outbox
收件箱 content://sms/inbox
草稿箱 content://sms/draft
conversations content://sms/conversations
threads表存储着每一个短信对话的线程. 主要列有_id, date, message_count, recipient_ids, snippet, read
recipient_ids 存放的是参与此次对话的person的id, 然而这个id不是通讯录里面的id, 而是canonical_addresses 的id. 这就是canonical_addresses 表格的作用
threads 表 uri: content://mms-sms/conversations?simple=true
canonical_addresses 表 uri content://mms-sms/canonical-addresses
一、需要实现一个同系统信息一样的功能
1)会话列表;
2)会话对话详情;
3)系统会话增加新信息或者删除信息等变化时做到同步;
二、实现思路
通过查询会话表显示会话界面,监听会话数据库实现与系统信息同步。通过会话id查询会话对应的具体聊天内容,比如短信或者彩信;
看下mmssms.db中的uri有好多个,可以根据自己的需求选择合适的uri,可以避免不必要的操作,提高效率。经过多次测试,实现以上功能需要用的信息表有:
1)会话表:content://mms-sms/conversations/
2)短信表:content://sms
3)彩信表:content://mms、content://mms/part
4)信息对应手机号码表:content://mms-sms/canonical-addresses
需要权限:<uses-permission android:name="android.permission.READ_SMS" />
首先:显示会话列表
public static final Uri THREADS_URI = Uri.parse("content://mms-sms/conversations?simple=true");
threads字段:
_id
date
ct_t:区分彩信还是短信:application/vnd.wap.multipart.related是彩信,否则是短信
snippet:最新的一条会话信息。彩信为彩信的主题,短信时短信的body
recipient_ids:信息对应手机号码表(content://mms-sms/canonical-addresses)中的id,查询对应的手机号码
message_count:详细对话条数
read
snippet_cs:snippet的编码方式,彩信:106(utf-8),短信:0
……
根据threads表中的date,snippet,messagecount基本可以显示会话列表了。
另外:
1:通过4)信息对应手机号码表:content://mms-sms/canonical-addresses获取了手机号之后获取联系人姓名以及头像使用:ContactsContract.CommonDataKinds.Phone.CONTENT_URI
2:当会话为彩信时,snippet显示的是彩信的主题,编码方式为utf-8。显示为乱码。
解决:snippet_mms = new String(snippet.getBytes("ISO8859_1"), "utf-8");
其次,获取会话具体对话内容
具体对话的格式有ssm或者mms,通过content://mms-sms/conversations/threadid,可以查询与某联系人的所有聊天记录的id,这个id对应短信或者彩信表中的id。如果具体会话是短信,则去sms表中查询具体内容,如果是彩信则去mms表中查询。通过字段ct_t 区分信息类别。
具体实现:
1)获取sms
[java] view plaincopyprint?String selection = "_id = "+id;
Uri uri = Uri.parse("content://sms");
Cursor cursor = contentResolver.query(uri, null, selection, null, null);
String phone = cursor.getString(cursor.getColumnIndex("address"));
int type = cursor.getInt(cursor.getColumnIndex("type"));// 2 = sent, etc.
String date = cursor.getString(cursor.getColumnIndex("date"));
String body = cursor.getString(cursor.getColumnIndex("body"));
String selection = "_id = "+id;
Uri uri = Uri.parse("content://sms");
Cursor cursor = contentResolver.query(uri, null, selection, null, null);
String phone = cursor.getString(cursor.getColumnIndex("address"));
int type = cursor.getInt(cursor.getColumnIndex("type"));// 2 = sent, etc.
String date = cursor.getString(cursor.getColumnIndex("date"));
String body = cursor.getString(cursor.getColumnIndex("body"));
2)获取mms
彩信表:content://mms
彩信附件:content://mms/part/
get text content from MMS:
[java] view plaincopyprint?String selectionPart = "mid=" + mmsId;
Uri uri = Uri.parse("content://mms/part");
Cursor cursor = getContentResolver().query(uri, null,
selectionPart, null, null);
if (cursor.moveToFirst()) {
do {
String partId = cursor.getString(cursor.getColumnIndex("_id"));
String type = cursor.getString(cursor.getColumnIndex("ct"));
if ("text/plain".equals(type)) {
String data = cursor.getString(cPart.getColumnIndex("_data"));
String body;
if (data != null) {
// implementation of this method below
body = getMmsText(partId);
} else {
body = cursor.getString(cursor.getColumnIndex("text"));
}
}
} while (cursor.moveToNext());
}
String selectionPart = "mid=" + mmsId;
Uri uri = Uri.parse("content://mms/part");
Cursor cursor = getContentResolver().query(uri, null,
selectionPart, null, null);
if (cursor.moveToFirst()) {
do {
String partId = cursor.getString(cursor.getColumnIndex("_id"));
String type = cursor.getString(cursor.getColumnIndex("ct"));
if ("text/plain".equals(type)) {
String data = cursor.getString(cPart.getColumnIndex("_data"));
String body;
if (data != null) {
// implementation of this method below
body = getMmsText(partId);
} else {
body = cursor.getString(cursor.getColumnIndex("text"));
}
}
} while (cursor.moveToNext());
}
[java] view plaincopyprint?private String getMmsText(String id) {
Uri partURI = Uri.parse("content://mms/part/" + id);
InputStream is = null;
StringBuilder sb = new StringBuilder();
try {
is = getContentResolver().openInputStream(partURI);
if (is != null) {
InputStreamReader isr = new InputStreamReader(is, "UTF-8");
BufferedReader reader = new BufferedReader(isr);
String temp = reader.readLine();
while (temp != null) {
sb.append(temp);
temp = reader.readLine();
}
}
} catch (IOException e) {}
finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {}
}
}
return sb.toString();
}
private String getMmsText(String id) {
Uri partURI = Uri.parse("content://mms/part/" + id);
InputStream is = null;
StringBuilder sb = new StringBuilder();
try {
is = getContentResolver().openInputStream(partURI);
if (is != null) {
InputStreamReader isr = new InputStreamReader(is, "UTF-8");
BufferedReader reader = new BufferedReader(isr);
String temp = reader.readLine();
while (temp != null) {
sb.append(temp);
temp = reader.readLine();
}
}
} catch (IOException e) {}
finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {}
}
}
return sb.toString();
}
获取彩信中图片:
[java] view plaincopyprint?String selectionPart = "mid=" + mmsId;
Uri uri = Uri.parse("content://mms/part");
Cursor cPart = getContentResolver().query(uri, null,
selectionPart, null, null);
if (cPart.moveToFirst()) {
do {
String partId = cPart.getString(cPart.getColumnIndex("_id"));
String type = cPart.getString(cPart.getColumnIndex("ct"));
if ("image/jpeg".equals(type) || "image/bmp".equals(type) ||
"image/gif".equals(type) || "image/jpg".equals(type) ||
"image/png".equals(type)) {
Bitmap bitmap = getMmsImage(partId);
}
} while (cPart.moveToNext());
}
String selectionPart = "mid=" + mmsId;
Uri uri = Uri.parse("content://mms/part");
Cursor cPart = getContentResolver().query(uri, null,
selectionPart, null, null);
if (cPart.moveToFirst()) {
do {
String partId = cPart.getString(cPart.getColumnIndex("_id"));
String type = cPart.getString(cPart.getColumnIndex("ct"));
if ("image/jpeg".equals(type) || "image/bmp".equals(type) ||
"image/gif".equals(type) || "image/jpg".equals(type) ||
"image/png".equals(type)) {
Bitmap bitmap = getMmsImage(partId);
}
} while (cPart.moveToNext());
}
[java] view plaincopyprint?private Bitmap getMmsImage(String _id) {
Uri partURI = Uri.parse("content://mms/part/" + _id);
InputStream is = null;
Bitmap bitmap = null;
try {
is = getContentResolver().openInputStream(partURI);
bitmap = BitmapFactory.decodeStream(is);
} catch (IOException e) {}
finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {}
}
}
return bitmap;
}
private Bitmap getMmsImage(String _id) {
Uri partURI = Uri.parse("content://mms/part/" + _id);
InputStream is = null;
Bitmap bitmap = null;
try {
is = getContentResolver().openInputStream(partURI);
bitmap = BitmapFactory.decodeStream(is);
} catch (IOException e) {}
finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {}
}
}
return bitmap;
}
测试结果:
最后,我的会话界面与系统的实时同步
监听系统的会话数据表即可:
public static final Uri THREADS_URI = Uri
.parse("content://mms-sms/conversations?simple=true");
getContentResolver().registerContentObserver(THREADS_URI ,true, sysCallLogObserver);
另外:
我只写了自己用的表字段,如果想字段别的可以自己打印下:
cursor.getColumnNames();
========================================
数据库中sms相关的字段如下:
_id primary key integer 与words表内的source_id关联
thread_id 会话id,一个联系人的会话一个id,与threads表内的_id关联 integer
address 对方号码 text
person 联系人id integer
date 发件日期 integer
protocol 通信协议,判断是短信还是彩信 integer 0:SMS_RPOTO, 1:MMS_PROTO
read 是否阅读 integer default 0 0:未读, 1:已读
status 状态 integer default-1 -1:接收,
0:complete,
64: pending,
128: failed
type 短信类型 integer 1:inbox
2:sent
3:draft56
4:outbox
5:failed
6:queued
body 内容
service_center 服务中心号码
subject 主题
reply_path_present
locked
error_code
seen
用adb指令将mmssms.db从/data/data/com.android.providers.telephony/databases中pull出来
经常使用到的表有
canonical_addresses, sms, threads三个表格
sms是存储着所有的短信, 主要的列有_id, thread_id, address, person, date, read, type, body
关于的sms的Uri有
发件箱 content://sms/outbox
收件箱 content://sms/inbox
草稿箱 content://sms/draft
conversations content://sms/conversations
threads表存储着每一个短信对话的线程. 主要列有_id, date, message_count, recipient_ids, snippet, read
recipient_ids 存放的是参与此次对话的person的id, 然而这个id不是通讯录里面的id, 而是canonical_addresses 的id. 这就是canonical_addresses 表格的作用
threads 表 uri: content://mms-sms/conversations?simple=true
canonical_addresses 表 uri content://mms-sms/canonical-addresses
一、需要实现一个同系统信息一样的功能
1)会话列表;
2)会话对话详情;
3)系统会话增加新信息或者删除信息等变化时做到同步;
二、实现思路
通过查询会话表显示会话界面,监听会话数据库实现与系统信息同步。通过会话id查询会话对应的具体聊天内容,比如短信或者彩信;
看下mmssms.db中的uri有好多个,可以根据自己的需求选择合适的uri,可以避免不必要的操作,提高效率。经过多次测试,实现以上功能需要用的信息表有:
1)会话表:content://mms-sms/conversations/
2)短信表:content://sms
3)彩信表:content://mms、content://mms/part
4)信息对应手机号码表:content://mms-sms/canonical-addresses
需要权限:<uses-permission android:name="android.permission.READ_SMS" />
首先:显示会话列表
public static final Uri THREADS_URI = Uri.parse("content://mms-sms/conversations?simple=true");
threads字段:
_id
date
ct_t:区分彩信还是短信:application/vnd.wap.multipart.related是彩信,否则是短信
snippet:最新的一条会话信息。彩信为彩信的主题,短信时短信的body
recipient_ids:信息对应手机号码表(content://mms-sms/canonical-addresses)中的id,查询对应的手机号码
message_count:详细对话条数
read
snippet_cs:snippet的编码方式,彩信:106(utf-8),短信:0
……
根据threads表中的date,snippet,messagecount基本可以显示会话列表了。
另外:
1:通过4)信息对应手机号码表:content://mms-sms/canonical-addresses获取了手机号之后获取联系人姓名以及头像使用:ContactsContract.CommonDataKinds.Phone.CONTENT_URI
2:当会话为彩信时,snippet显示的是彩信的主题,编码方式为utf-8。显示为乱码。
解决:snippet_mms = new String(snippet.getBytes("ISO8859_1"), "utf-8");
其次,获取会话具体对话内容
具体对话的格式有ssm或者mms,通过content://mms-sms/conversations/threadid,可以查询与某联系人的所有聊天记录的id,这个id对应短信或者彩信表中的id。如果具体会话是短信,则去sms表中查询具体内容,如果是彩信则去mms表中查询。通过字段ct_t 区分信息类别。
具体实现:
1)获取sms
[java] view plaincopyprint?String selection = "_id = "+id;
Uri uri = Uri.parse("content://sms");
Cursor cursor = contentResolver.query(uri, null, selection, null, null);
String phone = cursor.getString(cursor.getColumnIndex("address"));
int type = cursor.getInt(cursor.getColumnIndex("type"));// 2 = sent, etc.
String date = cursor.getString(cursor.getColumnIndex("date"));
String body = cursor.getString(cursor.getColumnIndex("body"));
String selection = "_id = "+id;
Uri uri = Uri.parse("content://sms");
Cursor cursor = contentResolver.query(uri, null, selection, null, null);
String phone = cursor.getString(cursor.getColumnIndex("address"));
int type = cursor.getInt(cursor.getColumnIndex("type"));// 2 = sent, etc.
String date = cursor.getString(cursor.getColumnIndex("date"));
String body = cursor.getString(cursor.getColumnIndex("body"));
2)获取mms
彩信表:content://mms
彩信附件:content://mms/part/
get text content from MMS:
[java] view plaincopyprint?String selectionPart = "mid=" + mmsId;
Uri uri = Uri.parse("content://mms/part");
Cursor cursor = getContentResolver().query(uri, null,
selectionPart, null, null);
if (cursor.moveToFirst()) {
do {
String partId = cursor.getString(cursor.getColumnIndex("_id"));
String type = cursor.getString(cursor.getColumnIndex("ct"));
if ("text/plain".equals(type)) {
String data = cursor.getString(cPart.getColumnIndex("_data"));
String body;
if (data != null) {
// implementation of this method below
body = getMmsText(partId);
} else {
body = cursor.getString(cursor.getColumnIndex("text"));
}
}
} while (cursor.moveToNext());
}
String selectionPart = "mid=" + mmsId;
Uri uri = Uri.parse("content://mms/part");
Cursor cursor = getContentResolver().query(uri, null,
selectionPart, null, null);
if (cursor.moveToFirst()) {
do {
String partId = cursor.getString(cursor.getColumnIndex("_id"));
String type = cursor.getString(cursor.getColumnIndex("ct"));
if ("text/plain".equals(type)) {
String data = cursor.getString(cPart.getColumnIndex("_data"));
String body;
if (data != null) {
// implementation of this method below
body = getMmsText(partId);
} else {
body = cursor.getString(cursor.getColumnIndex("text"));
}
}
} while (cursor.moveToNext());
}
[java] view plaincopyprint?private String getMmsText(String id) {
Uri partURI = Uri.parse("content://mms/part/" + id);
InputStream is = null;
StringBuilder sb = new StringBuilder();
try {
is = getContentResolver().openInputStream(partURI);
if (is != null) {
InputStreamReader isr = new InputStreamReader(is, "UTF-8");
BufferedReader reader = new BufferedReader(isr);
String temp = reader.readLine();
while (temp != null) {
sb.append(temp);
temp = reader.readLine();
}
}
} catch (IOException e) {}
finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {}
}
}
return sb.toString();
}
private String getMmsText(String id) {
Uri partURI = Uri.parse("content://mms/part/" + id);
InputStream is = null;
StringBuilder sb = new StringBuilder();
try {
is = getContentResolver().openInputStream(partURI);
if (is != null) {
InputStreamReader isr = new InputStreamReader(is, "UTF-8");
BufferedReader reader = new BufferedReader(isr);
String temp = reader.readLine();
while (temp != null) {
sb.append(temp);
temp = reader.readLine();
}
}
} catch (IOException e) {}
finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {}
}
}
return sb.toString();
}
获取彩信中图片:
[java] view plaincopyprint?String selectionPart = "mid=" + mmsId;
Uri uri = Uri.parse("content://mms/part");
Cursor cPart = getContentResolver().query(uri, null,
selectionPart, null, null);
if (cPart.moveToFirst()) {
do {
String partId = cPart.getString(cPart.getColumnIndex("_id"));
String type = cPart.getString(cPart.getColumnIndex("ct"));
if ("image/jpeg".equals(type) || "image/bmp".equals(type) ||
"image/gif".equals(type) || "image/jpg".equals(type) ||
"image/png".equals(type)) {
Bitmap bitmap = getMmsImage(partId);
}
} while (cPart.moveToNext());
}
String selectionPart = "mid=" + mmsId;
Uri uri = Uri.parse("content://mms/part");
Cursor cPart = getContentResolver().query(uri, null,
selectionPart, null, null);
if (cPart.moveToFirst()) {
do {
String partId = cPart.getString(cPart.getColumnIndex("_id"));
String type = cPart.getString(cPart.getColumnIndex("ct"));
if ("image/jpeg".equals(type) || "image/bmp".equals(type) ||
"image/gif".equals(type) || "image/jpg".equals(type) ||
"image/png".equals(type)) {
Bitmap bitmap = getMmsImage(partId);
}
} while (cPart.moveToNext());
}
[java] view plaincopyprint?private Bitmap getMmsImage(String _id) {
Uri partURI = Uri.parse("content://mms/part/" + _id);
InputStream is = null;
Bitmap bitmap = null;
try {
is = getContentResolver().openInputStream(partURI);
bitmap = BitmapFactory.decodeStream(is);
} catch (IOException e) {}
finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {}
}
}
return bitmap;
}
private Bitmap getMmsImage(String _id) {
Uri partURI = Uri.parse("content://mms/part/" + _id);
InputStream is = null;
Bitmap bitmap = null;
try {
is = getContentResolver().openInputStream(partURI);
bitmap = BitmapFactory.decodeStream(is);
} catch (IOException e) {}
finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {}
}
}
return bitmap;
}
测试结果:
最后,我的会话界面与系统的实时同步
监听系统的会话数据表即可:
public static final Uri THREADS_URI = Uri
.parse("content://mms-sms/conversations?simple=true");
getContentResolver().registerContentObserver(THREADS_URI ,true, sysCallLogObserver);
另外:
我只写了自己用的表字段,如果想字段别的可以自己打印下:
cursor.getColumnNames();
========================================
数据库中sms相关的字段如下:
_id primary key integer 与words表内的source_id关联
thread_id 会话id,一个联系人的会话一个id,与threads表内的_id关联 integer
address 对方号码 text
person 联系人id integer
date 发件日期 integer
protocol 通信协议,判断是短信还是彩信 integer 0:SMS_RPOTO, 1:MMS_PROTO
read 是否阅读 integer default 0 0:未读, 1:已读
status 状态 integer default-1 -1:接收,
0:complete,
64: pending,
128: failed
type 短信类型 integer 1:inbox
2:sent
3:draft56
4:outbox
5:failed
6:queued
body 内容
service_center 服务中心号码
subject 主题
reply_path_present
locked
error_code
seen
发表评论
-
ScrollView嵌套Edittext
2015-04-08 18:26 792scrollview 中加入多个控件如 edittext 后会 ... -
android 布局式跑马灯,非TextView
2015-04-07 10:51 451如题,简单的实现了跑马灯效果,把Scroll.java放入an ... -
Android圆角图片
2015-03-11 17:44 650my_wane_shape.xml 快速圆角背景边框实现, ... -
SQLite多线程读写实践及常见问题总结
2015-02-13 17:06 904基本操作的部分,大家都很熟悉了,这里根据个人切身经验,总结了一 ... -
android加速度感应
2015-01-19 10:25 14351.android测量数据 (1)android设备坐标系 ... -
MatrixCursor的使用
2015-01-19 09:49 1014ContentProvider对外共享数据的时候的query( ... -
Android 获取控件的宽高高级用法(MeasureSpec)
2015-01-15 14:23 940一个MeasureSpec封装了父 ... -
Android_GridView_GridView概述及实现水平滑动
2015-01-14 17:14 11191.GridView简介 GridView是ViewGroup ... -
Android MMS,SMS之常用Uri
2014-09-19 16:32 1292Android MMS,SMS之常用Uri Android ... -
使用Android自带DownloadManager下载文件
2014-08-19 11:04 735SDK在API Level 9中加入了DownloadMan ... -
android textview里链接点击事件,增加图片
2014-08-07 16:45 1103Android系统默认给TextView插入图片提供了三种方 ... -
android Home事件汇总
2014-07-18 11:30 967方法一:android 4.0以后无法通过更改页面的类型来 ... -
Android风格与主题(style and theme)
2014-07-16 16:35 639Android xml风格和主题文 ... -
Android中播放声音的两种方法
2014-05-30 15:09 609在Android中,音频、视 ... -
android 杀进程方法
2014-05-26 17:43 974关闭应用的方法: 1.System.exit(0); ... -
android service 生命周期
2014-04-21 16:16 740有了 Service 类我们如何启动他呢,有两种方法: ... -
解决ADB端口被占用的问题
2014-04-21 16:14 784究其源就是adb server没启动 经过分析整理如下: ... -
输入法隐藏打开
2013-12-23 14:24 771首次进入activity,如果有个edittex ... -
google经纬度互转
2013-07-11 16:34 896https://developers.google.com/ ... -
android 安装删除软件
2013-07-08 17:19 11131、 Android.mk文件 LOCAL_PA ...
相关推荐
做短彩信的朋友火速收藏,短彩信数据表结构
Android MMS彩信发送代码流程+UML流程图
Android短彩信收发流程(Framework)
3GPP和WAP论坛在共同确立MMS规范时,既定义了利用WAP协议作承载、SMS短消息作通知的 MMS彩信业务,又定义了直接采用TCP/IP方式的MMS彩信业务,即MMS彩信业务既可以基于WAP实现,也可以基于IP实现。
彩信 1
几个比较有用的Android开发的彩信程序,希望有帮助。
MMS彩信业务流程及代码实现,业务流程,彩信的接收
android 实现彩信发送 可直接部署使用
MMS PDU编码,支持GIF,JPG,MID,中文标题,自动生成彩信包。VS2008。
android 插入彩信数据库代码 新建彩信 导入彩信
彩信协议,介绍彩信客户端服务器端基本结构
【Android】Android彩信发送源码
最简单的android彩信发送代码。适合学习彩信发送流程。 事实上android中的Mms模块中,对这个流程进行了很少的封装,这里就是将其简化,帮助初学者了解流程。
C实现的彩信封包解包源码,分享给大家,个人感觉还不错。
本工程是对android中从彩信中读取二维码图片,以及彩信中的图片,文字等内容
这是那个彩信包,加入到项目里就可以解决很多无法引入的问题,然后网上有一些具体的拦截方法的帖子,看下,就可以了。 没时间把我做的东西提取成一个可用的demo,不好意思,想办法做吧,如果还是没有办法,等我有...
Android彩信发送介绍 Android彩信发送介绍
mms(彩信)研究PPT 供研究和开发的人员用. 谢谢合作.
MMS源代码 详细设计,包含sms mms
用c#实现发送彩信MMS