宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取

真的很奇怪大家的复制粘贴功能,一篇自动获取手机验证码的文章各大平台争相转发,我以为很牛逼,到后来发现不能用,可能我技术不够吧,复制粘贴还不到家。

android 自动获取手机验证码好处 :① 用户不用自动输入, 方便操作
② 防止用户在别的手机上登录,保证一手机只能一个号

言归正传

先创建继承于ContentObserver的子类,用于监听信息数据库发生变化,有信息来就立马截取。

public class SMSContentObserver extends ContentObserver {private static String TAG = "SMSContentObserver";private String patternCoder = "\\d{5}";     //正则表达式private String strContent;                  //验证码内容private Context mContext  ;private Handler mHandler ;   				  //更新UI线程private String TELPHONE = "TMRTXMIN"; // 短信来源号码private String TelPHONECONTEXT ="iViralLink"; // 短信内容 特殊关键字//    8448631136public SMSContentObserverContext context, Handler handler) {superhandler);mContext = context ;mHandler = handler ;}/*** 当所监听的Uri发生改变时,就会回调此方法** @param selfChange  此值意义不大 一般情况下该回调值false*/@Overridepublic void onChangeboolean selfChange){Log.iTAG, "the sms table has changed");//查询收件箱里的内容Uri outSMSUri = Uri.parse"content://sms/inbox") ;Cursor c = mContext.getContentResolver).queryoutSMSUri, null, null, null,"date desc");ifc != null){Log.iTAG, "the number of send is "+c.getCount)) ;StringBuilder sb = new StringBuilder) ;c.moveToNext);String message = c.getStringc.getColumnIndex"body"));      // 短信内容String phone = c.getStringc.getColumnIndex"address"));	   //短信来源号码Log.iTAG,"message : "+message);Log.iTAG,"phone : "+phone);c.close);ifcheckPhonephone) &&checkStringmessage)){String code = patternCodemessage);assert code != null;if!TextUtils.isEmptycode) ){strContent = code;}mHandler.obtainMessage1, sb.toString)).sendToTarget);}}}//指定一个号码,只读取与他有关的新消息。private boolean checkPhoneString phone) {// TODO Auto-generated method stubString c_phone = TELPHONE;ifc_phone.equalsphone) )return true;return false;}//指定一关键字符串,用来确认短信内容是我们想要去提取的private boolean checkStringString message){ifTextUtils.isEmptymessage))return false;Pattern p = Pattern.compileTelPHONECONTEXT);          //这个关键字符串可以自定义Matcher matcher = p.matchermessage);ifmatcher.find))return true;return false;}//匹配短信中的数字(验证码)private String patternCodeString patternContent){ifTextUtils.isEmptypatternContent))return null;Pattern p = Pattern.compilepatternCoder);Matcher matcher = p.matcherpatternContent);ifmatcher.find))return matcher.group);return null;}public String getStrContent){return strContent;}
}

然后自己需要的登录或者注册界面注册

  private void initRegisterContentObserver) {smsContentObserver = new SMSContentObserverthis, mHandler);Uri smsUri = Uri.parse"content://sms");getContentResolver).registerContentObserversmsUri, true, smsContentObserver);}

有注册记得关闭

 @Overrideprotected void onDestroy) {super.onDestroy);if getContentResolver)!=null){getContentResolver).unregisterContentObserversmsContentObserver);}}

展示信息:

private Handler mHandler = new Handler) {public void handleMessageMessage msg) {switch msg.what) {case 1:String outbox = smsContentObserver.getStrContent);//String) msg.obj;etVerificationCode.setTextoutbox);break;default:break;}}};

以上内容基本上已经可以获取到验证码了,但是获取手机短信,还是需要动态读取短信的权限。
AndroidManifest.xml中加权限

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

在获取权限的位置动态添加权限设置

