android自动获取短信验证码


这里主要使用了ContentObserver类(观察者模式类)来监听短信的变化,然后通过正则表达式,提取出短信,然后在子线程中更新UI,显示验证码。
所谓的观察者模式,它是软件设计模式的一种,在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。观察者模式(Observer)完美的将观察者和被观察的对象分离开,在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。
ContentObserver,内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当 ContentObserver 所观察的Uri发生变化时,便会触发它。
观察特定Uri的步骤如下:

  1. 、创建我们特定的 ContentObserver 派生类,必须重载父类构造方法,必须重载 onChange() 方法去处理回调后的功能实现。
  2. 利用 context.getContentResolover() 获得 ContentResolove 对象,接着调用 registerContentObserver() 方法去注册内容观察者。
  3. 由于 ContentObserver 的生命周期不同步于 Activity 和 Service 等,因此,在不需要时,需要手动的调用 unregisterContentObserver() 去取消注册。

具体使用:

1、继承ContentObserver,重写onChange方法

package com.tx.testsms;
/**
 * 自动读取短信验证码
 */
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;

public class SmsObserver extends ContentObserver {

    private Context mContext;
    private Handler mHandler;
    private String tel_phone = "";

    private String code;

    public void setTel_phone(String tel_phone) {
        this.tel_phone = tel_phone;
    }

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

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        // TODO Auto-generated method stub
        super.onChange(selfChange, uri);

        if(uri.toString().equals("content:://sms//raw")){
            return;
        }

        Uri inboxUri = Uri.parse("content://sms//inbox");

        Cursor cursor = mContext.getContentResolver().
                query(inboxUri, null, null, null, "date desc");

        if(cursor!=null){
            if(cursor.moveToFirst()){
                String address = cursor.getString(cursor.getColumnIndex("address"));
                Log.i("test", "短信验证码为:--------"+address);

                String body = cursor.getString(cursor.getColumnIndex("body"));
                Log.i("test", "uri---------"+inboxUri);

                if(address.equals(tel_phone)){

                    Pattern pattern = Pattern.compile("(\\d{4})");
                    Matcher matcher = pattern.matcher(body);

                    if(matcher.find()){
                        code = matcher.group(0);
                        Log.i("test", "短信验证码为:--------"+code);
                        mHandler.obtainMessage(
                                MainActivity.MSG_RECEIVED_CODE,code).sendToTarget();
                    }

                }

            }
            cursor.close();
        }
    }
}

2、在MainActivity中注册监听,在子线程中更更新显示UI,并复写onDestroy,取消注册

package com.tx.testsms;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    public static final int MSG_RECEIVED_CODE = 1;

    private SmsObserver mSmsObserver;
    private Handler mHandler;

    private EditText metPhone;
    private TextView mtvCode;
    private Button mbtnButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);

        metPhone = (EditText) findViewById(R.id.phone);
        mbtnButton = (Button) findViewById(R.id.btn);
        mtvCode = (TextView) findViewById(R.id.code);

        /**
         * 设置手机号,拦截固定的手机号
         */

        mbtnButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                mSmsObserver.setTel_phone(metPhone.getText().toString());
            }
        });

        /**
         * 在子线程中更新UI
         */
        mHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                // TODO Auto-generated method stub
                super.handleMessage(msg);
                if(msg.what == MSG_RECEIVED_CODE){
                    mtvCode.setText("四位短信验证码为:"+msg.obj.toString());
                    Toast.makeText(getApplicationContext(), msg.obj.toString(), Toast.LENGTH_SHORT).show();
                }
            }
        };

        <span style="color:#ff0000;">/**
         * 实例化ContentObserver,注册短信监听
         */
        mSmsObserver = new SmsObserver(getApplicationContext(), mHandler);
        Uri  uri = Uri.parse("content://sms");
        getContentResolver().registerContentObserver(uri, true, mSmsObserver);</span>

    }

    /**
     * 由于 ContentObserver 的生命周期不同步于 Activity 和 Service ,
     * 因此需要手动取消注册
     * 
     */

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        <span style="color:#ff0000;">getContentResolver().unregisterContentObserver(mSmsObserver);</span>
    }
}

3、注意在配置文件中添加读取短信的权限:

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

注意:最小sdk为16.

4、如下运行截图:


控制台打印出的Log:

例子源代码:http://download.csdn.net/detail/txadf/9188791


文章作者: imtianx
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明来源 imtianx !
评论
 上一篇
android 打开其他应用 android 打开其他应用
在开发中,有时需要在自己的应用中打开其他应用,自己写了两个方法来获取手机上安装的所有应用。这里主要以打开支付宝为例。(1)、获取手机上的所有应用,将其放在一个list中。 private List<PackageInfo> ge
下一篇 
android SQLite学习手册 android SQLite学习手册
在实际的应用中,SQLite作为目前最为流行的开源嵌入式关系型数据库,在系统的架构设计中正在扮演着越来越为重要的角色。和很多其它嵌入式NoSQL数据库不同的是,SQLite支持很多关系型数据库的基本特征,这在数据移植、程序演示等应用中有着
  目录