无法从消息中读取OTP

时间:2017-02-10 06:34:02

标签: android one-time-password

我试图从消息中读取OTP,但我无法自动阅读它。请告诉我我做错了什么,这是我的代码。我使用marshmallow。谢谢。

这是我的SmsReceiver类:

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

这是界面

  public interface SmsListener {
    public void messageReceived(String messageText);
   }

这是我的活动

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

}

5 个答案:

答案 0 :(得分:2)

这是我工作的广播接收器类,它将读取消息体和数字的数字。使用OTP代码广播到相关类

您需要在清单文件中添加这些权限

    <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" />

这是我的接收器类

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

我已经在我的课程程序中注册了这个接收器,因为我知道OTP短信将在我的提交按钮点击&amp;我在OTP读取后取消注册,因为我不希望通过在清单中注册它来触发每个SMS的接收器。

SmsListener smsListener = new SmsListener();
    try {
        unregisterReceiver(smsListener);
    } catch (Exception e) {
    }
    registerReceiver(smsListener, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));

修改

在您的活动中放置接收器以获取OTP代码

final String DISPLAY_MESSAGE_ACTION = activity.getPackageName() + ".CodeSmsReceived";
        try {
            activity.unregisterReceiver(mHandleMessageReceiver);
        } catch (Exception e) {
        }
        activity.registerReceiver(mHandleMessageReceiver, new IntentFilter(DISPLAY_MESSAGE_ACTION));

在接收下面的代码时,方法将被称为

 /**
     * 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"));
            }
        }
    };

答案 1 :(得分:0)

对于Marshmallow,您必须要求用户授予权限。即使您在manifest中声明它,也不会默认提供。 您需要添加代码才能获得marshmallow设备的运行时权限。

目前只是为了检查,您可以转到settings --> Apps --> go to your in the list --> click on permissions --> Enable SMS permission.然后重新启动您的应用并检查它是否正常工作。

希望它会对你有所帮助。

答案 2 :(得分:0)

将MyOtpActivity更改为

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

            }
        }
    }
}

}

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

}

答案 3 :(得分:0)

由于谷歌政策,您无法通过广播接收器读取包含 OTP 字样的短信。

答案 4 :(得分:0)

由于谷歌政策,您无法通过广播接收器读取包含 OTP 字样的短信,Ridhika 说得很好.... OTP 消息只能由消息正文中包含其 HashCode 的应用读取。