2015-06-16 14 views
14

Sto lavorando su un'app Android, in cui il server invia un OTP e l'utente deve inserire questo OTP nell'app, a Iscriviti alla mia app. Quello che voglio è che la mia app sia in grado di leggere automaticamente l'OTP inviato dal server. Come posso raggiungere questo obiettivo? Qualsiasi aiuto o guida in questo senso sarebbe molto apprezzato.OTP (token) deve essere letto automaticamente dal messaggio

+0

Sì, l'OTP viene inviato come messaggio di testo. Ad esempio: "Immettere questa OTP nell'app: 989809" – user1903022

+0

È possibile leggere messaggi di testo scrivendo un ricevitore di trasmissione. Ma sopra il livello API 19, è necessario creare un'app sms predefinita per leggere i messaggi. Quindi non penso sia possibile. O forse è possibile: controllare questo collegamento http://stackoverflow.com/questions/19856338/using-new-telephony-content-provider-to-read-sms –

+0

Ma è così che viene fatto in WhatsApp. Invia il messaggio token/OTP/autenticazione e l'OTP da quel messaggio viene letto automaticamente. – user1903022

risposta

3

Ho implementato qualcosa di simile. Ma ecco cosa ho fatto quando arriva il messaggio, recupero solo il codice a sei cifre, lo raggruppo in un intento e lo invio all'attività o al frammento che ne ha bisogno e verifica il codice. L'esempio mostra il modo di ottenere già gli sms. Guarda il codice qui sotto per le illustrazioni su come inviare usando LocalBrodcastManager e se il tuo messaggio contiene più testi E.g Saluti, standardizzalo per aiutarti meglio. E.g "Il tuo codice di verifica è: 84HG73" puoi creare un modello regex come questo ([0-9]){2}([A-Z]){2}([0-9]){2} che significa due inte, due lettere [maiuscole] e due inte. In bocca al lupo!

Dopo aver scartato tutto un Info necessaria dal messaggio

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

e il frammento/attività che lo riceve

@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); 
} 

E il codice destinato a gestire il carico utile avete raccolto

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 
     } 
    } 
}; 

Questo aiuta un po '. L'ho fatto meglio utilizzando richiamate

+0

non dovresti ignorare 'onPause()' invece di 'onDestroy()'? – gldraphael

+0

Dipende da come si desidera utilizzarlo.Se il 'Fragment' o' Activity' è sempre attivo, lasciatelo in 'onPause' ma nel mio caso per cui ne ho bisogno solo una volta, posso rilasciarlo in' onPause' o 'onDestroy' poiché entrambi sarebbero chiamati in ogni caso –

+1

Mi dispiace non essere stato abbastanza chiaro. La chiamata a onDestroy() è [non garantita] (http://developer.android.com/reference/android/app/Activity.html#onDestroy%28%29). Dovrebbe usare onStop() o onPause() a seconda del contesto. Destra? – gldraphael

12

Puoi provare a utilizzare una semplice libreria come https://github.com/stfalcon-studio/SmsVerifyCatcher

Dopo l'installazione tramite Gradle e l'aggiunta di autorizzazioni di avviare SmsVerifyCatcher nel metodo come attività onCreate:

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 
    } 
}); 

Inoltre, l'attività di override metodi 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); 
} 
+0

probabilmente la soluzione migliore, e anche facile. – TharakaNirmana

+0

funziona anche su torrone ... bella biblioteca .. –

+0

La migliore soluzione di sempre. Grazie mille –

2

Ci scusiamo per ritardo di risposta, ma ancora sentivo come distacco la mia risposta se aiuta. Funziona con OTP a 6 cifre.

@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}"; 

Per ascoltatore SMS si può seguire la classe sotto

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; 
    } 
6

mi consiglia di non utilizzare librerie di terze parti per auto prendere OTP da SMS in arrivo. Questo può essere fatto facilmente se si ha una conoscenza di base di Broadcast Receiver e come funziona. Basta provare seguente approccio:

Fase 1) Creare un'unica interfaccia cioè SmsListner

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

Punto 2) Creare singolo Broadcast Receiver cioè 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; 
} 
} 

Fase 3) Aggiungi Listener cioè ricevitore di broadcast in Android file manifesto

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

e aggiungere il permesso

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

Final Step 4) L'attività in cui stai andando a recuperare automaticamente otp quando viene ricevuto in inbo X. Nel mio caso sto recuperando otp e impostando il campo di 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();   
      } 
    }); 
    } 
} 

File Layout per 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> 

Screenshots for OTP Verification Activity where you fetch OTP as soons as messages received

Problemi correlati