Android-监听操作系统短信
想要访问Android操作系统的ContentProvider就需要明白以下原理:
在Android操作系统里面的 /packsges/目录:
apps: 很多的系统应用,例如:联系人,浏览器,音乐播放器,设置,相机 ......
............
providers:系统对外暴露的ContentProvider:

这样就明白了,Android操作系统里面的应用(apps),是访问系统对外暴露的ContentProvider(providers)
既然说Android操作系统里面的应用(apps),是访问系统对外暴露的ContentProvider(providers):
/data/data/com.android.mms(放置在apps目录里面)
/data/data/com.android.providers.telephony(放置在providers目录里面)
mms(短信应用) 是调用 providers.telephony(内容提供者里面的数据),如图:

短信应用没有数据库,那短信应用的数据是从哪里来的 ?

答:短信应用是去 增删改查了 com.android.providers.telephony 暴露短信数据的应用
apps:packages/apps/Mms Android文件系统里 /data/data/com.android.mms 短信应用

provider: packages/provider/ Android文件系统里 /data/data/com.android.providers.telephony 暴露短信数据的应用

阅读packages/provider/TelephonyProvider/com.android.providers.telephony 暴露短信数据的应用 数据库:
mmssms.db 数据库 其他应用是没有权限访问的,为什么所有应用都能获取到 packgeas/providers/....里面到所有应用,因为这些应用通过ContentProvider对外暴露了

阅读mmssms.db
打开后:表非常多,等等, 但是只需要关注一张核心的表,sms

关注的字段:address:短信号码, date:短信时间 ,body:短信内容

手机里只有一条短信:

阅读packages/provider/TelephonyProvider/com.android.providers.telephony AndroidManifest.xml
查看AndroidManifest.xml provider节点:关注ContentProvider对象,授权,权限 等;
SmsProvider:内容提供者
sms:授权,这授权真短
exported:对外输出
READ_SMS/WRITE_SMS:访问者必须要配置的权限
<!-- This is a singleton provider that is used by all users.
A new instance is not created for each user. And the db is shared
as well. -->
<provider android:name="SmsProvider"
android:authorities="sms"
android:multiprocess="false"
android:exported="true"
android:singleUser="true"
android:readPermission="android.permission.READ_SMS"
android:writePermission="android.permission.WRITE_SMS" />
阅读packages/provider/TelephonyProvider/com.android.providers.telephony SmsProvider.java
首先要找到的就是Uri,所以搜索UriMatcher的matcher.addURI
private static final UriMatcher sURLMatcher =
new UriMatcher(UriMatcher.NO_MATCH); static {
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", "icc", SMS_ALL_ICC);
sURLMatcher.addURI("sms", "icc/#", SMS_ICC);
//we keep these for not breaking old applications
sURLMatcher.addURI("sms", "sim", SMS_ALL_ICC);
sURLMatcher.addURI("sms", "sim/#", SMS_ICC);
sURLMatcher.addURI("sms", null, SMS_ALL); 就是全部短信内容的Uir,path等于null,这样写是可以的,代表全部的意思
在这源码中,一定有发送改变通知的代码:
搜索:.notifyChange
系统源码中 而且还另外两条通知的uri

测试的应用:AndroidManifest.xml 配置权限
<!--
访问操作系统短信内容提供者应用,需要加入的权限
android:readPermission="android.permission.READ_SMS"
android:writePermission="android.permission.WRITE_SMS"
-->
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS"/>
测试的应用:监听Android操作系统联系人内容提供者应用里面的短信数据发送的改变
package liudeli.cp.client; import android.app.Activity;
import android.app.AlertDialog;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler; public class SmsActivity extends Activity { /**
* 定义访问操作系统短信内容提供者应用的Uri
* android:authorities="sms"
*/
private final String AUTHORITIES = "content://sms";
private Uri telephonyUri = Uri.parse(AUTHORITIES); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_sms); /**
* 注册内容观察者监听器:用于监听/data/data/com.android.providers.telephony内容提供者应用
* 参数一:定义访问操作系统短信内容提供者应用的Uri android:authorities="sms"
* 参数二:要联级
* 参数三:监听器
*/
getContentResolver().registerContentObserver(telephonyUri, true, contentObserver);
} private ContentObserver contentObserver = new ContentObserver(new Handler()) { @Override
public void onChange(boolean selfChange) {
super.onChange(selfChange); // 短信数据发送改变啦 ... /**
* 查询短信最新的一条信息显示
*/
Cursor cursor = getContentResolver().query(telephonyUri,
new String[]{"address", "date", "body"},
null, // 查询条件为null
null , // 查询条件的值为null
" _id desc"); // 倒序,查询出来的第一条就是最新的短信 // Cursor游标必须往下移,才能取出数据
if (cursor.moveToFirst()) { // 移动到第一条
String address = cursor.getString(cursor.getColumnIndex("address"));
String body = cursor.getString(cursor.getColumnIndex("body"));
alterUser(address, body);
} // 关闭游标
cursor.close();
}
}; private void alterUser(String address, String body) {
new AlertDialog.Builder(this)
.setPositiveButton("我知道了", null)
.setTitle("注意")
.setMessage("短信发送改变啦, /n 短信号码:" + address + " /n 短信内容:" + body)
.show();
} @Override
protected void onDestroy() {
super.onDestroy();
/**
* 解除监听器
*/
getContentResolver().unregisterContentObserver(contentObserver);
}
}
Android操作系统里面的应用(apps),是访问系统对外暴露的ContentProvider(providers)
自己开发的应用,也是可以访问系统对外暴露的ContentProvider(providers)

