获取短信内容中的验证码:
1)分析短息内容:
一般包含验证码的短信可能为“您的短信验证码为123456.”
格式为“中文字符” + "数字验证码" + “其他字符”。
2)使用正则表达式表述验证码:
\d匹配0-9的数字,\d{6}表示匹配6位0-9的数字——这是验证码本体
使用零宽断言查找验证码的位置,(?<!\d)表示匹配前面不是0-9数字的位置,(?!\d)表示匹配后面不是0-9数字的位置
所以完整的正则表达时应该为(?<!\d)\d{6}(?!\d)
注意:Java中由于转义的问题,所以反斜杠需要再加一个反斜杠,\\表示\,所以程序中的表达式实际为(?<!\\d)\\d{6}(?!\\d)
剩下的都是代码了:
首先当然是layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/phone_num_edit_text"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:inputType="phone"
android:hint="请输入您的手机号码"/>
<Button
android:id="@+id/send_ver_code_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击发送验证码"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/ver_code_edit_text"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:hint="请输入收到的验证码"/>
<Button
android:id="@+id/confirm_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="点击确认验证码"/>
</LinearLayout>
</LinearLayout>
public class MainActivity extends AppCompatActivity {
private EditText phoneNumEditText,verificationCodeEditText;
//两个按键用于网络交互
private Button sendButton,confirmButton;
private Handler handler;
private String verCode;
private BroadcastReceiver broadcastReceiver;
//匹配验证码
private String patternCode(String patternContent){
if(TextUtils.isEmpty(patternContent)){
return null;
}
//将正则表达式赋予生成的Pattern类
Pattern pattern = Pattern.compile("(?<!\\d)\\d{6}(?!\\d)");
//将要匹配的内容赋予生成的Matcher类
Matcher matcher = pattern.matcher(patternContent);
//尝试在目标字符串里查找下一个匹配字符串
if(matcher.find()){
//返回当前查找而获得的与组匹配的所有字符串内容
return matcher.group();
}
return null;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
phoneNumEditText = (EditText) findViewById(R.id.phone_num_edit_text);
verificationCodeEditText = (EditText) findViewById(R.id.ver_code_edit_text);
sendButton = (Button) findViewById(R.id.send_ver_code_button);
confirmButton =(Button) findViewById(R.id.confirm_button);
//获取本机号码目前没有比较方便的方法,较简单的是读取sim卡,较成功的是发短信给服务商来读取发送号码
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
phoneNumEditText.setText(telephonyManager.getLine1Number());
//刷新UI要用到handler传送消息
handler = new Handler() {
public void handleMessage(Message message){
verificationCodeEditText.setText(verCode);
}
};
//创建一个意图过滤器,接收收到短信时的广播
IntentFilter intentFilter = new IntentFilter();
//只有用于过滤广播的IntentFilter可以在代码中创建,其他的IntentFilter必须在manifest文件中声明
intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
//设置优先级,由于参数必须为整数,所以简单的设置为Integer.MAX_VALUE——最大整数
//事实上,这里可以衍生开去,进行短信的拦截等操作,和之前的电话录音配合,基本上能完成一部手机的基本监听需求
intentFilter.setPriority(Integer.MAX_VALUE);
//定制广播接收器
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//生成一个数组将短信内容赋值进去
//intent.getExtras()方法就是从过滤后的意图中获取携带的数据,这里携带的是以"pdus"为key、短信内容为value的键值对
//Android设备接收到的SMS是以pdu形式的(protocol description unit)
Object[] pdus = (Object[]) intent.getExtras().get("pdus") ;
/*这里for循环也可以用
for(int i = 0; i < pdus.length; i++){
byte[] pdu[i] = (byte[]) pdus[i];
do something
}
*/
//遍历pdus数组,将每一次访问得到的数据放入object中
for(Object object : pdus){
byte[] pdu = (byte[]) object;
/*
6.0系统开始不建议使用createFromPdu(byte[])方法,只能使用createFromPdu(byte[],String format)方法
String format = intent.getExtras().getString("format");
SmsMessage smsMessage = SmsMessage.createFromPdu(pdu,format);
*/
//获取短信
SmsMessage smsMessage = SmsMessage.createFromPdu(pdu);
//获取短信体,即内容
String messageBody = smsMessage.getMessageBody();
//获取短信发送方地址
String originationAddress = smsMessage.getOriginatingAddress();
//如果短信发送地址不为空,这里也可以使用equals限定短信发送方
if(!TextUtils.isEmpty(originationAddress)){
//解析短信体
String code = patternCode(messageBody);
if(!TextUtils.isEmpty(code)){
verCode = code;
//sendEmptyMessage(int what)方法是发送指定的消息,该方法为仅仅只是传递一个int值来表示发送的消息类型
handler.sendEmptyMessage(1);
}
}
}
}
};
//注册广播接收器
registerReceiver(broadcastReceiver,intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
//动态注册就不能忘记取消注册
unregisterReceiver(broadcastReceiver);
}
}
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.INTERNET" />