android 短信验证码自动填写的二种方法

转载自:https://blog.csdn.net/VirusDerekRuler/article/details/78506522

现在开发越来越注重用户体验了,现今Android基本都有短信验证功能,那今天就实现一个自动填写短信验证码的小Demo,其中涉及有观察者模式、以及使用Handler来实现UI的更新。

我们还是先了解一下有关手机短信的一些知识

URI主要有:
     content://sms/               所有短信

     content://sms/inbox        收件箱

     content://sms/sent          已发送

     content://sms/draft         草稿

     content://sms/outbox     发件箱

     content://sms/failed       发送失败

     content://sms/queued    待发送列表

sms主要结构:
  
  _id:短信序号,如100
  
  thread_id:对话的序号,如100,与同一个手机号互发的短信,其序号是相同的
  
  address:发件人地址,即手机号,如+86138138000
  
  person:发件人,如果发件人在通讯录中则为具体姓名,陌生人为null
  
  date:日期,long型,如1346988516,可以对日期显示格式进行设置
  
  protocol:协议0SMS_RPOTO短信,1MMS_PROTO彩信
  
  read:是否阅读0未读,1已读
  
  status:短信状态-1接收,0complete,64pending,128failed
  
  type:短信类型1是接收到的,2是已发出
  
  body:短信具体内容
  
  service_center:短信服务中心号码编号,如+8613800755500

第一种通过短信数据库获取短信内容

那我们接下来看下我们的Activity

import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    public static final int SMG_RECEIVED_CODE = 1;
    private SmsObserver smsObserver;
    private static Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if(msg.what == SMG_RECEIVED_CODE){
                String code = (String) msg.obj;
                //更新UI
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        smsObserver = new SmsObserver(MainActivity.this,mHandler);
        Uri uri = Uri.parse("content://sms");
        getContentResolver().registerContentObserver(uri,true,smsObserver);//注册观察者
    }

    @Override
    protected void onPause() {
        super.onPause();
        getContentResolver().unregisterContentObserver(smsObserver);//取消观察者
    }
}

现在再来看下我们的SmsObserver类

public class SmsObserver extends ContentObserver{
    private static final String TAG = "SmsObserver";
    private Context mContext;
    private Handler mHandler;

    public SmsObserver(Context context, Handler handler) {
        super(handler);
        this.mContext = context;
        this.mHandler = handler;
    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        super.onChange(selfChange, uri);
        Log.e(TAG, "onChange: "+ uri.toString());
        String code="";
        if(uri.toString().equals("content://sms/raw")){
             return;
        }
        //读取短信
        Uri inboxUri = Uri.parse("content://sms/inbox");
        Cursor cursor = mContext.getContentResolver().query(inboxUri,null,null,null,"date desc");
        if(cursor!=null){
            if(cursor.moveToFirst()){
                String address = cursor.getString(cursor.getColumnIndex("address"));
                String body = cursor.getString(cursor.getColumnIndex("body"));
                if(!address.toString().equals("指定发送短信号码")){
                    return;
                }
                Log.e(TAG, "onChange: "+ address+"  "+body);
                Pattern pattern = Pattern.compile("(\\d{6})");//连续6个数字的验证码
                Matcher matcher = pattern.matcher(body.toString());
                if(matcher.find()){
                    code = matcher.group(0);
                    //发送消息
                    mHandler.obtainMessage(MainActivity.SMG_RECEIVED_CODE ,code).sendToTarget();
                }
            }
            cursor.close();
        }
    }
}

记得加权限哦

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

第二种通过广播监听短信消息

主Activity

private static Handler handler = new Handler() {  
        public void handleMessage(android.os.Message msg) {  
            if (msg.what == BC_SMS_RECEIVE) {  
                String code = (String) msg.obj;   
                //更新UI
            }  
        };  
    }; 


protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);  
    receiver = new SmsBroadcastReceiver(MainActivity.this, handler, 6);  
    IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");  
    registerReceiver(receiver, intentFilter);  
}  
  
 
@Override  
protected void onDestroy() {  
    super.onDestroy();  
    unregisterReceiver(receiver);  
}  

//自己的一个广播接收器

public class SmsBroadcastReceiver extends BroadcastReceiver {  
  
    private Context context;  
    private Handler handler;  
    private int codeLength = 0;  
    
    public SmsReceiveBroadcastReceiver(Context context, Handler handler) {  
        this.context = context;  
        this.handler = handler;  
    }  
  
    @Override  
    public void onReceive(Context context, Intent intent) {   
        Bundle bundle = intent.getExtras();  
        Object[] objects = (Object[]) bundle.get("pdus");  
        if (objects != null) {  
            String phone = null;  
            StringBuffer content = new StringBuffer();  
            for (int i = 0; i < objects.length; i++) {  
                SmsMessage sms = SmsMessage.createFromPdu((byte[]) objects[i]);  
                phone = sms.getDisplayOriginatingAddress();  
                content.append(sms.getDisplayMessageBody());  
            }    
            CodeAndSend(content.toString());  
        }  
    }  
  
    
    private void CodeAndSend(String content) {   
        Pattern pattern = Pattern.compile("(\\d{6})");//连续6个数字的验证码
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {  
            String code = matcher.group(0);  
            handler.obtainMessage(MainActivity.BC_SMS_RECEIVE, code).sendToTarget();    
        }  
    }   


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


备注:

 我用的是第一种,亲测有效! 反正Vivo手机是没有问题的,一定要记得权限申请! 其他品牌的手机,不知道是否有用,我这里没有测试机!

猜你喜欢

转载自blog.csdn.net/wolfking0608/article/details/80886735