1 前言

使用ContentProvider实现跨进程通讯 中介绍了自定义 ContentProvider,为外界提供操作 SQLite 的接口。但是大多数情况下,服务端的 ContentProvider 不需要用户编写,用户只需要知道怎么调用就行,比如系统资源。因此,本文将以监控飞行模式状态和最新短信为例,讲解使用 ContentObserver 监控系统状态信息。

​ 常用的系统 URI 取值如下:

内容名称 URI常量名 URI常量值
联系人 ContactsContract.Contacts.CONTENT_URI content://com.android.contacts/contacts
联系人电话 ContactsContract.CommonDataKinds.Phone.CONTENT_URI content://com.android.contacts/data/phones
联系人邮箱 ContactsContract.CommonDataKinds.Email.CONTENT_URI content://com.android.contacts/data/emails
短信 Telephony.Sms.CONTENT_URI content://sms
采信 Telephony.Mms.CONTENT_URI content://mms
通话记录 CallLog.Calls.CONTENT_URI content://call_log/calls

2 项目结构

3 代码

(1)权限

​ 在 AndroidManifest.xml 中的 manifest 标签(application 同级标签)下添加读短信权限,如下:

<uses-permission android:name="android.permission.READ_SMS" />

(2)飞行模式监听类

​ AirplaneObserver.java

package com.zhyan8.content_o;

import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.provider.Settings; public class AirplaneObserver extends ContentObserver {
private ContentResolver mResolver;
private Handler mHandler;
private Uri mUri = Settings.System.getUriFor(Settings.System.AIRPLANE_MODE_ON); public AirplaneObserver(Context context, Handler handler) {
super(handler);
mResolver = context.getContentResolver();
mHandler = handler;
} @Override
public void onChange(boolean selfChange) {
try {
int isAirplaneOpen = Settings.System.getInt(mResolver, Settings.System.AIRPLANE_MODE_ON);
mHandler.obtainMessage(0x100, isAirplaneOpen).sendToTarget() ;
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
}
} public void registerObserver() {
mResolver.registerContentObserver(mUri, false, this);
} public void unregisterObserver() {
mResolver.unregisterContentObserver(this);
}
}

(3)短信监听类

​ SMSObserver.java

package com.zhyan8.content_o;

import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler; public class SMSObserver extends ContentObserver {
private ContentResolver mResolver;
private Handler mHandler;
private Uri mUri = Uri.parse("content://sms"); public SMSObserver(Context context, Handler handler) {
super(handler);
mResolver = context.getContentResolver();
mHandler = handler;
} @Override
public void onChange(boolean selfChange) {
String[] projection = new String[]{"address", "body", "date"}; //查询的列属性
String selection = String.format("date>%d", System.currentTimeMillis()-1000*3); //查询条件(1秒内的短信)
Cursor cursor = mResolver.query(mUri, projection, selection, null,"date desc");
if(cursor!=null && cursor.moveToNext()){
String sender = cursor.getString(0);
String content = cursor.getString(1);
String msg = "sender: " + sender + "\ncontent: \n " + content;
cursor.close();
mHandler.obtainMessage(0x101, msg).sendToTarget();
}
} public void registerObserver() {
mResolver.registerContentObserver(mUri, true, this);
} public void unregisterObserver() {
mResolver.unregisterContentObserver(this);
}
}

(4)主类

​ MainActivity.java

package com.zhyan8.content_o;

import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log; public class MainActivity extends AppCompatActivity {
private SMSObserver mSMSObserver;
private AirplaneObserver mAirplaneObserver;
public static final String[] permissions = {"android.permission.READ_SMS"}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
} private void init() {
if(Build.VERSION.SDK_INT>=23){
requestPermissions(permissions,1);
}
mAirplaneObserver = new AirplaneObserver(this, mHandler);
mSMSObserver = new SMSObserver(this, mHandler);
mAirplaneObserver.registerObserver();
mSMSObserver.registerObserver();
} private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
String content = msg.obj.toString();
switch (msg.what) {
case 0x100:
Log.e("xxx", "飞行模式状态改变了: " + content);
break;
case 0x101:
Log.e("xxx", "收到短信:\n" + content);
break;
}
}
}; @Override
public void onDestroy() {
mAirplaneObserver.unregisterObserver();
mSMSObserver.unregisterObserver();
super.onDestroy();
}
}

4 效果展示

​ (1)点击2次飞行模式按钮,打印日志如下:

2020-11-23 02:17:56.065 2785-2785/com.zhyan8.content_o E/xxx: 飞行模式状态改变了: 1
2020-11-23 02:17:57.887 2785-2785/com.zhyan8.content_o E/xxx: 飞行模式状态改变了: 0

​ (2)给10086 发送短信,内容为“11”,会收到【套餐查询】、【语音】、【流量】已使用和剩余信息,打印日志如下:

2020-11-23 02:18:12.856 2785-2785/com.zhyan8.content_o E/xxx: 收到短信:
sender: 10086
content:
【套餐查询】尊敬的客户,您好!截至11月23日2时18分,扣除您已产生的消费(34.76元)后,您当前余额38.71元。 您各项套餐的准实时消费情况如下:
【语音】本月套内包含100分钟,剩余97分钟。
1、校园青春卡大流量套餐48元:本月套内包含国内主叫100分钟,剩余97分钟。 【流量】本月套内包含20GB,具体明细如下:
1、校园青春卡大流量套餐48元:本月套内包含国内流量(套内)20GB,剩余18.30GB。
仅供参考,具体以月结账单为准。
【中国移动】