private void getReadPermissions) {if Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {if ContextCompat.checkSelfPermissionthis, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {if ActivityCompat.shouldShowRequestPermissionRationaleRegisterActivity.this, Manifest.permission.RECEIVE_SMS)) {//是否请求过该权限ActivityCompat.requestPermissionsthis,new String[]{Manifest.permission.RECEIVE_SMS,Manifest.permission.READ_SMS
//                                    , Manifest.permission.SEND_SMS},10001);} else {//没有则请求获取权限,示例权限是:相机权限和定位权限,需要其他权限请更改或者替换ActivityCompat.requestPermissionsthis,new String[]{Manifest.permission.RECEIVE_SMS,Manifest.permission.READ_SMS},10001);}} else {        //如果已经获取到了权限则直接进行下一步操作Log.eTAG, "onRequestPermissionsResult");}}}

设置请求权限的回调

/*** 一个或多个权限请求结果回调** @param requestCode* @param permissions* @param grantResults*///当点击了不在询问,但是想要实现某个功能,必须要用到权限,可以提示用户,引导用户去设置@Overridepublic void onRequestPermissionsResultint requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResultrequestCode, permissions, grantResults);switch requestCode) {case 10001:for int i = 0; i < grantResults.length; i++) {
//                   如果拒绝获取权限if grantResults[i] != PackageManager.PERMISSION_GRANTED) {//判断是否勾选禁止后不再询问boolean flag= ActivityCompat.shouldShowRequestPermissionRationaleRegisterActivity.this, permissions[i]);if flag) {getReadPermissions);return;//用户权限是一个一个的请求的,只要有拒绝,剩下的请求就可以停止,再次请求打开权限了} else { // 勾选不再询问,并拒绝Toast.makeTextRegisterActivity.this, "Please go to Settings to get user permissions",Toast.LENGTH_LONG).show);return;}}}Toast.makeTextRegisterActivity.this, " go to school",Toast.LENGTH_LONG).show);break;default:break;}}

完整获取验证码代码如下:

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;import static android.content.ContentValues.TAG;public class RegisterActivity extends Activity {private SMSContentObserver smsContentObserver;private EditText etVerificationCode;private Handler mHandler = new Handler) {public void handleMessageMessage msg) {switch msg.what) {case 1:String outbox = smsContentObserver.getstrContent);//String) msg.obj;etVerificationCode.setTextoutbox);break;default:break;}}};@Overrideprotected void onCreateBundle savedInstanceState) {super.onCreatesavedInstanceState);setContentViewR.layout.activity_main);etVerificationCode = findViewByIdR.id.ed_code);getReadPermissions);initRegisterContentObserver);}private void initRegisterContentObserver) {smsContentObserver = new SMSContentObserverthis, mHandler);Uri smsUri = Uri.parse"content://sms");getContentResolver).registerContentObserversmsUri, true, smsContentObserver);}private void getReadPermissions) {if Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {if ContextCompat.checkSelfPermissionthis, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {if ActivityCompat.shouldShowRequestPermissionRationaleRegisterActivity.this, Manifest.permission.RECEIVE_SMS)) {//是否请求过该权限ActivityCompat.requestPermissionsthis,new String[]{Manifest.permission.RECEIVE_SMS,Manifest.permission.READ_SMS},10001);} else {//没有则请求获取权限,示例权限是:相机权限和定位权限,需要其他权限请更改或者替换ActivityCompat.requestPermissionsthis, new String[]{Manifest.permission.RECEIVE_SMS,Manifest.permission.READ_SMS},10001);}} else {        //如果已经获取到了权限则直接进行下一步操作Log.eTAG, "onRequestPermissionsResult");}}}/*** 一个或多个权限请求结果回调** @param requestCode* @param permissions* @param grantResults*///当点击了不在询问,但是想要实现某个功能,必须要用到权限,可以提示用户,引导用户去设置@Overridepublic void onRequestPermissionsResultint requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResultrequestCode, permissions, grantResults);switch requestCode) {case 10001:
//               一次请求多个权限时,可以循环设置,单独一个可以不用写了for int i = 0; i < grantResults.length; i++) {
//                   如果拒绝获取权限if grantResults[i] != PackageManager.PERMISSION_GRANTED) {//判断是否勾选禁止后不再询问boolean flag= ActivityCompat.shouldShowRequestPermissionRationaleRegisterActivity.this, permissions[i]);if flag) {getReadPermissions);return;//用户权限是一个一个的请求的,只要有拒绝,剩下的请求就可以停止,再次请求打开权限了} else { // 勾选不再询问,并拒绝Toast.makeTextRegisterActivity.this, "Please go to Settings to get user permissions",Toast.LENGTH_LONG).show);return;}}}Toast.makeTextRegisterActivity.this, " go to school",Toast.LENGTH_LONG).show);break;default:break;}}@Overrideprotected void onDestroy) {super.onDestroy);if getContentResolver)!=null){getContentResolver).unregisterContentObserversmsContentObserver);}}
}