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