Android自动填写验证码

  第四篇博客就来总结下项目中使用到的一个提升用户体验的功能: 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" />
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值