想要访问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-监听操作系统短信的更多相关文章

  1. Android监听系统短信数据库变化-提取短信内容

    由于监听系统短信广播受到权限的限制,所以很多手机可能使用这种方式没法监听广播,从而没办法获取到系统短信,所以又重新开辟一条路. Android监听系统短信数据库内容变化使用场景: 1.监听短信数据库的 ...

  2. Android 监听SMS短信

    当设备接收到一条新的SMS消息时,就会广播一个包括了android.provider.Telephony.SMS_RECEIVED动作的Intent. 注意,这个动作是一个字符串值,SDK 1.0不再 ...

  3. Android studio之广播监听接收短信

    一. 在清单文件中(AndroidManifest.xml)添加短信权限 这里我用的android studio版本是3.3的 <uses-permission android:name=&qu ...

  4. Android 监听短信(同时监听广播和数据库)

    暗扣,强烈谴责这种侵害用户利益的行为... 下面给大家介绍Android暗扣原理.......  Android4.4以下的系统玩游戏就要小心了哈 暗扣方式之一:短信订购,即监听--------拦截- ...

  5. android 监听短信数据库,制作短信控制工具,控制别人的手机!!(一)

    序言:本程序示例本着简洁易懂的目的,只做了简单的功能实现,需要用户启动应用,收到短信才有效果.作者将会在后面的(二)篇中加入服务后台运行.自动启动功能,实现一个真正的短信控制工具.本文的目的很简单,让 ...

  6. android: 接收和发送短信

    8.2    接收和发送短信 收发短信应该是每个手机最基本的功能之一了,即使是许多年前的老手机也都会具备这 项功能,而 Android 作为出色的智能手机操作系统,自然也少不了在这方面的支持.每个 A ...

  7. Android学习笔记之短信验证码的获取和读取

    PS:最近很多事情都拖拖拉拉的..都什么办事效率啊!!! 还得吐槽一下移动运营商,验证码超过五次的时候,直接把我的手机号封闭.真是受够了. 学习笔记: 1.Android之如何获取短信验证码. 2.如 ...

  8. Android-看操作系统短信应用源码-隐式意图激活短信界面

    选择模拟器Unknown Google Nexus,在选择system_process(系统进程) 操作模拟器的,操作系统短信应用,让操作系统短信打印日志,来查看: 然后就找到来,操作系统短信应用打印 ...

  9. Android监听返回键、Home键+再按一次返回键退出应用

    Android监听返回键需重写onKeyDown()方法 Home键keyCode==KeyEvent.KEYCODE_HOME @Override public boolean onKeyDown( ...

随机推荐

  1. Python Tkinter编程

    声明:主要是为了自己方便,所以把别人的教程搬到这里来,没有其他的意思. 如果有侵犯您的权益,请联系我QQ:3121922008 我会在第一时间妥善处理,抱歉. 还有其他的一些搜集的资源连接放在http ...

  2. excel之工作表工作簿保护暴力撤销

    excal之工作表工作簿保护暴力撤销 excel可以在审阅中设置工作表.工作簿的密码保护,但是当密码忘记或一些特殊情况下需要进行操作. 1.工作簿保护撤销 步骤一:将需要破解的excal文件后缀名改为 ...

  3. leetcode720

    public class Solution { public string LongestWord(string[] words) { var maxlist = new List<string ...

  4. 上传项目到git

    …or create a new repository on the command line   echo "# test" >> README.md git ini ...

  5. PHP 动态添加 Mcrypt 扩展库

    简介: PHP 动态添加 Mcrypt 扩展库,这是一个支持多种加密.解密算法.模式的扩展库. shell > php -m | grep mcrypt # 如果没有输出,就是缺少这个扩展 sh ...

  6. 【原】Coursera—Andrew Ng机器学习—编程作业 Programming Exercise 4—反向传播神经网络

    课程笔记 Coursera—Andrew Ng机器学习—课程笔记 Lecture 9_Neural Networks learning 作业说明 Exercise 4,Week 5,实现反向传播 ba ...

  7. Java字符串与文件的互转操作

    Java中有时候需要读取一个文本类的文件,将其转换为字符串,然后做进一步处理.Java中没有现成的API方法.   一.字符串转换为文件 /** * 将字符串写入指定文件(当指定的父路径中文件夹不存在 ...

  8. pyinstaller打包后运行提示找不到模块

    截止到2017年9月20号,pyinstaller只支持到python3.5,如果需要支持到3.6,需要自己在github上下载pyinstaller的开发版. 在打包时候,并没有提示错误,可以顺利打 ...

  9. Java核心技术-接口、lambda表达式与内部类

    本章将主要介绍: 接口技术:主要用来描述类具有什么功能,而并不给出每个功能的具体实现.一个类可以实现一个或多个接口. lambda表达式:这是一种表示可以在将来的某个时间点执行的代码块的简洁方法. 内 ...

  10. file_get_contents无法请求https连接的解决方法 php开启curl

    file_get_contents无法请求https连接的解决方法 方法1: PHP.ini默认配置下,用file_get_contents读取https的链接,就会如下错误: Warning: fo ...