Android-监听操作系统短信的更多相关文章
- Android监听系统短信数据库变化-提取短信内容
由于监听系统短信广播受到权限的限制,所以很多手机可能使用这种方式没法监听广播,从而没办法获取到系统短信,所以又重新开辟一条路. Android监听系统短信数据库内容变化使用场景: 1.监听短信数据库的 ...
- Android 监听SMS短信
当设备接收到一条新的SMS消息时,就会广播一个包括了android.provider.Telephony.SMS_RECEIVED动作的Intent. 注意,这个动作是一个字符串值,SDK 1.0不再 ...
- Android studio之广播监听接收短信
一. 在清单文件中(AndroidManifest.xml)添加短信权限 这里我用的android studio版本是3.3的 <uses-permission android:name=&qu ...
- Android 监听短信(同时监听广播和数据库)
暗扣,强烈谴责这种侵害用户利益的行为... 下面给大家介绍Android暗扣原理....... Android4.4以下的系统玩游戏就要小心了哈 暗扣方式之一:短信订购,即监听--------拦截- ...
- android 监听短信数据库,制作短信控制工具,控制别人的手机!!(一)
序言:本程序示例本着简洁易懂的目的,只做了简单的功能实现,需要用户启动应用,收到短信才有效果.作者将会在后面的(二)篇中加入服务后台运行.自动启动功能,实现一个真正的短信控制工具.本文的目的很简单,让 ...
- android: 接收和发送短信
8.2 接收和发送短信 收发短信应该是每个手机最基本的功能之一了,即使是许多年前的老手机也都会具备这 项功能,而 Android 作为出色的智能手机操作系统,自然也少不了在这方面的支持.每个 A ...
- Android学习笔记之短信验证码的获取和读取
PS:最近很多事情都拖拖拉拉的..都什么办事效率啊!!! 还得吐槽一下移动运营商,验证码超过五次的时候,直接把我的手机号封闭.真是受够了. 学习笔记: 1.Android之如何获取短信验证码. 2.如 ...
- Android-看操作系统短信应用源码-隐式意图激活短信界面
选择模拟器Unknown Google Nexus,在选择system_process(系统进程) 操作模拟器的,操作系统短信应用,让操作系统短信打印日志,来查看: 然后就找到来,操作系统短信应用打印 ...
- Android监听返回键、Home键+再按一次返回键退出应用
Android监听返回键需重写onKeyDown()方法 Home键keyCode==KeyEvent.KEYCODE_HOME @Override public boolean onKeyDown( ...
随机推荐
- Eclipse免reload设置
在使用eclipse开发web项目的时候,有的时候需要通过运行看结果,但是如果项目很大,你改一句代码,也许就要重启一次,或者eclipse自动帮你reload,这样严重的影响开发的效率,这里只要修改一 ...
- 20_java之集合Map
01Map集合概述 A:Map集合概述: 我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同 a:Collection中的集合,元素是孤立 ...
- A generic error occurred in GDI+的解决方案
转自智慧光原文A generic error occurred in GDI+. 解决方法 使用image1.RotateFlip(RotateFlipType.Rotate90FlipNone)方法 ...
- Bootstrip 的select的数据绑定问题
这个问题浪费了我整整一个下午时间 最后终于解决了 这里来备份一下 $(function(){ var stu_no = freeUrl(); var data, subname="&quo ...
- 超强敏感词过滤算法第二版 可以忽略大小写、全半角、简繁体、特殊符号、HTML标签干扰
上一篇 发一个高性能的敏感词过滤算法 可以忽略大小写.全半角.简繁体.特殊符号干扰 改进主要有几点: 用BitArray取代Dictionary用空间换时间 性能进一步提升 大概会增加词库的 6k* ...
- Python实现常见算法[2]——快速排序
#!/usr/bin/python # module: quik_sort.py def PARTION(L,m,n): base = L[n] i = m-1 j = m while j<n: ...
- redis缓存分页思路
传统分页一般分页做缓存都是直接查找出来,按页放到缓存里,但是这种缓存方式有很多缺点.如缓存不能及时更新,一旦数据有变化,所有的之前的分页缓存都失效了.比如像微博这样的场景,微博下面现在有一个顶次数的排 ...
- LoadRunner11学习记录五 -- 错误提示分析
LoadRunner测试结果具体分析: 一.错误提示分析 分析实例: 1.Error: Failed to connect to server “172.17.7.230″: [10060] Con ...
- [Jenkins] 执行SoapUI的task,设置邮件内容为HTML+CSS
设置邮件内容:Default Content <span style="font-family:verdana;font-size:16px;color:black;font-weig ...
- [SoapUI] SoapUI+Groovy中"org.apache.xmlbeans.XmlException: error:
把 def holder = groovyUtils.getXmlHolder("Get Token#Response") 改为 def holder = groovyUtils. ...