看啥推荐读物
专栏名称: 淼森007
Android开发
今天看啥  ›  专栏  ›  淼森007

Android中内容观察者的使用(读取短信内容)

淼森007  · 掘金  ·  · 2021-02-02 15:32
阅读 76

Android中内容观察者的使用(读取短信内容)

上次我们说了内容观察者的使用,细心的朋友会发现,我们需要主动进行查询才可以知道数据库是否有了变化。如果我们想在数据库变化的第一时间就知道怎么办?这里我们以读取短信数据为例,说明内容观察者的使用方法。

首先我们需要加入一个权限

<uses-permission android:name="android.permission.READ_SMS"/>
复制代码

有了这个权限我们才可以获取短信的内容

接着我们要在需要读取短息的界面加入观察的代码,示例代码如下

public class GcdxnrActivity extends WaterPermissionActivity<GcdxnrModel> implements GcdxnrCallback {

    private Handler mHandler = new Handler();//声明一个处理器对象
    private SmsGerObserver mObserver;//声明一个短信获取的观察器对象
    private static Uri mSmsUri;//声明一个系统短信提供器的Uri对象
    private static String[] mSmsColumn;//声明一个短信记录的字段数组
    private TextView tv_chect_flow;

    @Override
    protected GcdxnrModel getModelImp() {
        return new GcdxnrModel(this,this);
    }

    @Override
    protected int getContentLayoutId() {
        return R.layout.activity_gcdxnr;
    }

    @Override
    protected void initWidget() {
        tv_chect_flow = findViewById(R.id.tv_chect_flow);
        requestPermission(READ_SMS);
    }

    @Override
    protected void doSMS() {
        initSmsObserver();
    }

    /**
     * 初始化短信观察器
     */
    private void initSmsObserver(){
        mSmsUri = Uri.parse("content://sms");
        mSmsColumn = new String[]{"address","body","date"};
        //创建一个短信观察器对象
        mObserver = new SmsGerObserver(this,mHandler);
        //给指定Uri注册内容观察器,一旦Uri内部发生数据变化,就出发观察器的onChange方法
        getContentResolver().registerContentObserver(mSmsUri,true,mObserver);
    }

    /**
     * 在页面销毁时触发
     */
    @Override
    protected void onDestroy() {
        //注销内容观察器
        getContentResolver().unregisterContentObserver(mObserver);
        super.onDestroy();
    }

    /**
     * 定义一个短信获取的观察器
     */
    private static class SmsGerObserver extends ContentObserver {

        private Activity mActivity;//声明一个上下文对象
        private GcdxnrActivity mainActivity;

        public SmsGerObserver(Activity activity, Handler handler){
            super(handler);
            mActivity = activity;
            mainActivity = (GcdxnrActivity) activity;
        }

        public void onChange(boolean selfChange){
            String sender = "";
            String content = "";
            //构建一个查询短信的条件语句,这里使用移动号码测试,故而查找10086发来的短信
            String selection = String.format("address='1008611' and date>%d",System.currentTimeMillis() - 1000*60);
            //通过内容解析器获取符合条件的结果集游标
            Cursor cursor = mActivity.getContentResolver().query(mSmsUri,mSmsColumn,selection,null,"date desc");
            //循环取出游标所指向的所有短信记录
            while (cursor.moveToNext()){
                sender = cursor.getString(0);
                content = cursor.getString(1);
                break;
            }
            cursor.close();//关闭数据库游标
            mainActivity.setText("发送者:"+sender+"\n"+"内容:"+content);
            super.onChange(selfChange);
        }
    }

    public void setText(String text){
        if (tv_chect_flow!=null) {
            tv_chect_flow.setText(text);
        }
    }
}
复制代码

首先我们可以看到

requestPermission(READ_SMS);
复制代码

这里是请求了一个Manifest.permission.READ_SMS动态权限,doSMS()是用户同意权限后执行的方法。我们在这里执行了initSmsObserver()方法,即初始化观察器的方法。大家可以使用自己的动态权限请求的方法。

如果数据库发生了改变,则会调用onChange方法。sender是短信发送者,content是短信的内容。

String selection = String.format("address='1008611' and date>%d",System.currentTimeMillis() - 1000*60);
复制代码

这个代码中指定了要查询的短信是哪个号码发送的,以及要查询多久以前的短信。

大家有什么疑问都可以在评论区给我留言。




原文地址:访问原文地址
快照地址: 访问文章快照