短信验证码自动填写

在应用的开发过程中 我们需要向用户发送验证码以验证用户的身份,但是用户收到短信验证码后,需要离开当前的应用去查看验证码,然后再返回我们的应用来填写验证码,这样会给用户带来诸多的不便。android系统上的应用可以读取到手机上的短信,我们可以通过这个特性去获取我们想要的内容,显示到我们的输入框中。

本次我们实现的功能要用到ContentObserver,当我们发送一条短信到我们的手机上时,手机会自动调用ContentObserver类中的指定方法,来通知我们的应用短信内容的改变,我们提取内容中的信息 填写到我们的输入框中 

短信验证码自动填写_第1张图片


 在这里我和大家说一个与之相关的设计模式:观察者模式:

观察者模式是软件设计模式中的一种,在此模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常是透过呼叫各观察者所提供的方法来实现。此模式通常被用来实现时间处理系统。

观察者模式(Observer)完美的将观察者和被观察者的对象分离开,在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。

观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。

应用到我们的这个例子上来说,就是首先我们在我们的应用刚开始运行的过程中,向我们的系统短信应用注册一个观察者,就告诉我们的短信应用说,我是你的观察者,当你自己的状态发生了变化后,你就通知我。

我们来看一下观察者的基本流程:

观察者将自己注册到被观察对象(subject)中,被观察者对象将观察者存放在一个容器(Container)里。

被观察者对象发生变化,从容器中得到所有注册过的观察者,将变化通知观察者。

观察者告诉观察者要撤销观察,被观察者从容器中将观察者去除。

接下来说下ContentObservber类

ContentObserver 

内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentOberver所观察的Uri发生变化时,便会触发它。

观察特定Uri的步骤如下:

1.创建我们特定的ContentOberver派生类,必须重载父类构造方法,必须重载onChange()方法去处理回调后的功能实现。
2.利用context.getContetResolover()获得ContentResolover对象,接着调用registerContentObeserver()方法去注册内容观察者。
3.由于ContentObsever的生命周期不同步于Activity和Service等,因此,在不需要时,需要手动的调用unregisterContentObserver()去取消注册。
好了接下来开始编写代码,首先写个简单的布局
xml version="1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
            android:ems="10"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/et_validateCode"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

创建一个ContentObserver的派生类 去实现获取到短信的一些功能实现
public class SmsObserver extends ContentObserver {
    private static final String TAG = SmsObserver.class.getSimpleName();
    private Context mContext;
    private Handler mHandler;

    public SmsObserver(Context mContext, Handler handler) {
        super(handler);
        this.mContext = mContext;
        this.mHandler = handler;
    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        super.onChange(selfChange, uri);
        Log.e(TAG, "sms has changed !");
        Log.e(TAG, uri.toString());

        String code = "";

        if (uri.toString().equals("content://sms/raw")) {
            return;
        }
        Uri inboxUri = Uri.parse("content://sms/inbox");
        Cursor c = mContext.getContentResolver().query(inboxUri, null, null, null, "date desc");
        if (c != null) {
            if (c.moveToFirst()) {
                String address = c.getString(c.getColumnIndex("address"));
                String body = c.getString(c.getColumnIndex("body"));

                Log.e(TAG, "发件人为:" + address + "" + "内容为:" + body);

                Pattern pattern = Pattern.compile("\\d{6}");
                Matcher matcher = pattern.matcher(body);
                if (matcher.find()) {
                    code = matcher.group(0);
                    Log.e(TAG, "code is " + code);
                    mHandler.obtainMessage(1, code).sendToTarget();
                }
            }
            c.close();
        }
    }
}

接下来 建一个Activity来注册这个派生类 并且建一个handler接受发送的消息,显示我们要的验证码

public class SmsActivity extends Activity{
    private  SmsObserver observer;
    private EditText et_validateCode;
    private Handler mHadler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what==1){
                String code= (String) msg.obj;
                //update the ui
                et_validateCode.setText(code);
            }
        }
    };
    @Override
    protected void onPause() {
        super.onPause();
        getContentResolver().unregisterContentObserver(observer);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sms);
        et_validateCode= (EditText) findViewById(R.id.et_validateCode);
        observer=new SmsObserver(SmsActivity.this,mHadler);
        Uri uri=Uri.parse("content://sms");
        getContentResolver().registerContentObserver(uri,true,observer);
    }
}

好了 到这里 一个简单的短信验证码自动填写的功能就实现了 

你可能感兴趣的:(android)