OTP (token) debe ser leído automáticamente desde el mensaje
Estoy trabajando en una aplicación para Android, en la que el servidor envía una OTP y el usuario necesita ingresar esta OTP en la aplicación, a SignUp para mi aplicación. Lo que quiero es, que mi aplicación debe ser capaz de leer automáticamente el OTP enviado por el servidor. ¿Cómo puedo conseguir esto? Cualquier ayuda u orientación en este sentido sería muy apreciada.
Puede probar con una biblioteca simple como https://github.com/stfalcon-studio/SmsVerifyCatcher
Después de instalar a través de Gradle y agregar permisos iniciar SmsVerifyCatcher en el método como onCreate actividad:
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 } });
Además, sustituya los métodos de ciclo de vida de la actividad:
@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); }
Esto me ayudó y también trabajó para mí:
http://androiddhina.blogspot.in/2015/06/reading-incoming-message-automatically-to-verify-OTP.html
También por favor no olvide hacer static
a su EditText
de su Activity/Fragment
He implementado algo de eso. Pero, aquí es lo que hice cuando el mensaje llega, recupero sólo el código de seis dígitos, lo agrugo en una intención y enviarlo a la actividad o fragmento que lo necesitan y verifica el código. El ejemplo muestra la forma de obtener los sms ya. Mire el código de abajo para ver la ilustración sobre cómo enviar usando LocalBrodcastManager y si su mensaje contiene más textos, por ejemplo, Greetings, estandarizarlo para ayudarlo mejor. Por ejemplo: "Su código de verificación es: 84HG73" puede crear un patrón de regex como este ([0-9]){2}([AZ]){2}([0-9]){2}
que significa dos ints, Dos letras [mayúsculas] y dos ints. ¡Buena suerte!
Después de descartar toda la información no necesaria del mensaje
Intent intent = new Intent("AddedItem"); intent.putExtra("items", code); LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
Y el Fragmento / Actividad que lo recibe
@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); }
Y el código destinado a manejar la carga útil que recogió
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 } } };
¿Eso ayuda un poco. Lo hice mejor utilizando devoluciones de llamada
Lo siento por la respuesta tardía, pero todavía me sentí como publicar mi respuesta si help.It funciona para 6 dígitos 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}";
Para el oyente de SMS se puede seguir la siguiente clase
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; }
Te recomendaré que no uses bibliotecas de terceros para buscar automáticamente OTP desde la bandeja de entrada de SMS. Esto se puede hacer fácilmente si tiene conocimientos básicos de Broadcast Receiver y cómo funciona. Sólo intente seguir el siguiente enfoque:
Paso 1) Crear interfaz única, es decir, SmsListner
package com.wnrcorp.reba; public interface SmsListener{ public void messageReceived(String messageText);}
Paso 2) Cree un único receptor de difusión, es decir, 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; } }
Paso 3) Añadir Listener es decir receptor de difusión en el archivo de manifiesto android
<receiver android:name=".SmsReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver>
Y agregar permiso
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
Paso final 4) La actividad en la que va a buscar auto otp cuando se recibe en la bandeja de entrada. En mi caso, estoy buscando otp y el ajuste en el campo 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(); } }); } }
Archivo de presentación de 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>
Capturas de pantalla para la actividad de verificación de OTP donde obtiene OTP como soons como mensajes recibidos