• Android监听系统短信数据库变化-提取短信内容


    由于监听系统短信广播受到权限的限制,所以很多手机可能使用这种方式没法监听广播,从而没办法获取到系统短信,所以又重新开辟一条路。

    Android监听系统短信数据库内容变化使用场景:

    1、监听短信数据库的变化,添加删除修改,变化的时候会回调onChange方法

    2、提取刚刚变化的那条短信的内容

    备注:

    1、这种方式虽然一开始能够监听到数据变化,但是要判断是刚刚接手到的短信,还需要做一些处理,具体看代码

    2、这种方式需要从数据库里面去读取刚刚加入的那条短信,所以需要读取数据库权限,会弹出系统的权限申请框,所以注意使用时机

    import android.content.ContentResolver;
    import android.database.ContentObserver;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Handler;
    import android.text.TextUtils;
    
    /**
     * 数据库观察者
     */
    public class SmsDatabaseChaneObserver extends ContentObserver {
        // 只检查收件箱
        public static final Uri MMSSMS_ALL_MESSAGE_URI = Uri.parse("content://sms/inbox");
        public static final String SORT_FIELD_STRING = "_id asc";  // 排序
        public static final String DB_FIELD_ID = "_id";
        public static final String DB_FIELD_ADDRESS = "address";
        public static final String DB_FIELD_PERSON = "person";
        public static final String DB_FIELD_BODY = "body";
        public static final String DB_FIELD_DATE = "date";
        public static final String DB_FIELD_TYPE = "type";
        public static final String DB_FIELD_THREAD_ID = "thread_id";
        public static final String[] ALL_DB_FIELD_NAME = {
                DB_FIELD_ID, DB_FIELD_ADDRESS, DB_FIELD_PERSON, DB_FIELD_BODY,
                DB_FIELD_DATE, DB_FIELD_TYPE, DB_FIELD_THREAD_ID };
        public static int mMessageCount = -1;
        
        private static final long DELTA_TIME = 60 * 1000;
        private ContentResolver mResolver;
    
        public SmsDatabaseChaneObserver(ContentResolver resolver, Handler handler) {
            super(handler);
            mResolver = resolver;
        }
    
        @Override
        public void onChange(boolean selfChange) {
            onReceiveSms();
        }
    
        private void onReceiveSms() {
            Cursor cursor = null;
            // 添加异常捕捉
            try {
                cursor = mResolver.query(MMSSMS_ALL_MESSAGE_URI, ALL_DB_FIELD_NAME,
                        null, null, SORT_FIELD_STRING);
                final int count = cursor.getCount();
                if (count <= mMessageCount) {
                    mMessageCount = count;
                    return;
                }
                // 发现收件箱的短信总数目比之前大就认为是刚接收到新短信---如果出现意外,请神保佑
                // 同时认为id最大的那条记录为刚刚新加入的短信的id---这个大多数是这样的,发现不一样的情况的时候可能也要求神保佑了
                mMessageCount = count;
                if (cursor != null) {
                    cursor.moveToLast();
                    final long smsdate = Long.parseLong(cursor.getString(cursor.getColumnIndex(DB_FIELD_DATE)));
                    final long nowdate = System.currentTimeMillis();
                    // 如果当前时间和短信时间间隔超过60秒,认为这条短信无效
                    if (nowdate - smsdate > DELTA_TIME) {
                        return;
                    }
                    final String strAddress = cursor.getString(cursor.getColumnIndex(DB_FIELD_ADDRESS));    // 短信号码
                    final String strbody = cursor.getString(cursor.getColumnIndex(DB_FIELD_BODY));          // 在这里获取短信信息
                    final int smsid = cursor.getInt(cursor.getColumnIndex(DB_FIELD_ID));
                    if (TextUtils.isEmpty(strAddress) || TextUtils.isEmpty(strbody)) {
                        return;
                    }
                    // 得到短信号码和内容之后进行相关处理
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (cursor != null) {
                    try {  // 有可能cursor都没有创建成功
                        cursor.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    下面是对数据库观察者的注册,使用方式与广播类似,生命周期也需要自己控制,结合自己使用的Activity或者Service的生命周期来进行控制。

    public static final Uri SMS_MESSAGE_URI = Uri.parse("content://sms");
    private static SmsDatabaseChaneObserver mSmsDBChangeObserver;
    private static void registerSmsDatabaseChangeObserver(ContextWrapper contextWrapper) {
        //因为,某些机型修改rom导致没有getContentResolver
        try {
            SmsDatabaseChaneObserver = new SmsDatabaseChaneObserver(contextWrapper.getContentResolver(), new Handler());
            contextWrapper.getContentResolver().registerContentObserver(SMS_MESSAGE_URI, true, mSmsDBChangeObserver);
        } catch (Throwable b) {
        }
    }
    
    private static void unregisterSmsDatabaseChangeObserver(ContextWrapper contextWrapper) {
        try {
            contextWrapper.getContentResolver().unregisterContentObserver(SmsDatabaseChaneObserver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    监听一般放在Service中,所以需要在Service时创建时注册监听,Service销毁时取消监听

  • 相关阅读:
    d3js selections深入理解
    d3js scales深入理解
    d3js shape深入理解
    如何使用chrome devtool调试Mobile网页?
    为什么有时父元素无法包含子元素?
    base64编码以及url safe base64是怎么工作的?
    古老的CSS同高列问题
    springboot2.0整合redis的发布和订阅
    如何在centos7中设置redis服务器开机自启动
    1.Linux安装redis
  • 原文地址:https://www.cnblogs.com/popfisher/p/5455980.html
Copyright © 2020-2023  润新知