第四篇博客就来总结下项目中使用到的一个提升用户体验的功能: Android自动填写验证码
  从字面上来看,很明显的可以看出它的实现流程:监听->有改变->获取信息->改变ui

观察者模式

  观察者模式是软件设计模式中的一种,在此模式中,一个目标物件管理所有相依于它的观察者物件,并且在本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统
  观察者模式Observer完美的将观察者和被观察的对象分离开,在模块之间划定接线,提高应用程序的可维护性和重用性。同时定义了对象间一种一对多的以来关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。
观察者:Observer将自己注册到被观察对象中,被观察对象将观察者存放在一个容器里
被观察:当被观察者对象发生了某种变化,从容器中得到所有注册过的观察者,将变化通知观察者
撤销观察:观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除
ContentObserver
  内容观察者,目的是观察捕捉特定uri引起的数据库的变化,继而做一些相应的处理,类似于数据库中的触发器。
  流程如下:
  1. 创建ContentObserver派生类,重载onChange()方法处理回调。
  2. 利用context.getContentResolover() 获得ContentResolove对象,调用registerContentObserver()方法去注册
  3. 在不需要使用时(例如验证码获取成功后),调用unregisterContentObserver()取消注册

实现

  在我们创建的SmsObserver类中,必须要实现onChange方法,这是一个检测uri是否变化的方法。
  而验证短信发来的时候,会调用两次,第一次的uri会提示raw,此时只是表示短信到了,还没有写入数据库中。而第二次变化的时候才是我们需要接收与检测的,此时才表示短信已经被写入了数据库中。
而对于相关验证码的提取,使用正则表达式的方式,获取连续的4个数字(根据自己的需要)。
 另外,在AndroidManifest文件中添加Read_SMS的权限

相关代码如下:

package com.screform.mmd.customview;import android.content.Context;import android.database.ContentObserver;import android.database.Cursor;import android.net.Uri;import android.os.Handler;import android.util.Log;import com.screform.mmd.aty.Aty_Register;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * Created by lizhongquan on 15-11-18. * Class to Observer the sms and notify to setText in editText_IdentifyingCode */public class SmsObserver extends ContentObserver {    private Context context;    private Handler handler;    /** * Creates a content observer. * * @param handler The handler to run {@link #onChange} on, or null if none. */    public SmsObserver(Context context, Handler handler) {        super(handler);        this.context = context;        this.handler = handler;    }    /** * code ChangeListener * * @param selfChange change or not * @param uri the uri of event */    @Override    public void onChange(boolean selfChange, Uri uri) {        super.onChange(selfChange, uri);        Log.d("info", "SMS is changed");        Log.d("info", uri.toString());        // When the sms is coming, it will be change twice.        // the first time change is not the one we need.        // The sms is not writed into the database in this time        if (uri.toString().equals("content://sms/raw")) {            return;        }        // handle the second change        // get the inboxUri        Uri inboxUri = Uri.parse("content://sms/inbox");        // query the inbox        // get the sms        Cursor mCursor = context.getContentResolver().query(inboxUri, null, null, null, "date desc");        if (null != mCursor) {            if (mCursor.moveToFirst()) {                String address = mCursor.getString(mCursor.getColumnIndex("address"));                String body = mCursor.getString(mCursor.getColumnIndex("body"));                Log.d("info", "address is :" + address + ", body is " + body);                if (address.equals("106900321100")) {                    // use a regular expression to resolve and get the identifying code                    // get the four consecutive numbers                    Pattern pattern = Pattern.compile("(\\d{4})");                    Matcher matcher = pattern.matcher(body);                    if (matcher.find()){                        Log.d("info", "Identifying code is " + matcher.group(0));                        handler.obtainMessage(Aty_Register.GETSMS, matcher.group(0))                                .sendToTarget();                    }                }            }        }        // close mCursor        mCursor.close();    }}

在Aty_Register.java中:

initObserver():

 Uri uri = Uri.parse("content://sms"); smsObserver = new SmsObserver(Aty_Register.this, handler); getContentResolver().registerContentObserver(uri, true, smsObserver);

onStop()中: 取消注册

@Override    protected void onStop() {        super.onStop();        getContentResolver().unregisterContentObserver(smsObserver);        Log.d("info", "unregister");    }

handler中: 更新UI

case GETSMS:      editText_IdentifyingCode.setText(msg.obj.toString());      break;

AndroidManifest:

<uses-permission android:name="android.permission.READ_SMS" />

更多相关文章

  1. No.11 使用firewall配置的防火墙策略的生效模式
  2. Android(安卓)四大组件之Activity
  3. Android(安卓)避免重复提交
  4. 调用对象[置顶] Android通过调用Webservice实现天气预报
  5. Android窗口管理服务WindowManagerService对窗口的组织方式分析
  6. Android艺术探索读书笔记 -IPC机制
  7. Android(安卓)MTP框架和流程分析
  8. Android内存泄露浅析
  9. Android(安卓)中内存泄漏的原因分析及解决方案

随机推荐

  1. Android(安卓)根文件系统启动分析
  2. Android(安卓)相对布局 简单编程
  3. android之CheckBox
  4. Android(安卓)之 资源自适应与国际化
  5. EventBus Usage
  6. Android条形统计图实现
  7. ViewPager介绍
  8. Android(安卓)WebView
  9. android 查看apk中资源文件
  10. android 操作sqlite数据库