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方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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,取消注册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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、注意在配置文件中添加读取短信的权限:

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

注意:最小sdk为16.

4、如下运行截图:


控制台打印出的Log:

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

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器