使用 Sms Retriever 时无法获取 OTP
Cannot get OTP when use Sms Retriever
我正在尝试使用 Google 的短信检索器 API 进行自动短信验证。我已按照说明 here 进行操作,但我的应用程序没有收到任何短信。我已经尝试了很多方法,但它仍然无法正常工作,我真的不明白为什么。
这是我所做的。首先我创建 class 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();
}
}
对于classOTPActivity
,我删除了不相关的代码:
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);
}
}
}
Google 最近更改了短信策略。现在您必须以这种方式发送短信,OTP:
消息 (otp) 应以前缀 <#>
开头
消息 (otp) 不能超过 140 字节
消息 (otp) 应以 11 个字符结尾
标识您的应用程序的哈希字符串。
这个 post 将是 helpfully
确保 emulator/device 上的播放服务版本 > 10.2.0
您无需在清单 中添加任何权限,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.have 您在清单中添加了以下代码
<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,我会向您推荐这个 package SMS 这在 android 上非常有效,它只有 2 行代码
获取传入的短信;
创建接收器实例
SmsReceiver receiver = new SmsReceiver();
在您的初始化状态中收听传入的短信
receiver.onSmsReceived.listen((SmsMessage msg) => print(msg.body));
这很好用,但不幸的是这个包不支持 ios
我正在尝试使用 Google 的短信检索器 API 进行自动短信验证。我已按照说明 here 进行操作,但我的应用程序没有收到任何短信。我已经尝试了很多方法,但它仍然无法正常工作,我真的不明白为什么。
这是我所做的。首先我创建 class 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();
}
}
对于classOTPActivity
,我删除了不相关的代码:
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);
}
}
}
Google 最近更改了短信策略。现在您必须以这种方式发送短信,OTP:
消息 (otp) 应以前缀 <#>
开头
消息 (otp) 不能超过 140 字节
消息 (otp) 应以 11 个字符结尾 标识您的应用程序的哈希字符串。
这个 post 将是 helpfully
确保 emulator/device 上的播放服务版本 > 10.2.0
您无需在清单 中添加任何权限,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.have 您在清单中添加了以下代码
<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,我会向您推荐这个 package SMS 这在 android 上非常有效,它只有 2 行代码 获取传入的短信;
创建接收器实例
SmsReceiver receiver = new SmsReceiver();
在您的初始化状态中收听传入的短信
receiver.onSmsReceived.listen((SmsMessage msg) => print(msg.body));
这很好用,但不幸的是这个包不支持 ios