使用短信检索器时无法获得OTP

时间:2019-02-27 10:12:38

标签: android sms one-time-password

我正在尝试使用Google的SMS检索器API进行自动SMS验证。我遵循了here的指示,但是我的应用未收到任何短信。我已经尝试了很多方法,但是仍然无法正常工作,我真的不明白为什么。

这就是我所做的。首先,我创建类MySMSBroadcastReceiver

public class MySMSBroadcastReceiver extends BroadcastReceiver {

    public OTPReceiveListener otpReceiveListener;
    public void initOtpReceiveListener(OTPReceiveListener otpReceiveListener) {
        this.otpReceiveListener = otpReceiveListener;
    }

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

            switch(status.getStatusCode()) {
                case CommonStatusCodes.SUCCESS:
                    // Get SMS message contents
                    String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
                    otpReceiveListener.onOTPReceived(message);
                    break;
                case CommonStatusCodes.TIMEOUT:
                    otpReceiveListener.onOTPTimeOut();
                    break;
            }
        }
    }

    public interface OTPReceiveListener {

        void onOTPReceived(String otp);
        void onOTPTimeOut();
    }

}

对于类OTPActivity,我删除了不相关的代码:

public class OTPActivity extends BaseActivity implements IDelegateResponse<OTPResponse>, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, MySMSBroadcastReceiver.OTPReceiveListener {

    @BindView(R.id.edtSmsOtp)
    EditText edtSmsOtp;

    private final String TAG = "OTPActivity";
    private MySMSBroadcastReceiver mySMSBroadcastReceiver;

    @Override
    public int getLayoutID() {
        return R.layout.activity_otp;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setUpOTPSms();
    }

    private void setUpOTPSms() {
        AppSignatureHelper appSignatureHelper = new AppSignatureHelper(OTPActivity.this);
        Utils.showLog(TAG, "getAppSignatures:" + appSignatureHelper.getAppSignatures());

        mySMSBroadcastReceiver = new MySMSBroadcastReceiver();
        mySMSBroadcastReceiver.initOtpReceiveListener(this);

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(SmsRetriever.SMS_RETRIEVED_ACTION);
        intentFilter.setPriority(2147483647);
        registerReceiver(mySMSBroadcastReceiver, intentFilter);

        startSMSListener();
   }

    private void startSMSListener() {
        SmsRetrieverClient client = SmsRetriever.getClient(OTPActivity.this);
        Task<Void> task = client.startSmsRetriever();
        task.addOnSuccessListener(aVoid -> {
            //Toast.makeText(OTPActivity.this, "SMS Retriever starts", Toast.LENGTH_LONG).show();
            Utils.showLog(TAG, "SMS Retriever starts");
        });
        task.addOnFailureListener(e -> Toast.makeText(OTPActivity.this, "Error", Toast.LENGTH_LONG).show());
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Override
    public void onOTPReceived(String otp) {
        if (mySMSBroadcastReceiver != null) {
            unregisterReceiver(mySMSBroadcastReceiver);
        }

        Utils.showLog("OTP Received", "OTP: " + otp);
    }

    @Override
    public void onOTPTimeOut() {
        Utils.showLog("OTP Received", "onOTPTimeOut");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mySMSBroadcastReceiver != null) {
            unregisterReceiver(mySMSBroadcastReceiver);
        }
    }
}

5 个答案:

答案 0 :(得分:2)

您无需在清单中添加任何权限即可使 OPT 正常工作。 遵循给定的代码(在Kotlin中,易于实现且正在运行)。

class MainActivity : AppCompatActivity() {

private val smsBroadcastReceiver by lazy { SMSBroadcastReceiver() }

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val client = SmsRetriever.getClient(this)
    val retriever = client.startSmsRetriever()
    retriever.addOnSuccessListener {

        Toast.makeText(this@MainActivity,"Listener started", Toast.LENGTH_SHORT).show()

        val otpListener = object : SMSBroadcastReceiver.OTPListener {
            override fun onOTPReceived(otp: String) {
                customCodeInput.setText(otp)
                Toast.makeText(this@MainActivity, otp , Toast.LENGTH_LONG).show()
            }

            override fun onOTPTimeOut() {
                Toast.makeText(this@MainActivity,"TimeOut", Toast.LENGTH_SHORT).show()
            }
        }
        smsBroadcastReceiver.injectOTPListener(otpListener)
        registerReceiver(smsBroadcastReceiver,
                IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION))
    }
    retriever.addOnFailureListener {
        Toast.makeText(this@MainActivity,"Problem to start listener", Toast.LENGTH_SHORT).show()
    }

}

override fun onDestroy() {
    super.onDestroy()
    unregisterReceiver(smsBroadcastReceiver)
}}

SMSBroadcastReceiver 如下:

class SMSBroadcastReceiver: BroadcastReceiver() {

private var otpReceiver: OTPListener? = null

fun injectOTPListener(receiver: OTPListener?) {
    this.otpReceiver = receiver
}

override fun onReceive(context: Context, intent: Intent) {
    if (SmsRetriever.SMS_RETRIEVED_ACTION == intent.action) {
        val extras = intent.extras
        val status = extras.get(SmsRetriever.EXTRA_STATUS) as Status

        when (status.statusCode) {

            CommonStatusCodes.SUCCESS -> {

                val message = extras.get(SmsRetriever.EXTRA_SMS_MESSAGE) as String

                val pattern = Pattern.compile("\\d{6}")
                val matcher = pattern.matcher(message)

                if (matcher.find()) {
                    otpReceiver?.onOTPReceived(matcher.group(0))
                    return
                }
            }
            CommonStatusCodes.TIMEOUT -> {
                otpReceiver?.onOTPTimeOut()
            }
        }
    }
}

interface OTPListener {


    fun onOTPReceived(otp: String)

    fun onOTPTimeOut()
}}

PS:如果您仍然遇到困难,请告诉我。

答案 1 :(得分:1)

确保模拟器/设备上的播放服务版本为> 10.2.0

答案 2 :(得分:0)

Google最近更改了短信策略。现在,您必须通过以下方式发送OTP的短信:

  1. 消息(otp)应该以前缀<#>

  2. 开头
  3. 消息(otp)不得超过140个字节

  4. 消息(otp)应该以11个字符结尾 标识您的应用的哈希字符串。

此帖子将是helpfully

答案 3 :(得分:0)

请同时检查您的清单

1。您是否已在清单

中添加了以下代码?
<receiver android:name=".MySMSBroadcastReceiver" 
          android:exported="true">
  <intent-filter>
    <action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED" />
  </intent-filter>
</receiver>
  1. 增加依赖性

    实现“ com.google.android.gms:play-services-auth-api-phone:15.0.1”

答案 4 :(得分:0)

如果您只想为Android检索OTP,我建议您使用此package SMS,这在android及其仅两行代码上就可以很好地工作 来获取传入的短信;

创建接收者实例

SmsReceiver receiver = new SmsReceiver();

在您的初始状态下,侦听传入的短信为

receiver.onSmsReceived.listen((SmsMessage msg) => print(msg.body));

这确实很好用,但不幸的是,此软件包不支持ios