android 短信验证码自动填写的两种方式

https://blog.csdn.net/u010399316/article/details/48781319

https://www.01hai.com/note/av123438

https://pan.baidu.com/s/1g5HMWx45VuGsuh3dEZJNJg我的代码下载,里面除了短信,还包含了上一篇的打开通讯录

有的手机接收不到短信,是因为有的手机有安全设置,我的手机是荣耀系列的,去短信==更多==设置==高级==验证码安全保护打开就可以拦截短信了,其他的手机类似,小米手机也是这样,但是有部分手机可能系统不支持,还有个别手机安装了第三方的短信软件,也会出现问题,(没有试过)还有广播的优先级,可能360的优先级更高,就会拦截掉短信,就接收不到了。

下面代码的这两个方式我都试过了,我的荣耀7.0版本的手机没有问题

记得加权限,6.0的记得加动态权限,不然会监听不到短信

  <!-- 短信验证登陆功能需要添加次权限来自动填充验证码,用不到可以去掉 -->

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

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

一、广播方式,记得加权限,还有广播的优先级别

SmsBroadcastReceiver
package com.example.administrator.mysms.broadcast;

/**
 * Created by wq on 2018/10/8.
 */
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;


import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by Sunwork on 2016/7/8.
 */
public class SmsBroadcastReceiver extends BroadcastReceiver {

    private static final String TAG = "SmsBroadcastReceiver";

    private static MessageListener mMessageListener;

    public SmsBroadcastReceiver() {
        super();
        Log.i(TAG, "onReceive: super:" );
    }
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG, "onReceive: 接收短信:");
        Toast.makeText(context,"接收短信",Toast.LENGTH_SHORT).show();
        Object[] pdus = (Object[]) intent.getExtras().get("pdus");
        for (Object pdu : pdus) {
            SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu);
            String sender = smsMessage.getDisplayOriginatingAddress();
            String content = smsMessage.getMessageBody();
            long date = smsMessage.getTimestampMillis();
            Date timeDate = new Date(date);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time = simpleDateFormat.format(timeDate);

            Log.i(TAG, "onReceive: 短信来自:" + sender);
            Log.i(TAG, "onReceive: 短信内容:" + content);
            Log.i(TAG, "onReceive: 短信时间:" + time);

            mMessageListener.OnReceived(content);
            //如果短信号码来自自己的短信网关号码
           /* if ("your sender number".equals(sender) && mMessageListener != null) {
                Log.i(TAG, "onReceive: 回调");
                mMessageListener.OnReceived(content);
            }*/
        }
    }

    // 回调接口
    public interface MessageListener {

        /**
         * 接收到自己的验证码时回调
         * @param message 短信内容
         */
        void OnReceived(String message);
    }

    /**
     * 设置验证码接收监听
     * @param messageListener 自己验证码的接受监听,接收到自己验证码时回调
     */
    public void setOnReceivedMessageListener(MessageListener messageListener) {
        this.mMessageListener = messageListener;
    }
}

主页面调用广播,当有短信的时候,广播会接收的信息

package com.example.administrator.mysms.broadcast;

import android.Manifest;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.example.administrator.mysms.R;
import com.example.administrator.mysms.phone.MainActivity3;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

//https://www.01hai.com/note/av123438
public class SmsBroadcastActivity extends AppCompatActivity {
    SmsBroadcastReceiver mSMSBroadcastReceiver;
    private static final int REQUEST_PERMISSION_CODE = 0;
    private EditText et_code ;
    private Button but_tl ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_code = (EditText)findViewById(R.id.et_code);
        but_tl = (Button)findViewById(R.id.but_tl);
        but_tl.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(SmsBroadcastActivity.this, MainActivity3.class);

