我尝试使用 SmsRetrieverClient 从收到的 SMS 中读取 OTP,但广播接收器未调用
I tried to read OTP from received SMS with SmsRetrieverClient but broadcast receiver not calling
我曾尝试通过其广播接收器使用 SmsRetrieverClient 获取短信,但实际问题是当 SMS 出现时,Receive 从未调用进一步处理它,但在 5 分钟后它调用了接收器的超时方法。
实际上我尝试了库来获取 SMS 并且它工作正常但是请求 SMS 读取权限,不幸的是在将应用程序上传到 Playstore 时将面临 Google 政策问题。
下面是我的代码。
下面是我的 Activity 中的 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();
}
});
}
下面的代码是从广播接收器接收短信:
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>
非常感谢您提供解决方案,
但经过多次尝试后我找到了解决方案,广播收不到短信 otp 的原因有两个:
1) 消息应为 140 字节,如下所示 link:
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" 具有相同操作的清单中删除所有其他已注册的接收器,并仅在清单中使用具有单个声明的单个广播接收器及其操作解决了我的问题。
我曾尝试通过其广播接收器使用 SmsRetrieverClient 获取短信,但实际问题是当 SMS 出现时,Receive 从未调用进一步处理它,但在 5 分钟后它调用了接收器的超时方法。
实际上我尝试了库来获取 SMS 并且它工作正常但是请求 SMS 读取权限,不幸的是在将应用程序上传到 Playstore 时将面临 Google 政策问题。
下面是我的代码。
下面是我的 Activity 中的 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();
}
});
}
下面的代码是从广播接收器接收短信:
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>
非常感谢您提供解决方案, 但经过多次尝试后我找到了解决方案,广播收不到短信 otp 的原因有两个:
1) 消息应为 140 字节,如下所示 link:
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" 具有相同操作的清单中删除所有其他已注册的接收器,并仅在清单中使用具有单个声明的单个广播接收器及其操作解决了我的问题。