retrieval - sms retriever api android example
OTP(token) debe leerse automáticamente del mensaje (6)
Esto me ayudó y también me funcionó:
http://androiddhina.blogspot.in/2015/06/reading-incoming-message-automatically-to-verify-OTP.html
Además, no olvide hacer static
a su EditText
de su Activity/Fragment
Estoy trabajando en una aplicación de Android, en la que el servidor envía una OTP y el usuario debe ingresar esta OTP en la aplicación, para suscribirse a mi aplicación. Lo que quiero es que mi aplicación pueda leer automáticamente la OTP enviada por el servidor. ¿Cómo puedo conseguir esto? Cualquier ayuda u orientación en este sentido sería muy apreciada.
Implementé algo de eso tal. Pero, esto es lo que hice cuando llega el mensaje, recupero solo el código de seis dígitos, lo agrupo en un intento y lo envío a la actividad o fragmento que lo necesita y verifica el código. El ejemplo te muestra la manera de obtener los sms ya. Mire el código a continuación para ver una ilustración de cómo enviar usando LocalBrodcastManager y si su mensaje contiene más textos, por ejemplo, Saludos, estandarícelo para ayudarlo mejor. Por ejemplo, "Su código de verificación es: 84HG73" puede crear un patrón de expresión regular 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 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 usando Callbacks
Le recomendaré que no utilice bibliotecas de terceros para obtener automáticamente OTP desde la Bandeja de entrada de SMS. Esto se puede hacer fácilmente si tiene un conocimiento básico de Broadcast Receiver y cómo funciona. Solo intente seguir el enfoque:
Paso 1) Crear una interfaz única, es decir, SmsListner
package com.wnrcorp.reba;
public interface SmsListener{
public void messageReceived(String messageText);}
Paso 2) Crear 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) Agregue Listener, es decir, receptor de difusión en un archivo de manifiesto de 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 se va a buscar automáticamente cuando se recibe en la bandeja de entrada. En mi caso, estoy buscando OTP y configurando en el campo de edición de texto.
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 diseño para 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 en la que obtiene OTP como puntos como mensajes recibidos
Puedes intentar usar una biblioteca simple like
Después de instalar via gradle y agregar permisos, inicie SmsVerifyCatcher en un método como onCreate activity:
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, anular los métodos de actividad del ciclo de vida:
@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);
}
public String parseCode(String message) {
Pattern p = Pattern.compile("//b//d{4}//b");
Matcher m = p.matcher(message);
String code = "";
while (m.find()) {
code = m.group(0);
}
return code;
}
Lo siento por la respuesta tardía, pero aún siento como si publicara mi respuesta si ayuda. Funciona para OTP de 6 dígitos.
@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 uno 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;
}
**activity_main.xml**
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.mukundwn.broadcastreceiver.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
**MainActivity.java**
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private BroadcastReceiver broadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
broadcastReceiver =new MyBroadcastReceiver();
}
@Override
protected void onStart()
{
super.onStart();
IntentFilter intentFilter=new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(broadcastReceiver,intentFilter);
}
@Override
protected void onStop()
{
super.onStop();
unregisterReceiver(broadcastReceiver);
}
}
**MyBroadcastReceiver.java**
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
/**
* Created by mukundwn on 12/02/18.
*/
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"hello received an sms",Toast.LENGTH_SHORT).show();
}
}
**Manifest.xml**
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mukundwn.broadcastreceiver">
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVE"></action>
</intent-filter>
</receiver>
</application>
</manifest>