OTP(令牌)应自动从消息中读取

我正在开发一个Android应用程序,在这个应用程序中,服务器发送一个OTP,并且用户需要在应用程序中input这个OTP,来注册我的应用程序。 我想要的是,我的应用程序应该能够自动读取服务器发送的OTP。 我怎样才能做到这一点? 任何帮助或在这方面的指导将不胜感激。

Solutions Collecting From Web of "OTP(令牌)应自动从消息中读取"

你可以尝试使用一个简单的库,如https://github.com/stfalcon-studio/SmsVerifyCatcher

在通过gradle安装并添加权限之后,像onCreate活动一样启动SmsVerifyCatcher:

smsVerifyCatcher = new SmsVerifyCatcher(this, new OnSmsCatchListener<String>() { @Override public void onSmsCatch(String message) { String code = parseCode(message);//Parse verification code etCode.setText(code);//set code in edit text //then you can send verification code to server } }); 

此外,覆盖活动lifecicle方法:

  @Override protected void onStart() { super.onStart(); smsVerifyCatcher.onStart(); } @Override protected void onStop() { super.onStop(); smsVerifyCatcher.onStop(); } /** * need for Android 6 real time permissions */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); smsVerifyCatcher.onRequestPermissionsResult(requestCode, permissions, grantResults); } 

我build议您不要使用任何第三方库从SMS收件箱中自动获取OTP。 如果您对广播接收机有基本的了解,以及它如何工作,可以轻松完成。 试试下面的方法:

步骤1)创build单个接口,即SmsListner

 package com.wnrcorp.reba; public interface SmsListener{ public void messageReceived(String messageText);} 

步骤2)创build单个广播接收器即SmsReceiver

 package com.wnrcorp.reba; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.telephony.SmsMessage; public class SmsReceiver extends BroadcastReceiver { private static SmsListener mListener; Boolean b; String abcd,xyz; @Override public void onReceive(Context context, Intent intent) { Bundle data = intent.getExtras(); Object[] pdus = (Object[]) data.get("pdus"); for(int i=0;i<pdus.length;i++){ SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]); String sender = smsMessage.getDisplayOriginatingAddress(); // b=sender.endsWith("WNRCRP"); //Just to fetch otp sent from WNRCRP String messageBody = smsMessage.getMessageBody(); abcd=messageBody.replaceAll("[^0-9]",""); // here abcd contains otp which is in number format //Pass on the text to our listener. if(b==true) { mListener.messageReceived(abcd); // attach value to interface object } else { } } } public static void bindListener(SmsListener listener) { mListener = listener; } } 

步骤3)在Android清单文件中添加监听器,即广播接收器

 <receiver android:name=".SmsReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver> 

并添加权限

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

最后一步4)您将在收件箱中收到otp时自动获取的活动。 在我的情况下,我正在获取otp并设置edittext字段。

 public class OtpVerificationActivity extends AppCompatActivity { EditText ed; TextView tv; String otp_generated,contactNo,id1; GlobalData gd = new GlobalData(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_otp_verification); ed=(EditText)findViewById(R.id.otp); tv=(TextView) findViewById(R.id.verify_otp); /*This is important because this will be called every time you receive any sms */ SmsReceiver.bindListener(new SmsListener() { @Override public void messageReceived(String messageText) { ed.setText(messageText); } }); tv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { InputMethodManager imm= (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),0); } catch(Exception e) {} if (ed.getText().toString().equals(otp_generated)) { Toast.makeText(OtpVerificationActivity.this, "OTP Verified Successfully !", Toast.LENGTH_SHORT).show(); } }); } } 

OtpVerificationActivity的布局文件

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_otp_verification" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.wnrcorp.reba.OtpVerificationActivity"> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/firstcard" xmlns:card_view="http://schemas.android.com/apk/res-auto" card_view:cardCornerRadius="10dp" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:background="@android:color/white"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="OTP Confirmation" android:textSize="18sp" android:textStyle="bold" android:id="@+id/dialogTitle" android:layout_margin="5dp" android:layout_gravity="center" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/otp" android:layout_margin="5dp" android:hint="OTP Here" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Verify" android:textSize="18sp" android:id="@+id/verify_otp" android:gravity="center" android:padding="10dp" android:layout_gravity="center" android:visibility="visible" android:layout_margin="5dp" android:background="@color/colorPrimary" android:textColor="#ffffff" /> </LinearLayout> </android.support.v7.widget.CardView> </RelativeLayout> 

