转载自:https://blog.csdn.net/VirusDerekRuler/article/details/78506522
现在开发越来越注重用户体验了,现今Android基本都有短信验证功能,那今天就实现一个自动填写短信验证码的小Demo,其中涉及有观察者模式、以及使用Handler来实现UI的更新。
我们还是先了解一下有关手机短信的一些知识
URI主要有:
content://sms/ 所有短信
content://sms/inbox 收件箱
content://sms/sent 已发送
content://sms/draft 草稿
content://sms/outbox 发件箱
content://sms/failed 发送失败
content://sms/queued 待发送列表
sms主要结构:
_id:短信序号,如100
thread_id:对话的序号,如100,与同一个手机号互发的短信,其序号是相同的
address:发件人地址,即手机号,如+86138138000
person:发件人,如果发件人在通讯录中则为具体姓名,陌生人为null
date:日期,long型,如1346988516,可以对日期显示格式进行设置
protocol:协议0SMS_RPOTO短信,1MMS_PROTO彩信
read:是否阅读0未读,1已读
status:短信状态-1接收,0complete,64pending,128failed
type:短信类型1是接收到的,2是已发出
body:短信具体内容
service_center:短信服务中心号码编号,如+8613800755500
第一种通过短信数据库获取短信内容
那我们接下来看下我们的Activity
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
public static final int SMG_RECEIVED_CODE = 1;
private SmsObserver smsObserver;
private static Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what == SMG_RECEIVED_CODE){
String code = (String) msg.obj;
//更新UI
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
smsObserver = new SmsObserver(MainActivity.this,mHandler);
Uri uri = Uri.parse("content://sms");
getContentResolver().registerContentObserver(uri,true,smsObserver);//注册观察者
}
@Override
protected void onPause() {
super.onPause();
getContentResolver().unregisterContentObserver(smsObserver);//取消观察者
}
}
现在再来看下我们的SmsObserver类
public class SmsObserver extends ContentObserver{
private static final String TAG = "SmsObserver";
private Context mContext;
private Handler mHandler;
public SmsObserver(Context context, Handler handler) {
super(handler);
this.mContext = context;
this.mHandler = handler;
}
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
Log.e(TAG, "onChange: "+ uri.toString());
String code="";
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"));
String body = cursor.getString(cursor.getColumnIndex("body"));
if(!address.toString().equals("指定发送短信号码")){
return;
}
Log.e(TAG, "onChange: "+ address+" "+body);
Pattern pattern = Pattern.compile("(\\d{6})");//连续6个数字的验证码
Matcher matcher = pattern.matcher(body.toString());
if(matcher.find()){
code = matcher.group(0);
//发送消息
mHandler.obtainMessage(MainActivity.SMG_RECEIVED_CODE ,code).sendToTarget();
}
}
cursor.close();
}
}
}
记得加权限哦
<uses-permission android:name="android.permission.READ_SMS" />
主Activity
private static Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == BC_SMS_RECEIVE) {
String code = (String) msg.obj;
//更新UI
}
};
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiver = new SmsBroadcastReceiver(MainActivity.this, handler, 6);
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(receiver, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
//自己的一个广播接收器
public class SmsBroadcastReceiver extends BroadcastReceiver {
private Context context;
private Handler handler;
private int codeLength = 0;
public SmsReceiveBroadcastReceiver(Context context, Handler handler) {
this.context = context;
this.handler = handler;
}
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Object[] objects = (Object[]) bundle.get("pdus");
if (objects != null) {
String phone = null;
StringBuffer content = new StringBuffer();
for (int i = 0; i < objects.length; i++) {
SmsMessage sms = SmsMessage.createFromPdu((byte[]) objects[i]);
phone = sms.getDisplayOriginatingAddress();
content.append(sms.getDisplayMessageBody());
}
CodeAndSend(content.toString());
}
}
private void CodeAndSend(String content) {
Pattern pattern = Pattern.compile("(\\d{6})");//连续6个数字的验证码
Matcher matcher = pattern.matcher(content);
if (matcher.find()) {
String code = matcher.group(0);
handler.obtainMessage(MainActivity.BC_SMS_RECEIVE, code).sendToTarget();
}
}
}
加权限
<uses-permission android:name="android.permission.RECEIVE_SMS" > </uses-permission>
<uses-permission android:name="android.permission.READ_SMS" > </uses-permission>
备注:
我用的是第一种,亲测有效! 反正Vivo手机是没有问题的,一定要记得权限申请! 其他品牌的手机,不知道是否有用,我这里没有测试机!