Android自动提取短信验证码

发表于:2017-3-10 10:02

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:我是程序猿    来源:51Testing软件测试网采编

  手机端在银行卡支付,用户注册时,都会要求输入短信验证码,接收到短信后可以直接复制,那么是如何提取到短信内容的
  有以下2种方式
  1、手机在接收到短信后,会发送一个广播(BroadCast)
  2、可以通过内容观察者(ContentObserver)检测短信URI的变化
  第一种广播(BroadCast)方式正在被淘汰 1、广播比较耗性能,如果多软件监听短信 2、会因为优先级无法接收到广播
  那么主要讲下第二种方式,有以下3个知识点
  1、自定义ContentObserver监听短信URI变化
  2、通过LoaderManager异步读取短信内容
  a、替换managedQuery(主线程运行,由于耗时查询会出现ANR现象)
  b、提供异步加载数据机制
  c、对数据源变化进行监听,实时更新数据;
  d、在Activity配置发生变化(如横竖屏切换)时不用重复加载数据;
  e、适用于任何Activity和Fragment;
  3、在LoaderManager中学会用Cursor读取短信内容
  完整代码
<!--收短信的权限-->
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<!--读取短信信息的权限-->
<uses-permission android:name="android.permission.READ_SMS"/>
public class MainActivity extends AppCompatActivity {
private TextView text_view;
private Uri URI_SMS = Uri.parse("content://sms/");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text_view = (TextView) findViewById(R.id.text_view);
//注册观察者检测短信URI变化
this.getContentResolver().registerContentObserver(URI_SMS, true, new ReadSmsContentObserver(new Handler()));
}
//观察者监听短信数据库
class ReadSmsContentObserver extends ContentObserver {
public ReadSmsContentObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange);
//通过异步数据LoaderManager来读取短信内容
ReadSmsLoaderListener readSmsLoaderListener = new ReadSmsLoaderListener();
LoaderManager loaderManager = MainActivity.this.getLoaderManager();
loaderManager.initLoader(0, null, readSmsLoaderListener);
}
}
//异步数据加载类
class ReadSmsLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
private Uri sms_uri = Uri.parse("content://sms/inbox");
//id, address, person, date, type, body...
private final String[] sms_projection = new String[]{"body"};
//按时间降序
private final String sms_order = "date desc";
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
//读取2分钟内的短信,并不会读取之前的短信
String sms_where = "date >" + (System.currentTimeMillis() - 2*60*1000);
return new CursorLoader(MainActivity.this, sms_uri, sms_projection, sms_where, null, sms_order);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
fetchSmsCodeFromCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
//解析短信内容
private void fetchSmsCodeFromCursor(Cursor cursor) {
if(cursor != null) {
while (cursor.moveToNext()) {
String body = cursor.getString(cursor.getColumnIndex("body"));
if (!TextUtils.isEmpty(body)) {
if (body.contains("验证码")) {
String verifyCode = getSmsCode(body);
//更新UI,显示短信码
text_view.setText(verifyCode);
break;
}
}
}
}
}
//提取验证码
private String getSmsCode(String smsContent){
Pattern pattern = Pattern.compile("[0-9]{4,}");
Matcher m = pattern.matcher(smsContent);
while (m.find()) {
String group = m.group();
if(group != null && group.length() >= 4){
return group;
}
}
return "";
}
}
}
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号