                startActivity(intent);
            }
        });
        //实例化IntentFilter对象

        IntentFilter filter = new IntentFilter();

        filter.addAction("android.provider.Telephony.SMS_RECEIVED");
        filter.setPriority(1000);
        mSMSBroadcastReceiver = new SmsBroadcastReceiver();
        //注册广播接收
        registerReceiver(mSMSBroadcastReceiver, filter);


        mSMSBroadcastReceiver.setOnReceivedMessageListener(new SmsBroadcastReceiver.MessageListener() {

            public void OnReceived(String message) {

                Log.e("tag", "1=" + message);

                et_code.setText(getDynamicPwd(message));//截取6位验证码

            }
        });

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_SMS)

                != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, REQUEST_PERMISSION_CODE);
        }


    }

    /*高版本手动获取权限*/

    @Override

    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == REQUEST_PERMISSION_CODE) {

            if (grantResults.length != 0) {

                if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {

                    Toast.makeText(this, "您阻止了app读取您的短信,您可以自己手动输入验证码", Toast.LENGTH_SHORT).show();
                }
            } else {
                Log.e("TAG", "获取权限");
            }

        }

    }





    /**

     * 从字符串中截取连续6位数字组合 ([0-9])截取六位数字 进行前后断言不能出现数字 用于从短信中获取动态密码

     *

     * @param content 短信内容

     * @return 截取得到的6位动态密码

     */

    public String getDynamicPwd(String content) {

        // 此正则表达式验证六位数字的短信验证码

        Pattern pattern = Pattern.compile("(?<![0-9])([0-9])(?![0-9])");

        Matcher matcher = pattern.matcher(content);

        String dynamicPwd = "";

        while (matcher.find()) {

            dynamicPwd = matcher.group();

            Log.i("TAG", "getDynamicPwd: find pwd=" + dynamicPwd);
        }
        return dynamicPwd;
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mSMSBroadcastReceiver);
        mSMSBroadcastReceiver = null;

    }
}

二、实现ContentObserver,把我们自己的Observer注册到短信服务,短信应用收到新的短信的时候会发送给我我们自己的Observer,然后我们在自己的Observer中.通过代码发送给我们的需要填充的界面就行了.这种方式是利用了观察者模式 .

上面的广播有动态授权的代码,可以复制过来。。。。。这个代码记得动态授权

package com.example.administrator.mysms;

/**
 * Created by wq on 2018/10/8.
 * https://blog.csdn.net/mazhidong/article/details/72675828
 */

import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;


import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * 观察者对象
 */
public class SmsObserver extends ContentObserver {

    private Context mContext;
    private Handler mHandler;

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

    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        super.onChange(selfChange, uri);

        Log.d("====main", "SMS has changed!");
        Log.d("====main", uri.toString());
        // 短信内容变化时,第一次调用该方法时短信内容并没有写入到数据库中,return
        if (uri.toString().equals("content://sms/raw")) {
            return;
        }
        getValidateCode();//获取短信验证码

    }

    /**
     * 获取短信验证码
     */
    private void getValidateCode() {
        String code = "";
        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"));

                //13162364720为发件人的手机号码
                /*if (!address.equals("15860526788")) {
                    return;
                }*/
                Log.d("====main", "发件人为:" + address + " ," + "短信内容为:" + body);

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

                if (matcher.find()) {
                    code = matcher.group(0);
                    Log.d("====main", "验证码为: " + code);
                    mHandler.obtainMessage(1, code).sendToTarget();
                }

            }
            c.close();
        }
    }
}
package com.example.administrator.mysms;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
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.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.example.administrator.mysms.broadcast.SmsBroadcastActivity;
import com.example.administrator.mysms.phone.MainActivity3;

/**
 * 短信验证码自动填写功能的实现
 * <p>
 * Created by huangminzheng on 16/3/15.
 */
public class SmsObserverActivity extends Activity {

    public static final int MSG_RECEIVED_CODE = 1;
    private static final int REQUEST_PERMISSION_CODE = 0;
    private EditText metValidateCode = null;
    private SmsObserver mObserver;

    private Button but_tl ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_SMS)

                != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, REQUEST_PERMISSION_CODE);
        }

        but_tl = (Button)findViewById(R.id.but_tl);
        but_tl.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(SmsObserverActivity.this, MainActivity3.class);

                startActivity(intent);
            }
        });


        metValidateCode = (EditText) findViewById(R.id.et_code);

        mObserver = new SmsObserver(SmsObserverActivity.this, mHandler);
        Uri uri = Uri.parse("content://sms");
        //注册短信的监听
        getContentResolver().registerContentObserver(uri, true, mObserver);
    }

    @Override
    protected void onPause() {
        super.onPause();
        //解除注册短信的监听
        getContentResolver().unregisterContentObserver(mObserver);
    }

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == MSG_RECEIVED_CODE) {
                String code = (String) msg.obj;
                metValidateCode.setText(code);
            }
        }
    };
    /*高版本手动获取权限*/

    @Override

    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == REQUEST_PERMISSION_CODE) {

            if (grantResults.length != 0) {

                if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {

                    Toast.makeText(this, "您阻止了app读取您的短信,您可以自己手动输入验证码", Toast.LENGTH_SHORT).show();
                }
            } else {
                Log.e("TAG", "获取权限");
            }

        }

    }

}

猜你喜欢

转载自blog.csdn.net/code_dream_wq/article/details/82984729