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( ...
随机推荐
- VMware虚拟机如何设置从U盘启动
要给虚拟机重新安装win7系统,想使用U盘重装系统的方式,就需要让虚拟机从U盘启动,以下内容就是虚拟机从U盘启动的全操作过程. 前期准备: 1.u盘启动盘 2.VMware虚拟机 具体操作步骤: 1. ...
- nginx的下载和安装
安装 下载必要组件 nginx下载地址 http://nginx.org/en/download.html pcre库下载地址,nginx需要[解析正则] http://sourceforge.ne ...
- python的socket编程之udp编程
在上篇文章中,仅仅讲述了如何进行了TCP编程,在本章中,将讲述使用udp进行编码,先看如下的代码,服务器端: root@python 513]# cat serverudp.py #!/usr/bin ...
- C/S软件的自动升级部署
升级的原理有好几个,首先无非是将现有版本与最新版本作比较,发现最新的则提示用户是否升级.当然也有人用其它属性比较的,例如:文件大小,或者更新日期.而实现的方法呢? 在.Net时代,我们就有了更多的选择 ...
- 浅谈Trigger
- 查看MSSQL数据库每个表占用的空间大小
需要查看数据库表的大小,查询SQL Server联机从书得到如下语句: sp_spaceused 显示行数.保留的磁盘空间以及当前数据库中的表所使用的磁盘空间,或显示由整个数据库保留和使用的磁盘空间. ...
- java 多线程下载文件 以及URLConnection和HttpURLConnection的区别
使用 HttpURLConnection 实现多线程下载文件 注意GET大写//http public class MultiThreadDownload { public static void m ...
- 【POJ1509】Glass Beads 【后缀自动机】
题意 给出一个字符串,求它的最小表示法. 分析 这个题当然可以用最小表示法做啦!但是我是为了学后缀自动机鸭! 我们把这个字符串长度乘二,然后建SAM,然后在SAM上每次跑最小的那个字母,找出长度为n的 ...
- K.O. ----- 配置文件没有提示
---------------siwuxie095 K.O. ----- 配置文件没有提示 1.解决方法一:联网 只要 PC 联网,配置文件中就有提示 2.解决方法二:手动导入约束文件 约束文件:hi ...
- 文件操作putc
putc是把一个字符写入到指定文件中,每写一个字符,文件指针自动加1. 我写了一个随机生成255字符到d:/456.txt的程序. int main() { FILE *p; int num[255] ...