我试图通过SmsRetrieverClient从收到的SMS中读取OTP,但广播接收器未调用

时间:2019-04-09 09:55:24

标签: android android-sms

我试图通过其广播接收器使用SmsRetrieverClient来获取短信,真正的问题是SMS出现时接收不再调用以对其进行进一步处理,但是稍后5分钟后它将调用接收器的超时方法。

实际上,我尝试通过库来获取SMS及其功能,但是要求获得SMS读取权限,不幸的是,在Play商店上载应用程序时,这将面临Google政策问题。

下面是我的代码。

下面是我的活动中的SmsRetrieverClient方法:

 private void startSMSListener() {

    SmsRetrieverClient smsRetrieverClient = SmsRetriever.getClient(this);
    Task<Void> retriever = smsRetrieverClient.startSmsRetriever();
    retriever.addOnSuccessListener(new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {
            SMSBroadcastReceiver.OTPListener otpListener = new SMSBroadcastReceiver.OTPListener() {
                @Override
                public void onOTPReceived(String otpData) {
                    inputOTP.setText(otpData);
                }

                @Override
                public void onOTPTimeOut() {
                    inputOTP.setText("");
                    Toast.makeText(ctx, "TimeOut", Toast.LENGTH_SHORT).show();
                }
            };

            smsBroadcastReceiver.injectOTPListener(otpListener);
            registerReceiver(smsBroadcastReceiver, new IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION));
        }
    });

    retriever.addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Toast.makeText(ctx, "Problem to start listener", Toast.LENGTH_SHORT).show();
        }
    });

}

以下代码是从广播接收器接收SMS:

public class SMSBroadcastReceiver extends BroadcastReceiver {
private OTPListener otpReceiver;

public void injectOTPListener(OTPListener receiver) {
    this.otpReceiver = receiver;
}

@Override
public void onReceive(Context context, Intent intent) {
    if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
        Bundle extras = intent.getExtras();
        Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
        System.out.println("SMS verification code::SMSBroadcastReceiver:0:  "+ status);

        switch (status.getStatusCode()) {

            case CommonStatusCodes.SUCCESS:

                String message = (String)extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
                Pattern pattern = Pattern.compile("\\d{4}");
                Matcher matcher = pattern.matcher(message);
                System.out.println("SMS verification code::SMSBroadcastReceiver:1:  "+ message);

                if (matcher.find()) {
                    if (otpReceiver != null){
                        otpReceiver.onOTPReceived(matcher.group(0));
                    }
                }
                break;

            case CommonStatusCodes.TIMEOUT:
                System.out.println("SMS verification code::SMSBroadcastReceiver:2:  TIMEOUT");

                if (otpReceiver != null){
                    otpReceiver.onOTPTimeOut();
                }
                break;
        }
    }
}


public interface OTPListener {

    void onOTPReceived(String otp);

    void onOTPTimeOut();
}
}

在清单中:

     <receiver android:name=".SMSBroadcastReceiver"
        android:exported="true">
        <intent-filter>
            <action 

 android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>

        </intent-filter>
        </receiver>

1 个答案:

答案 0 :(得分:0)

非常感谢您提供您的解决方案, 但经过多次尝试后,我发现了解决方案,原因是广播未收到SMS otp的原因有两个:

1)消息应为140字节,如以下链接所示:

https://developers.google.com/identity/sms-retriever/verify#1_construct_a_verification_message

2)我发现在开发广播时,我得到了2到3个广播Java文件,这些文件已添加到我的应用程序中,用于测试SMS的每个代码都有不同的代码,并且我以相同的动作显示了所有SMS广播接收器,是没有意义的。 因此,最后从与“ com.google.android.gms.auth.api.phone.SMS_RETRIEVED”相同动作的清单中删除所有其他已注册的接收器,并且仅在清单中具有单个声明的单个广播接收器上工作,此动作解决了我的问题。