Вы можете использовать словари для этого. Словари - это хранилища ключей и ценностей.
>>> dct = {'x': 1, 'y': 2, 'z': 3}
>>> dct
{'y': 2, 'x': 1, 'z': 3}
>>> dct["y"]
2
Вы можете использовать имена переменных ключей для достижения эффекта переменных переменных без риска для безопасности.
>>> x = "spam"
>>> z = {x: "eggs"}
>>> z["spam"]
'eggs'
В тех случаях, когда вы думаете сделать что-то вроде
var1 = 'foo'
var2 = 'bar'
var3 = 'baz'
...
список может быть более подходящим, чем dict. Список представляет упорядоченную последовательность объектов с целыми индексами:
l = ['foo', 'bar', 'baz']
print(l[1]) # prints bar, because indices start at 0
l.append('potatoes') # l is now ['foo', 'bar', 'baz', 'potatoes']
Для упорядоченных последовательностей списки удобнее, чем dict с целыми ключами, потому что списки поддерживают итерацию в порядке индекса, slicing , append
и другие операции, которые потребуют неудобного управления ключами с помощью dict.
Я не рекомендую использовать сторонние библиотеки для автоматического извлечения OTP из SMS-сообщений. Это можно сделать легко, если у вас есть базовое понимание Broadcast Receiver и как оно работает. Просто попробуйте следующий подход:
Шаг 1) Создайте единый интерфейс, т.е. SmsListner
package com.wnrcorp.reba; public interface SmsListener{ public void messageReceived(String messageText);}
Шаг 2) Создайте единый широковещательный приемник, то есть 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>
Скриншоты для проверки OTP Активность, в которой вы выбираете OTP как сообщения, полученные сообщениями
Я реализовал что-то подобное. Но вот то, что я сделал, когда приходит сообщение, я извлекаю только шестизначный код, собираю его в намерении и отправляю его на активность или фрагмент, нуждающийся в этом, и проверяет код. В этом примере показан способ получения смс. Посмотрите на приведенный ниже код для иллюстрации того, как отправлять с помощью LocalBrodcastManager, и если ваше сообщение содержит больше текстов. Например, приветствуйте, стандартизируйте его, чтобы помочь вам лучше. Например, «Ваш код проверки: 84HG73» вы можете создать шаблон регулярного выражения, подобный этому ([0-9]){2}([A-Z]){2}([0-9]){2}
, что означает два ints, две [столичные] буквы и два ints. Удачи!
После отбрасывания всей ненужной информации из сообщения
Intent intent = new Intent("AddedItem");
intent.putExtra("items", code);
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
И Fragment / Activity, получающего его
@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
Это помогло мне, а также помогло мне:
http://androiddhina.blogspot.in/2015/06/reading-incoming-message-automatically-to-verify-OTP. html
Также не забудьте сделать static
на EditText
с вашего Activity/Fragment
**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>
Вы можете попробовать использовать простую библиотеку, например https://github.com/stfalcon-studio/SmsVerifyCatcher
. После установки с помощью градиента и добавления разрешений инициируйте SmsVerifyCatcher в методе, подобном 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
}
});
Кроме того, переопределить методы жизненного цикла:
@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);
}