Android短信验证码自动填充

在我们的Android开发中会经常用到短信验证的功能,这个时候如果再让用户就查看短信.然后再回到界面进行短信的填写,难免有多少有些不方便,为了提高用户体验,我也就自己来实现验证码的自动填写功能

  一、简介

  之前笔者见过一些人的实现思路是这样的:

  创建一个广播接收器,接受短信变化的广播,然后在收到广播的时候,再把验证码提取出来发送给我们的需要填充验证码的地方就行了。 但是,这种方式有它的缺陷:当你的手机安装了其他一些短信应用(例如QQ通讯录)或者手机本身限制了权限的情况下,这种方式有可能会不起作用,无法做到自动填写,而且就算把优先级设高,也不能保证不会被别的应用抢先。 所以,通过查阅资料,发现了这种方式: 可以通过监听短信数据库的方式实现。监听短信数据库主要是通过ContentObserver这个类来完成。ContentObserver主要是通过Uri来监测特定的Databases的表,当ContentObserver所观察的Uri发生变化时,便会触发它。

  二、短信验证码自动填充的工具类

  /**

  短信验证码自动填充

  *

  * @author 周旭

  */

  public class SMSContentObserver extends ContentObserver {

  private Context mContext; // 上下文

  private Handler mHandler; // 更新UI线程

  private String code; // 验证码

  public SMSContentObserver(Context context, Handler handler) {

  super(handler);

  mContext = context;

  mHandler = handler;

  }

  /**

  回调函数当所监听的Uri发生改变时,就会回调此方法

  *

  注意当收到短信的时候会回调两次

  收到短信一般来说都是执行了两次onchange方法.第一次一般都是raw的这个.

  这个时候虽然收到了短信.但是短信还没有写入到收件箱里面

  然后才是另外一个,后面的数字是该短信在收件箱中的位置

  *

  * @param selfChange 此值意义不大 一般情况下该回调值false

  */

  @Override

  public void onChange(boolean selfChange, Uri uri) {

  Log.e("tag", uri.toString());

  // 第一次回调 不是我们想要的 直接返回

  if (uri.toString().equals("content://sms/raw")) {

  return;

  }

  // 第二次回调 查询收件箱里的内容

  Uri inboxUri = Uri.parse("content://sms/inbox");

  // 按时间顺序排序短信数据库

  Cursor c = mContext.getContentResolver().query(inboxUri, null, null,

  null, "date desc");

  if (c != null) {

  if (c.moveToFirst()) {

  // 获取短信提供商的手机号

  String address = c.getString(c.getColumnIndex("address"));

  // 获取短信内容

  String body = c.getString(c.getColumnIndex("body"));

  Log.i("tag", "body------->" + body);

  // 判断手机号是否为目标号码(短信提供商的号码)

  // 在这里我们的短信提供商的号码如果是固定的话.我们可以再加一个判断,这样就不会受到别的短信应用的验证码的影响了

  // 不然的话就在我们的正则表达式中,加一些自己的判断,例如短信中含有自己应用名字啊什么的...

  /*if (!address.equals("13342290623"))

  {

  Log.i("tag","------->没有读取到内容");

  return;

  }*/

  // 正则表达式截取短信中的6位验证码

  Pattern pattern = Pattern.compile("(\\d{6})");

  Matcher matcher = pattern.matcher(body);

  // 利用handler将得到的验证码发送给主线程

  if (matcher.find()) {

  code = matcher.group(0);

  //mHandler.obtainMessage(1, code).sendToTarget();

  Message msg = Message.obtain();

  msg.what = MainActivity.MSG_RECEIVE_CODE;

  msg.obj = code;

  mHandler.sendMessage(msg);

  }

  }

  c.close();

  }

  }

  }

  调用的Activity

  /**

  短信验证码自动填写功能的实现

  */public class MainActivity extends AppCompatActivity {

  public static final int MSG_RECEIVE_CODE = 1; //收到短信的验证码

  private EditText codeEdt; //短信验证码的输入框

  private SMSContentObserver smsContentObserver;

  //回调接口

  @SuppressLint("HandlerLeak")

  Handler handler = new Handler() {

  @Override

  public void handleMessage(Message msg) {

  if (msg.what == MSG_RECEIVE_CODE) {

  codeEdt.setText(msg.obj.toString()); //设置读取到的内容

  }

  }

  };

  @Override

  protected void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  setContentView(R.layout.activity_main);

  codeEdt = (EditText) findViewById(R.id.smsCode);

  findViewById(R.id.send_sms_btn).setOnClickListener(new View.OnClickListener() {

  @Override

  public void onClick(View v) {

  senSMSCode();

  }

  });

  smsContentObserver = new SMSContentObserver(

  MainActivity.this, handler);

  //ContentObserver注册

  getContentResolver().registerContentObserver(

  Uri.parse("content://sms/"), true, smsContentObserver);

  }

  /**

  取消注册

  */

  @Override

  protected void onDestroy() {

  super.onDestroy();

  getContentResolver().unregisterContentObserver(smsContentObserver);

  }

  //使用Bmob云的短信验证功能来发送短信

  private void senSMSCode() {

  BmobSMS.requestSMSCode("13342290623", "知么网络", new QueryListener() {

  @Override

  public void done(Integer smsId, BmobException ex) {

  if (ex == null) {//验证码发送成功

  Log.i("smile", "短信id" + smsId);//用于后续的查询本次短信发送状态

  Toast.makeText(MainActivity.this, "发送验证码成功", Toast.LENGTH_SHORT).show();

  }

  }

  });

  }

  }

  添加权限

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

  三、短信的Uri共有一下几种:

  content://sms/inbox 收件箱

  content://sms/sent 已发送

  content://sms/draft 草稿

  content://sms/outbox 发件箱 (正在发送的信息)

  content://sms/failed 发送失败

  content://sms/queued 待发送列表 (比如开启飞行模式后,该短信就在待发送列表里)

 

来源:简书

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值