Android 使用Sms检索器时无法获取OTP

Android 使用Sms检索器时无法获取OTP,android,sms,one-time-password,Android,Sms,One Time Password,我正在尝试使用谷歌的短信检索器API进行自动短信验证。我已按照说明操作,但我的应用程序未收到任何短信。我尝试了很多方法,但仍然不起作用,我真的不明白为什么 这就是我所做的。首先,我创建类myssbroadcastreceiver: public class MySMSBroadcastReceiver extends BroadcastReceiver { public OTPReceiveListener otpReceiveListener; public void ini

我正在尝试使用谷歌的短信检索器API进行自动短信验证。我已按照说明操作,但我的应用程序未收到任何短信。我尝试了很多方法,但仍然不起作用,我真的不明白为什么

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

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);
        }
    }
}
公共类OTPActivity extends BaseActivity实现IDelegateResponse、GoogleAppClient.ConnectionCallbacks、GoogleAppClient.OnConnectionFailedListener、MySMSBroadcastReceiver.otPreviveListener{
@BindView(R.id.edtSmsOtp)
EditText-edtSmsOtp;
私有最终字符串TAG=“OTPActivity”;
私人私家车;私人私家车;私人私家车;
@凌驾
public int getLayoutID(){
返回R.layout.activity\u otp;
}
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setUpOTPSms();
}
私有void setUpOTPSms(){
AppSignatureHelper AppSignatureHelper=新AppSignatureHelper(OTPActivity.this);
Utils.showLog(标记“getAppSignatures:+appSignatureHelper.getAppSignatures());
mySMSBroadcastReceiver=新的mySMSBroadcastReceiver();
mySMSBroadcastReceiver.initotPreciveListener(此);
IntentFilter IntentFilter=新的IntentFilter();
intentFilter.addAction(SmsRetriever.SMS\u retrieve\u ACTION);
intentFilter.setPriority(2147483647);
注册接收人(mySMSBroadcastReceiver,intentFilter);
startSMSListener();
}
私有void startSMSListener(){
SmsRetrieverClient=SmsRetriever.getClient(OTPActivity.this);
Task=client.startSmsRetriever();
task.addOnSuccessListener(避免->{
//Toast.makeText(OTPActivity.this,“SMS检索器启动”,Toast.LENGTH_LONG.show();
Utils.showLog(标记“SMS检索器启动”);
});
task.addOnFailureListener(e->Toast.makeText(OTPActivity.this,“Error”,Toast.LENGTH_LONG.show());
}
@凌驾
未连接的公共无效(@Nullable Bundle){
}
@凌驾
公共空间连接暂停(int i){
}
@凌驾
public void onconnection失败(@NonNull ConnectionResult ConnectionResult){
}
@凌驾
收到的公共无效(字符串otp){
if(mySMSBroadcastReceiver!=null){
未注册接收人(myssb)和卡斯特罗接收人;
}
Utils.showLog(“收到OTP”,“OTP:+OTP”);
}
@凌驾
公共void onOTPTimeOut(){
Utils.showLog(“接收到OTP”、“onOTPTimeOut”);
}
@凌驾
受保护的空onDestroy(){
super.ondestory();
if(mySMSBroadcastReceiver!=null){
未注册接收人(myssb)和卡斯特罗接收人;
}
}
}

谷歌最近改变了短信策略。现在,您必须通过以下方式发送短信、OTP:

  • 邮件(otp)应以前缀开头

  • 消息(otp)的长度不得超过140字节

  • 消息(otp)应以11个字符结尾 标识应用程序的哈希字符串


  • 这篇文章将是

    请确保您的模拟器/设备上的play services版本>10.2.0

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

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

    如果你仍然面临困难,请告诉我

    请交叉检查您的menifest

    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>
    
    
    
  • 增加依赖性

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


  • 如果你想只为android检索OTP,我建议你这在android上运行得很好,只需2行代码 获取收到的短信

    创建receiver的实例

    SmsReceiver receiver = new SmsReceiver();
    
    在您的初始状态下,按以下方式收听传入的sms

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

    这工作得很好,但不幸的是,这个软件包不支持ios

    我也这么做,这是我的消息示例应用程序:你的验证码是143567 32urg60XXXX,但它不起作用。你获得短信权限了吗?什么权限,我只是添加了一个,试试看这不是真的,我想,因为Google的SMS Retriever API不需要许可证是的,你说得对,问题是其他一些东西经过了测试,它并不完美,但在我的Java代码项目中,它仍然不工作。感谢你的回答,但Google play services在我的手机中是15.0.90。
    receiver.onSmsReceived.listen((SmsMessage msg) => print(msg.body));