​ 声明:本文转自【Android】使用 ContentObserver 监控统状态信息

【Android】使用 ContentObserver 监控统状态信息的更多相关文章

  1. Zabbix监控Nginx状态信息

    首先要检查Nginx是否安装了 http_stub_status_module 模块,通过下面的命令可以看到编译参数.yum安装的默认会带有这个模块. [root@kafka60 ~]# /data/ ...

  2. linux系统常用监控系统状态信息命令

    [root@bogon ~]# uptime #平均负载 23:33:21 up 2:09, 3 users, load average: 0.02, 0.05, 0.05 [root@bogon ~ ...

  3. Android中判断网络连接是否可用及监控网络状态

    Android中判断网络连接是否可用及监控网络状态 作者: 字体:[增加 减小] 类型:转载 获取网络信息需要在AndroidManifest.xml文件中加入相应的权限,接下来详细介绍Android ...

  4. Android 获得本地IP地址、外网IP地址、本设备网络状态信息、本地Mac地址

    本地内网IP和外网IP的区别: 根据我的经验一台电脑需要两个ip才可以上网,一个是本地的内网ip 一个是外网的ip 本地的ip 一般是192.168.1.2这种样子  只要在不同的路由器上可以重复 外 ...

  5. Android记录3--ExpandableListView使用+获取SIM卡状态信息

    Android记录3--ExpandableListView使用+获取SIM卡状态信息 2013年8月9日Android记录 ExpandableListView是一个可以实现下拉列表的控件,大家可能 ...

  6. Nginx 开启status用以监控状态信息

    Nginx 可以通过with-http_stub_status_module模块来监控nginx的一些状态信息.1.通过nginx -V来查看是否有with-http_stub_status_modu ...

  7. Android网络性能监控方案

    阿里云 云原生应用研发平台EMAS 刘宝文(木睿) 背景 移动互联网时代,移动端极大部分业务都需要通过App和Server之间的数据交互来实现,所以大部分App提供的业务功能都需要使用网络请求.如果因 ...

  8. Linux watch 监控系统状态

    1.linux下watch命令的基本用法 # watch --helpUsage: watch [-dhntv] [--differences[=cumulative]] [--help] [--in ...

  9. Android 组件系列-----Activity保存状态

    本篇随笔将详细的讲解Activity保存状态的概念,也就是saving activity state. 一.Activity状态保持概念 保存Activity的状态是非常重要的,例如我们在玩一个游戏的 ...

  10. Zabbix 监控 Nginx 状态

    简介: 如何使用 Zabbix 监控 Nginx 状态 ? 1.获取 Nginx 状态( HTTP Stub Status ) shell > /usr/local/nginx/sbin/ngi ...

随机推荐

  1. [转帖]Python学习之十七_django的入门

    Python学习之十七_django的入门 前言 Python学习了一周, 慢慢总结摸索. 自己还是有多不会的地方. 感慨这些年浪费的时间. 所有的时间都是选择大于努力. 努力最多感动自己. 生活是需 ...

  2. [转帖]PostgreSQL任意命令执行漏洞利用(CVE-2019-9193)

    https://zhuanlan.zhihu.com/p/143443516   最近没事曰曰内网,偶然发现了一个使用空密码的pg(是的,连爆破都省了).用navicat连上去看了下几个库都是一些业务 ...

  3. [转帖]坑:jmeter代理服务器录制脚本出现target controller is configured to "use recording Controller" but no such controller exists...

    配置好代理服务器后,运行代理服务器 run 报错: target controller is configured to "use recording Controller" bu ...

  4. [转帖]sqlplus与shell互相传值的几种情况

    https://www.cnblogs.com/youngerger/p/9068888.html sqlplus与shell互相传值的几种情况 情况一:在shell中最简单的调用sqlplus $c ...

  5. [转帖]Linux系统awk命令详解

    AWK 是一种处理文本文件的语言,是一个强大的文本分析工具. 之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 ...

  6. [转帖]SkyWalking集成logback

    1.引入skywalking的jar包,导入的包和agent版本一致 <dependency> <groupId>org.apache.skywalking</group ...

  7. SQLServer 隔离级别的简单学习

    SQLServer 隔离级别的简单学习 背景 上周北京一个项目出现了卡顿的现象. 周末开发测试加紧制作测试发布了补丁,但是并没有好转. 上周四时跟研发訾总简单沟通过, 怀疑是隔离级别有关系.但是不敢确 ...

  8. 通过mat获取OOM时对象信息的方法与过程

    通过mat获取OOM时对象信息的方法与过程 背景 如果谁的耐心不好, 就让他去看MAT里的objects信息. 有项目出现了OOM的情况 我在公司这边有一台内存比较高的Win10机器. 然后帮助同事进 ...

  9. vite构建打包产物

    构建打包产物 build: { assetsInlineLimit: 10240, //静态资源(不会包含js,css)不超过10kb 转化为 base64 [不好含css js] outDir: & ...

  10. CTF&爬虫:掌握这些特征,一秒识别密文加密方式

    关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 前言 爬虫工程师在做加密参数逆向的时候,经常会遇到各种各样的加密算法.编码.混淆,每个算法都有其对应的特征,对于一些较小的网站, ...