content://sms/inbox 收件箱
content://sms/sent 已发送
content://sms/draft 草稿
content://sms/outbox 发件箱
content://sms/failed 发送失败
content://sms/queued 待发送列表
数据库中sms相关的字段如下:
_id 一个自增字段,从1开始
thread_id 序号,同一发信人的id相同
address 发件人手机号码
person 联系人列表里的序号,陌生人为null
date 发件日期
protocol 协议,分为: 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;
body 短信内容
service_center 短信服务中心号码编号
subject 短信的主题
reply_path_present TP-Reply-Path
locked
检索数据方法很简单:
Uri uri = Uri.parse("content://sms/inbox");
Cursor cur = this.managedQuery(uri, null, null, null, null);
if (cur.moveToFirst()) {
do{
for(int j = 0; j < cur.getColumnCount(); j++){
info = "name:" + cur.getColumnName(j) + "=" + cur.getString(j);
Log.i("====>", info);
}
}while(cur.moveToNext());
}
managedQuery最终也要将参数转换为SQL语句向SQLite发送消息,因此参数跟SQL语句很类似,所以可以在查询字段中加入SQL函数,
比如new String[] projection = new String[]{"count(*) as count"}等等。
managedQuery中的参数依次为uri,
查询字段 查询字段数组,也可以将所有需要查询的字段放入一个字符内
比如new projection[]{"_id", "thread_id"}和new projection[]{"_id,thread_id"}是一致的。
跟SQL一样,字段名不区分大小写
条件 不带Where的SQL 条件字符,如果有参数则用?替代,比如"_id=? And thread_id = ? Or type = '1'"
条件中的参数 参数字符数组,跟上述的条件一一对应
排序 不带Order by排序字符串,比如_id desc, type
如果参数为null,SQL中查询字段为“*”,相关的条件为空白
还可以用getContentResolver()获得一个ContentResolver,
getContentResolver().query()同样返回一个Cursor对象,参数跟managedQuery一致。
不过用ContentResolver对象去更新、删除和插入一条数据时报SecurityException。看来没有权限,在Manifest.xml中加入权限:
<uses-permission android:name="android.permission.WRITE_SMS"></uses-permission>
然后删除短信:
this.getContentResolver().delete(Uri.parse("content://sms"), "_id=?", new String[]{"3"});
删除成功。
Url中content://sms替换成content://sms/也成功,但是其它url时程序报错,比如content://sms/inbox
看了一下android的源代码,sms支持的协议有:
sURLMatcher.addURI("sms", null, SMS_ALL);
sURLMatcher.addURI("sms", "#", SMS_ALL_ID);
sURLMatcher.addURI("sms", "inbox", SMS_INBOX);
sURLMatcher.addURI("sms", "inbox/#", SMS_INBOX_ID);
sURLMatcher.addURI("sms", "sent", SMS_SENT);
sURLMatcher.addURI("sms", "sent/#", SMS_SENT_ID);
sURLMatcher.addURI("sms", "draft", SMS_DRAFT);
sURLMatcher.addURI("sms", "draft/#", SMS_DRAFT_ID);
sURLMatcher.addURI("sms", "outbox", SMS_OUTBOX);
sURLMatcher.addURI("sms", "outbox/#", SMS_OUTBOX_ID);
sURLMatcher.addURI("sms", "undelivered", SMS_UNDELIVERED);
sURLMatcher.addURI("sms", "failed", SMS_FAILED);
sURLMatcher.addURI("sms", "failed/#", SMS_FAILED_ID);
sURLMatcher.addURI("sms", "queued", SMS_QUEUED);
sURLMatcher.addURI("sms", "conversations", SMS_CONVERSATIONS);
sURLMatcher.addURI("sms", "conversations/*", SMS_CONVERSATIONS_ID);
sURLMatcher.addURI("sms", "raw", SMS_RAW_MESSAGE);
sURLMatcher.addURI("sms", "attachments", SMS_ATTACHMENT);
sURLMatcher.addURI("sms", "attachments/#", SMS_ATTACHMENT_ID);
sURLMatcher.addURI("sms", "threadID", SMS_NEW_THREAD_ID);
sURLMatcher.addURI("sms", "threadID/*", SMS_QUERY_THREAD_ID);
sURLMatcher.addURI("sms", "status/#", SMS_STATUS_ID);
sURLMatcher.addURI("sms", "sr_pending", SMS_STATUS_PENDING);
sURLMatcher.addURI("sms", "sim", SMS_ALL_SIM);
sURLMatcher.addURI("sms", "sim/#", SMS_SIM);
其中,delete方法中支持的协议为:
SMS_ALL 根据参数中的条件删除sms表数据
SMS_ALL_ID 根据_id删除sms表数据
SMS_CONVERSATIONS_ID 根据thread_id删除sms表数据,可以带其它条件
SMS_RAW_MESSAGE 根据参数中的条件删除 raw表
SMS_STATUS_PENDING 根据参数中的条件删除 sr_pending表
SMS_SIM 从Sim卡上删除数据
试一下SMS_CONVERSATIONS_ID:"content://sms/conversations/3",删除thread_id="3", _id="5"的数据
在eclipse中的Emulator Control中,以13800给模拟器发送三条数据,然后以13900发送一条
this.getContentResolver().delete(Uri.parse("content://sms/conversations/3"), "_id=?", new String[]{"5"});
成功删除一条数据。
在数据库中每个发送者的thread_id虽然一样,但不是固定的,如果把一个发送者的全部数据删除掉,
然后换一个新号码发送短信时,thread_id是以数据库中最大的id+1赋值的。
update支持的协议有很多:
SMS_RAW_MESSAGE
SMS_STATUS_PENDING
SMS_ALL
SMS_FAILED
SMS_QUEUED
SMS_INBOX
SMS_SENT
SMS_DRAFT
SMS_OUTBOX
SMS_CONVERSATIONS
SMS_ALL_ID
SMS_INBOX_ID
SMS_FAILED_ID
SMS_SENT_ID
SMS_DRAFT_ID
SMS_OUTBOX_ID
SMS_CONVERSATIONS_ID
SMS_STATUS_ID
以SMS_INBOX_ID测试一下:
ContentValues cv = new ContentValues();
cv.put("thread_id", "2");
cv.put("address", "00000");
cv.put("person", "11");
cv.put("date", "11111111");
this.getContentResolver().update(Uri.parse("content://sms/inbox/4"), cv, null, null);
太强了,连thread_id都可以修改。
insert支持的协议:
SMS_ALL
SMS_INBOX
SMS_FAILED
SMS_QUEUED
SMS_SENT
SMS_DRAFT
SMS_OUTBOX
SMS_RAW_MESSAGE
SMS_STATUS_PENDING
SMS_ATTACHMENT
SMS_NEW_THREAD_ID
向sms表插入数据时,type是根据协议来自动设置,
如果传入的数据中没有设置date时,自动设置为当前系统时间;非SMS_INBOX协议时,read标志设置为1
SMS_INBOX协议时,系统会自动查询并设置PERSON
threadId为null或者0时,系统也会自动设置
一直为造不了"发送失败"的邮件而发愁,现在来做一个:
content://sms/failed
ContentValues cv = new ContentValues();
cv.put("_id", "99");
cv.put("thread_id", "0");
cv.put("address", "9999");
cv.put("person", "888");
cv.put("date", "9999");
cv.put("protocol", "0");
cv.put("read", "1");
cv.put("status", "-1");
//cv.put("type", "0");
cv.put("body", "@@@@@@@@@");
this.getContentResolver().insert(Uri.parse("content://sms/failed"), cv);
type被设置成了5,thread_id设置为1
系统连最起码的数据校验都没有做啊,google对程序员也太仁慈了。
看看能不能再挖掘一下sms的功能。先来做一个错误的查询:
getContentResolver().query( Uri.parse("content://sms/") , new String[]{"a"}, "b", null, null);
log输出错误的SQL语句:
SELECT a FROM sms WHERE (b) ORDER BY date DESC
query方法中没有Group by,如果想对短信做统计,对Cursor进行遍历再统计也太慢了。
在SQL语言中group by在Where后面,那就在条件参数中想想办法:
Android组织SQL语句时将条件两端加(),那就拼一个group by出来吧:
getContentResolver().query( Uri.parse("content://sms/") , new String[]{"count(*) as count, thread_id"}, "1=1) group by (thread_id", null, null);
那么输出的SQL= SELECT count(*) as count, thread_id FROM sms WHERE ( 1=1) group by (thread_id ) ORDER BY date DESC
如果想查询URI没有对应的表怎么办呢,比如想知道 mmssms.db数据库中有哪些表,
查询的表是URI定的,再在条件参数中拼凑肯定是不行。
那我们把目光往前移,看看在字段参数中能不能凑出来。
要查询其它表,关键要去掉系统固定添加的FROM sms,
用用SQL中的注释吧,
getContentResolver().query(Uri.parse("content://sms/"), new String[]{" * from sqlite_master WHERE type = 'table'--"}, null, null, null);
那么输出的SQL=SELECT * from sqlite_master WHERE type = 'table'--FROM sms ORDER BY date DESC
居然能够运行。
得寸进尺,再进一步,如果加入“;”也能运行的话,哈哈,那么建表、删除表、更新表也能为所欲为咯。
getContentResolver().query(Uri.parse("content://sms/"), new String[]{" * from sms;select * from thrreads;--"}, null, null, null);
很可惜,只运行了第一条SQL语句,看来在关键问题上,android还是有所控制的。
不过支持--也很不错了,这样可以查询数据库中所有的表,而且还可以多表联查
分享到:
相关推荐
这通常涉及到创建ContentValues对象,填充短信的相关字段,如address(发件人)、body(短信内容)等。 7. **UI设计**: 应用的用户界面需要能够显示短信列表,支持查看和回复短信。这可能涉及到使用ListView、...
在Android操作系统中,通话、通讯录、短信和彩信是移动设备的核心功能,它们构成了用户与外界交流的主要渠道。下面将详细阐述这些知识点,并提供一个简单的Contact_Demo应用实例。 **1. 通讯录(Contacts)** ...
【Android短信源码详解】 Android系统的短信功能是其核心组件之一,主要用于用户间发送和接收文本消息,甚至包括多媒体信息(MMS)。本篇将详细探讨Android 4.3及以上版本的短信源码,帮助开发者深入理解其工作原理...
这个压缩包文件“Android短信验证码自动拦截读取的具体代码.zip”包含了一个示例,展示了如何在C#中实现这一功能。尽管C#通常是.NET桌面应用或服务器端编程的首选语言,但在Android开发中,我们通常会使用Java或...
SGIP(Short Message Gateway Interface Protocol)是中国联通推出的一种短消息网关接口协议,主要用于SP(Service Provider,服务提供商)与运营商的短信网关之间进行数据交互。该协议的版本为1.2,它包含了上行和...
本项目"Android Studio 做的小型通讯录"是一个基于这个强大的工具进行的实战练习,旨在帮助开发者掌握Android应用的基本构建过程以及与之相关的技术。 首先,通讯录的核心功能是管理联系人信息,这涉及到了数据存储...
在Android系统中,Gmail备份手机短信功能是一个实用的应用,它允许用户将手机中的短信数据安全地备份到Gmail邮箱中。这个功能背后的实现涉及到Android的API接口、SQLite数据库、网络通信以及数据加密等多个关键知识...
2. **发送短信**:发送短信同样涉及`Intent`的使用,但这次需要设置`ACTION_SENDTO`动作,并将`sms:`协议与电话号码一起作为数据。此外,需要检查设备是否支持发送短信,并在必要时请求用户许可,例如`...
3. **SMTP协议与电子邮件发送**:实现短信转发到邮件的功能,需要利用SMTP(Simple Mail Transfer Protocol)协议。Android中可以使用JavaMail API或者第三方库如Android JavaMail来实现邮件的发送。需要设置SMTP...
至于短信指令的隐藏技术,则是为了让远程控制指令不被普通短信应用或用户察觉,这些隐藏技术可能包括特殊编码、使用特殊协议,甚至是将控制指令嵌入到正常短信的某些特定字段中。 恶意程序利用远程控制技术可以窃取...
在Android应用开发中,用户身份验证是至关重要的环节,它涉及到登录、注册、密码设置以及短信验证码等功能。本文将深入探讨这些关键知识点,并基于提供的"LoginDemo-master"压缩包文件,解析实现这些功能的基本逻辑...
这三个表格共同构成了Android短信系统的数据结构,便于高效地检索、管理和操作短信数据。通过查询和分析这些表格,开发者可以实现各种功能,如统计未读短信、查找特定会话、显示联系人信息以及处理发送失败的情况等...
在Android系统中,RIL(Radio Interface Layer)是操作系统与无线网络硬件之间的接口层,它负责处理各种无线网络相关的操作,如通话、数据连接、短信等。本文将深入解析Android 4.4版本中RIL如何接收短信的流程,...
WeatherDemo应用中,获取天气数据通常通过HTTP协议与远程服务器通信。Android提供了HttpURLConnection或第三方库如OkHttp等进行网络请求。请求过程中,需要注意处理异步操作,避免阻塞主线程,确保用户体验流畅。 ...
- **应用程序层(Applications)**:这一层包含了Android系统中的核心应用程序,例如短信(SMS)应用、日历、联系人管理等。开发者可以通过这些预装的应用了解系统的功能,并以此为基础开发自己的应用。 - **应用程序...
8. **网络请求**:Android应用与云平台交互通常使用HTTP/HTTPS协议,可借助像Retrofit或OkHttp这样的网络库进行API调用。这些库简化了网络请求的编写,支持异步操作,处理JSON数据格式。 9. **数据持久化**:为了...
发送短信界面应该简洁明了,包含必要的输入字段,如接收者电话号码、短信内容等。此外,还需要一个发送按钮来触发短信的发送操作。 **3.2.2 接收短信界面设计** 接收短信界面则需要展示接收到的短信列表,每个条目...
在Android开发中,登录注册界面是用户与应用交互的重要部分,尤其对于移动应用程序而言,一个良好的登录注册体验能显著提升用户的满意度。这个"android 登陆注册界面 有详细的注释"示例,提供了完整的源代码,是学习...
在Android应用开发中,登录和注册功能是必不可少的模块,它们是用户与应用程序交互的入口。这份"Android安卓源码-登录注册类源代码(9例).zip"压缩包提供了一系列的登录注册示例,旨在帮助开发者理解和实现这类功能...