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
risposta
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
non dovresti ignorare 'onPause()' invece di 'onDestroy()'? – gldraphael
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 –
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
Questo mi ha aiutato e ha lavorato anche per me:
http://androiddhina.blogspot.in/2015/06/reading-incoming-message-automatically-to-verify-OTP.html
Inoltre si prega di non dimenticate per rendere static
al tuo EditText
dal Activity/Fragment
statico EditText ??? Non è una buona scelta per creare statico. –
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);
}
probabilmente la soluzione migliore, e anche facile. – TharakaNirmana
funziona anche su torrone ... bella biblioteca .. –
La migliore soluzione di sempre. Grazie mille –
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;
}
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
- 1. WCF MaxReceivedMessageSize non essere letto dal config
- 2. Spring Batch: org.springframework.batch.item.ReaderNotOpenException: Reader deve essere aperto prima di poter essere letto
- 3. come deve essere salvato il token di aggiornamento
- 4. Come deve essere memorizzato il token di accesso all'API Web?
- 5. Il token deve essere un token di breve durata e in un intervallo di tempo ragionevole
- 6. File IO non sembra essere letto correttamente
- 7. Entity Framework Codice Primo e CA2227 "Proprietà della raccolta deve essere letto solo"
- 8. Il rfc1034identifier deve essere rimosso dal CFBundleIdentifier nel file plist?
- 9. JAXB cosa deve essere restituito dal metodo `beforeMarshal (Marshaller)`?
- 10. Token antlr dal file
- 11. PHP letto dal file di testo caricato?
- 12. angularjs letto dal file delle proprietà
- 13. Come determinare lo stato del messaggio (letto/non letto) nella chat?
- 14. Web deve essere installato
- 15. Erlang: OTP vs spawn
- 16. Errore "Questo messaggio non supporta l'operazione perché è stato letto"
- 17. JavaScript SDK Un token di accesso attivo deve essere usato per interrogare le informazioni sull'utente corrente
- 18. Come posso contrassegnare un messaggio come letto in MailKit
- 19. Il nome dell'attività principale deve essere .MainActivity?
- 20. Revisiona automaticamente token OAuth per l'account google
- 21. OAuthException: Un token di accesso attivo deve essere usato per interrogare le informazioni sull'utente corrente
- 22. Come posso utilizzare PHP per pubblicare dinamicamente un file ical che deve essere letto da Google Calendar?
- 23. Erlang OTP supervisione Java applicazione
- 24. L'entità deve essere gestita per chiamare rimuovere
- 25. UIGraphicsBeginImageContext deve essere compatibile con Retina?
- 26. elemento RelativeLayout deve essere dichiarato
- 27. MongoCollection.forEach deve essere thread-safe?
- 28. Quando deve essere utilizzato WS_EX_NOREDIRECTIONBITMAP?
- 29. Perché COBOL deve essere rientrato?
- 30. Perché constexpr deve essere statico?
Sì, l'OTP viene inviato come messaggio di testo. Ad esempio: "Immettere questa OTP nell'app: 989809" – user1903022
È 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 –
Ma è così che viene fatto in WhatsApp. Invia il messaggio token/OTP/autenticazione e l'OTP da quel messaggio viene letto automaticamente. – user1903022