在使用App的时候,经常需要接收短信验证码进行身份验证,有的App在收到短信后,能够自动在需要填写验证码的地方自动填写验证码,这样的话就不需要手动再填写,很好的提升用户体验。
如何实现这个功能呢?我们通常会想到通过注册广播来实现。实现步骤如下:
首先,需要申请监控短信接收权限以及读取短信权限
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
然后,写一个类继承BroadcastReceiver
public class SmsBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if(bundle != null){
Object[] datas = (Object[]) bundle.get("pdus");
for(Object data : datas){
byte[] sms = (byte[]) data;
SmsMessage message = SmsMessage.createFromPdu(sms);
// 发送人号码
String number = message.getOriginatingAddress();
// 短信内容
String content = message.getMessageBody();
// 发送时间
Date date = new Date(message.getTimestampMillis());
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(date);
Log.e("Receiver", "发送号码:" + number +
" 发送内容:" + content +
" 发送时间" + time);
}
}
}
}
接下来注册广播,注册的方法有两种:
(1)在AndroidManifest.xml中注册
<receiver android:name="com.example.smstest.SmsBroadcastReceiver">
<intent-filter android:priority="999">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
这里的priority数值越大,优先级越高。
(2)使用Java代码进行注册
IntentFilter filter = new IntentFilter(); filter.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(new SmsBroadcastReceiver(), filter);
在MainActivity的onCreate()中进行注册,就可以通过日志查看接收到的短信了。日志如下:
在onReceive中,为什么获取短信内容是bundle.get(“pdus”)呢?
感兴趣的可以看下这篇博客:Android短信接收过程源码分析(原) http://blog.csdn.net/u010961631/article/details/12705541
好,现在功能看起来一切OK,真的没问题么?
实际上因为短信的广播是有序广播,假如有其他应用先捕获广播并终止传递,那么我们就永远也收不到这条短信变化的广播了。
还有没有其他办法呢?答案是肯定的,解决问题的办法不会只有一种,我们还可以通过ContentObserver来监听短信。具体怎么实现呢,下篇博客接着讲。