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. VSCODE中GIT配置

    1.问题:无法正常提交 问题描述 *使用vscode提交就会一直卡住**. 参考方案链接:VS CODE GIT 500 问题处理-pudn.com 根据这位博主的描述,应当是设置的这里选择的默认选项 ...

  2. pybind11

    fatal error: Python.h: no such file or directory 在使用pybind11时,如果不做调整可能就会出现这样的情况,Python.h一般出现在usr/inc ...

  3. Kafka的部分初始化参数的学习与整理

    Kafka的部分初始化参数的学习与整理 背景 前段时间跟同事一起处理过kafka的topic offset的retention 时间与 log 的retention时间不一致. 导致消息还有, 但是o ...

  4. [转帖]等待事件 enq:TX - row lock contention分析与解决

    6月30日,数据库发生了大量锁表.大概持续1小时,并且越锁越多.后来通过业务人员停掉程序,并kill掉会话后解决. 几天后再EM上查看CPU占用: CPU发生了明显等待. 主要是由于enq:TX - ...

  5. [转帖]OpenSSL版本历史

    OpenSSL版本历史 新闻日志 这是所有 OpenSSL 公告的简洁日志.它们几乎是发布通知. 日期物品 2021 年 7 月 29 日OpenSSL 3.0 的 Beta 2 现已推出.这是一个候 ...

  6. [转帖]线上一个隐匿 Bug 的复盘

    前言 之前负责的一个项目上线好久了,最近突然爆出一 Bug,最后评估影响范围将 Bug 升级成了故障,只因为影响的数据量有 10000 条左右,对业务方造成了一定的影响. 但因为不涉及到资金损失,Bu ...

  7. kafka的学习之二_kafka的压测与GUI管理

    kafka的学习之二_kafka的压测与GUI管理 第一部分创建topic cd /root/kafka_2.13-3.5.0 bin/kafka-topics.sh --create --boots ...

  8. shell补遗_一个巨简单的保证服务存活的脚本

    Shell补遗 背景 公司一台机器总是会在没有更新补丁的情况下启动失败. 查看所有的配置都没有问题. 但是就是不启动 没办法,准备写一个检查进行启动. 最近写shell很少. 所以总结一下. 思路 判 ...

  9. 【python】SSTI模版注入

    0x00  Python Vene环境及介绍 venv虚拟环境:创建和管理虚拟环境的模块 首先apt update更新一下包管理 安装你当前版本的python-venv 选择一个目录,安装venv虚拟 ...

  10. .NetCore开发人员首选框架---Bridge(Abp-VNext + Vue3)

    bridge系统是基于Abp-VNext+Vue3开发的一套前后端分离的通用权限管理系统,不论是单体服务,还是微服务都可在此基础上自由扩展,此框架组合可以说是集成了.netcore在BS架构领域最前沿 ...