首页 > 其他分享 >【Android】使用 ContentObserver 监控统状态信息

【Android】使用 ContentObserver 监控统状态信息

时间:2023-03-19 17:12:51浏览次数:41  
标签:ContentObserver void private public content 监控 import Android android

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 项目结构

img

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 监控统状态信息

标签:ContentObserver,void,private,public,content,监控,import,Android,android
From: https://www.cnblogs.com/zhyan8/p/17233628.html

相关文章