问题
i m trying to read OTP from message, but i cant auto read it.please tell me what i did wrong, here is my code.i m using marshmallow. thank you.
here is my SmsReceiver class:
public class SmsReceiver extends BroadcastReceiver {
private static SmsListener mListener;
@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();
//You must check here if the sender is your provider and not another one with same text.
String messageBody = smsMessage.getMessageBody();
//Pass on the text to our listener.
mListener.messageReceived(messageBody);
}
}
public static void bindListener(SmsListener listener) {
mListener = listener;
}}
here is interface
public interface SmsListener {
public void messageReceived(String messageText);
}
and this is my activity
public class MyOTP extends BaseActivity implements View.OnClickListener {
EditText txtotp;
Button btnSubmitOtp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_otp);
txtotp = (EditText) findViewById(R.id.txtOtp);
btnSubmitOtp = (Button) findViewById(R.id.btnSubmit);
btnSubmitOtp.setOnClickListener(this);
SmsReceiver.bindListener(new SmsListener() {
@Override
public void messageReceived(String messageText) {
Log.d("Text",messageText);
Toast.makeText(MyOTP.this,"Message: "+messageText,Toast.LENGTH_LONG).show();
}
});
}
}
回答1:
Here is my working Broadcast receiver class which will read digits from message body & broadcast with OTP code to related class
You need to add these permissions in menifest file
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission-sdk-23 android:name="android.permission.READ_SMS" />
<uses-permission-sdk-23 android:name="android.permission.RECEIVE_SMS" />
Here is my receiver class
public class SmsListener extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
Bundle bundle = intent.getExtras(); //---get the SMS message passed in---
SmsMessage[] msgs = null;
String msg_from;
if (bundle != null) {
//---retrieve the SMS message received---
try {
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i = 0; i < msgs.length; i++) {
if (Build.VERSION.SDK_INT <= 22) {
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
} else {
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i], bundle.getString("format"));
}
msg_from = msgs[i].getOriginatingAddress();
if (msg_from.contains("PINSMS")) {
String msgBody = msgs[i].getMessageBody();
//String pinNo = msgBody.substring(msgBody.indexOf('"') + 1, msgBody.indexOf('"', msgBody.indexOf('"') + 2));
String pinNo = msgBody.replaceAll("[^0-9]", "");
Log.d("SMS", "From -" + msg_from + " : Body- " + msgBody);
//CodeVerification.insertCode(pinNo);
// Broadcast to Auto read Code sms
final String DISPLAY_MESSAGE_ACTION = context.getPackageName() + ".CodeSmsReceived";
Intent intentCodeSms = new Intent(DISPLAY_MESSAGE_ACTION);
intentCodeSms.putExtra("varificationCode", pinNo);
context.sendBroadcast(intentCodeSms);
}
}
} catch (Exception e) {
Log.d("Exception caught", e.getMessage());
}
}
}
}
}
I have registered this receiver in my class programmatic because i know OTP sms will come after my submit button click & i unregister it after OTP read as i dont want to trigger this receiver for every SMS by registering it in menifest.
SmsListener smsListener = new SmsListener();
try {
unregisterReceiver(smsListener);
} catch (Exception e) {
}
registerReceiver(smsListener, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));
EDIT
Put below receiver in your activity to get OTP code
final String DISPLAY_MESSAGE_ACTION = activity.getPackageName() + ".CodeSmsReceived";
try {
activity.unregisterReceiver(mHandleMessageReceiver);
} catch (Exception e) {
}
activity.registerReceiver(mHandleMessageReceiver, new IntentFilter(DISPLAY_MESSAGE_ACTION));
On receiving code below method will be called
/**
* Receiving Call Log Changed broadcast
*/
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.hasExtra("varificationCode")) {
String youtOTPcode = intent.getStringExtra("varificationCode"));
}
}
};
回答2:
For Marshmallow you have to ask users to give permissions. It's not given by default even if you declare it in manifest
. You need to add code to get runtime permission for marshmallow devices.
For now just for checking you can go to settings --> Apps --> go to your in the list --> click on permissions --> Enable SMS permission.
Then restart your app and check is it working.
Hope it will help you.
回答3:
Change MyOtpActivity to
public class MyOTP extends BaseActivity{
EditText txtotp;
Button btnSubmitOtp;
private UpdateOTPReceiver mUpdateOtpReceiver;
private SMSReceiver mSmsReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_otp);
txtotp = (EditText) findViewById(R.id.txtOtp);
btnSubmitOtp = (Button) findViewById(R.id.btnSubmit);
btnSubmitOtp.setOnClickListener(this);
}
@Override
protected void onStart() {
super.onStart();
mUpdateOtpReceiver = new UpdateOTPReceiver();
registerReceiver(mUpdateOtpReceiver, new IntentFilter("UPDATE_OTP"));
registerSMSReceiver();
}
private void registerSMSReceiver() {
mSmsReceiver = new SMSReceiver();
registerReceiver(mSmsReceiver, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));
}
private class UpdateOTPReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
String msg = intent.getStringExtra("msg");
Toast.makeText(MyOTP.this,"Message: "+msg,Toast.LENGTH_LONG).show();
}
}
}
}
}
In SmsReceiver
Public class SmsReceiver extends BroadcastReceiver {
@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();
//ToDo check your sender
String messageBody = smsMessage.getDisplayMessageBody();
Intent updateTokenIntent = new Intent("UPDATE_OTP");
updateTokenIntent.putExtra("msg", getVerificationCode(messageBody));
context.sendBroadcast(updateTokenIntent);
}
}
private String getVerificationCode(String message) {
if (message == null) {
return null;
}
int index = message.indexOf("is");
int index_last_length = message.indexOf(".");
if (index != -1) {
int start = index + 3;
return message.substring(start, index_last_length);
}
return null;
}
}
来源:https://stackoverflow.com/questions/42152924/cannot-read-otp-from-message