OTPvalidation活动的屏幕截图,您可以像接收消息一样获取OTP

这帮助我,也为我工作:

http://androiddhina.blogspot.in/2015/06/reading-incoming-message-automatically-to-verify-OTP.html

另外请不要忘记从你的Activity/Fragment为你的EditText制作static

我实现了这样的东西。 但是,这是我在进入信息时所做的,我只检索六位数字的代码,将其捆绑在一个意图中,并将其发送给需要它的活动或片段,并validation代码。 这个例子显示你已经获得短信的方式。 查看下面的代码,了解如何使用LocalBrodcastManager进行发送,如果您的消息中包含更多的文本,例如Greetings,则将其标准化,以便更好地帮助您。 例如,“您的validation码是:84HG73”,您可以创build像这样的([0-9]){2}([AZ]){2}([0-9]){2}这样的正则expression式模式,两个[大写]字母和两个整数。 祝你好运!

丢弃消息中所有不需要的信息后

  Intent intent = new Intent("AddedItem"); intent.putExtra("items", code); LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent); 

和接收它的片段/活动

 @Override public void onResume() { LocalBroadcastManager.getInstance(getActivity()).registerReceiver(receiver, new IntentFilter("AddedItem")); super.onResume(); } @Override public void onPause() { super.onDestroy(); LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(receiver); } 

而代码意味着处理你收集的有效载荷

  private BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction()) { final String message = intent.getStringExtra("message"); //Do whatever you want with the code here } } }; 

这有一点帮助吗? 我使用Callbacks做得更好

对不起,迟到的答复,但仍然觉得像张贴我的答案,如果有帮助。它适用于6位OTP。

  @Override public void onOTPReceived(String messageBody) { Pattern pattern = Pattern.compile(SMSReceiver.OTP_REGEX); Matcher matcher = pattern.matcher(messageBody); String otp = HkpConstants.EMPTY; while (matcher.find()) { otp = matcher.group(); } checkAndSetOTP(otp); } Adding constants here public static final String OTP_REGEX = "[0-9]{1,6}"; 

对于短信听众,可以按照下面的类

 public class SMSReceiver extends BroadcastReceiver { public static final String SMS_BUNDLE = "pdus"; public static final String OTP_REGEX = "[0-9]{1,6}"; private static final String FORMAT = "format"; private OnOTPSMSReceivedListener otpSMSListener; public SMSReceiver(OnOTPSMSReceivedListener listener) { otpSMSListener = listener; } @Override public void onReceive(Context context, Intent intent) { Bundle intentExtras = intent.getExtras(); if (intentExtras != null) { Object[] sms_bundle = (Object[]) intentExtras.get(SMS_BUNDLE); String format = intent.getStringExtra(FORMAT); if (sms_bundle != null) { otpSMSListener.onOTPSMSReceived(format, sms_bundle); } else { // do nothing } } } @FunctionalInterface public interface OnOTPSMSReceivedListener { void onOTPSMSReceived(@Nullable String format, Object... smsBundle); } } @Override public void onOTPSMSReceived(@Nullable String format, Object... smsBundle) { for (Object aSmsBundle : smsBundle) { SmsMessage smsMessage = getIncomingMessage(format, aSmsBundle); String sender = smsMessage.getDisplayOriginatingAddress(); if (sender.toLowerCase().contains(ONEMG)) { getIncomingMessage(smsMessage.getMessageBody()); } else { // do nothing } } } private SmsMessage getIncomingMessage(@Nullable String format, Object aObject) { SmsMessage currentSMS; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && format != null) { currentSMS = SmsMessage.createFromPdu((byte[]) aObject, format); } else { currentSMS = SmsMessage.createFromPdu((byte[]) aObject); } return currentSMS; }