Android接受驗證碼自動填入功能(源碼+已實現+可用+版本兼容)


實際應用開發中,會經常用到短信驗證的功能,這個時候如果再讓用戶就查看短信.然后再回到界面進行短信的填寫,難免有多少有些不方便,作為開發者.本着用戶至上的原則我們也應該來實現驗證碼的自動填寫功能,還有一個重要的原因是為了防止惡意注冊。今天實現這個功能的方法是用的廣播來實現的

首先在AndroidMainfest.xml中加入所需要的權限:

 

<!-- 短信驗證登陸功能需要添加次權限來自動填充驗證碼,用不到可以去掉 -->
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />

 

首先看一下實現的效果,沒效果說再多都沒用,親眼看到的才知道適不適合自己

 

 

中效果看完接下來就看怎么實現的了,這里使用的廣播為動態注冊,因為這個APP在進程殺死之后就不需要監聽這個廣播了,在Activity的onDestory之后注銷廣播。

SMSBroadcastReceiver.java

 

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;
import android.util.Log;

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

/**
 * Created by dingchao on 2018/3/31.
 */

public class SMSBroadcastReceiver extends BroadcastReceiver {

    private static final String TAG = "SMSBroadcastReceiver";

    private static MessageListener mMessageListener;

    public SMSBroadcastReceiver() {
        super();
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        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.e(TAG, "onReceive: 短信來自:" + sender);
            Log.e(TAG, "onReceive: 短信內容:" + content);
            Log.e(TAG, "onReceive: 短信時間:" + time);

            if(content.indexOf("優鋪")>-1){
                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;
    }
}

 

MainActivity.java

 

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

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

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

import static android.R.attr.phoneNumber;


public class MainActivity extends AppCompatActivity {
    private EditText et_phone, et_code;
    private Button btn_code;
    private static final int REQUEST_PERMISSION_CODE = 0;
    SMSBroadcastReceiver mSMSBroadcastReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //實例化IntentFilter對象
        IntentFilter filter = new IntentFilter();
        filter.addAction("android.provider.Telephony.SMS_RECEIVED");
        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位驗證碼
            }
        });


        et_phone = (EditText) findViewById(R.id.et_phone);
        et_code = (EditText) findViewById(R.id.et_code);
        btn_code = (Button) findViewById(R.id.btn_code);
        btn_code.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getCode(et_phone.getText().toString());
            }
        });


        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_SMS)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, REQUEST_PERMISSION_CODE);
        }

       /* SMSBroadcastReceiver mSMSBroadcastReceiver = new SMSBroadcastReceiver();
        mSMSBroadcastReceiver.setOnReceivedMessageListener(new SMSBroadcastReceiver.MessageListener() {
            public void OnReceived(String message) {
                Log.e("tag", "1=" + message);
                et_code.setText(getDynamicPwd(message));//截取6位驗證碼
            }
        });*/



    }


    /*發送驗證碼請求*/
    private void getCode(final String phone) {
        Log.e("getCode", "getCode:229:" + phoneNumber);
        RequestQueue mQueue = Volley.newRequestQueue(MainActivity.this);
        StringRequest strinRequest = new StringRequest(Request.Method.POST, "你的驗證碼請求接口", new Response.Listener<String>() {
            @Override
            public void onResponse(String s) {
                Log.e("login", "-------獲取到的idjson--------" + s.toString());
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {

            }
        }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> map = new HashMap<String, String>();
                map.put("phoneNumber", phone);
                Log.e("map", "map:249:" + phone);
                return map;
            }
        };
        /*設置請求一次*/
        strinRequest.setRetryPolicy(
                new DefaultRetryPolicy(
                        500000,//默認超時時間,應設置一個稍微大點兒的,例如本處的500000
                        DefaultRetryPolicy.DEFAULT_MAX_RETRIES,//默認最大嘗試次數
                        DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
                )
        );
        mQueue.add(strinRequest);/*請求數據*/
    }


    /*高版本手動獲取權限*/
    @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]{6})截取六位數字 進行前后斷言不能出現數字 用於從短信中獲取動態密碼
     *
     * @param content 短信內容
     * @return 截取得到的6位動態密碼
     */
    public String getDynamicPwd(String content) {
        // 此正則表達式驗證六位數字的短信驗證碼
        Pattern pattern = Pattern.compile("(?<![0-9])([0-9]{6})(?![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;
    }
}

 

 

 

主要的步驟代碼已經貼出,源碼地址鏈接:https://pan.baidu.com/s/1vbYxHZxw9t0LGF_BkzmpvQ 密碼:fxrm

有問題或建議請聯系dingchao7323@qq.com

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM