Android基础开发-读写短信

1、利用ContentObserver监听短信

内容观察器ContentObserver给目标内容注册一个观察器,目标内容的数据一旦发生改变,观察器规定好的动作马上触发,从而执行开发者预定义的代码。

参数原理:

notifyForDescendents 通知子孙后代
        false:表示精确匹配,即只匹配Uri。

        true可以表示同时匹配其派生的Uri
假设UriMatcher 里注册的Uri共有以下类型
1、content://AUTHORITIES/table
2、content://AUTHORITIES/table/#
3、content://AUTHORITIES/table/subtable
假设我们当前需要的Uri为content://AUTHORITIES/stuent:
         如果我们需要发生变化的Uri为3
         当notifyForDescendents为false,那么该ContentObserver就监听不到

麻烦的地方:

来到一条短信,onChange可能会执行两到三次
        mUri===content://sms/raw/20
        mUri===content://sms/inbox/20
android 7.0以上的系统,点击标记为已读,也会调用一次
        mUri == content://sms
收到一条短信都是Uri后边都会有一个确切的数字,对应数据库的_id,比如上边的20

参考代码:

package com.example.client;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

public class MonitorSmsActivity extends AppCompatActivity {
    SmsGetObserver smsGetObserver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_monitor_sms);

        //给指定Uri注册 内容观察器,一旦数据发生变化,就会触发观察器的onChange方法
        Uri uri = Uri.parse("content://sms");
        /**
         * notifyForDescendents 通知子孙后代
         * false:表示精确匹配,即只匹配Uri。tru可以表示同时匹配其派生的Uri
         * 假设UriMatcher 里注册的Uri共有以下类型
         * 1、content://AUTHORITIES/table
         * 2、content://AUTHORITIES/table/#
         * 3、content://AUTHORITIES/table/subtable
         * 假设我们当前需要的Uri为content://AUTHORITIES/stuent:
         *  如果我们需要发生变化的Uri为3
         *  当notifyForDescendents为false,那么该ContentObserver就监听不到
         */
        smsGetObserver = new SmsGetObserver(this);
        getContentResolver().registerContentObserver(uri, true, smsGetObserver);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        getContentResolver().unregisterContentObserver(smsGetObserver);
    }

    private static class SmsGetObserver extends ContentObserver {

        private Context mContext;

        public SmsGetObserver(Context context) {
            super(new Handler(Looper.getMainLooper()));
            this.mContext = context;
        }

        /**
         * 麻烦的地方:来到一条短信,onChange可能会执行两到三次
         * mUri===content://sms/raw/20
         * mUri===content://sms/inbox/20
         * android 7.0以上的系统,点击标记为已读,也会调用一次
         * mUri == content://sms
         * 收到一条短信都是Uri后边都会有一个确切的数字,对应数据库的_id,比如上边的20
         */
        @Override
        public void onChange(boolean selfChange, @Nullable Uri uri) {
            super.onChange(selfChange, uri);

            if (uri == null) {
                return;
            }
            if (uri.toString().contains("content://sms/raw")
                    || uri.toString().equals("content://sms")) {
                return;
            }
            //通过内容解析器获取符合条件的结果集游标
            Cursor cursor = mContext.getContentResolver().query(uri, new String[]{"address", "body", "date"}, null, null, "date desc");
            if(cursor.moveToNext()){
                //短信的发送号码
                String sender = cursor.getString(cursor.getColumnIndex("address"));
                //短信内容
                String content = cursor.getString(cursor.getColumnIndex("body"));
                Log.d("pansd",String.format("sender:%s,content:%s",sender,content));


            }
            cursor.close();

        }
    }

}

执行结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值