One Tap SMS Verification API无法捕获含OTP的短信问题求助
看起来你遇到的核心问题是短信没有被SMS Retriever API识别到,结合你的代码和短信内容,我整理了几个最可能的原因和对应的解决办法:
1. 短信缺少应用哈希字符串(最关键原因)
Google的SMS Retriever API要求短信必须包含你的应用生成的唯一哈希字符串,这个字符串是API识别该短信属于你的应用的核心标识。你的短信内容"Your code is 221-222"完全没有这个哈希,所以API根本不会触发回调。
解决方法:
生成你的应用哈希字符串:可以通过官方推荐的工具类实现:
class AppSignatureHelper(context: Context) { fun getAppSignatures(): List<String> { val appCodes = ArrayList<String>() try { val packageName = context.packageName val packageManager = context.packageManager val signatures = packageManager.getPackageInfo( packageName, PackageManager.GET_SIGNATURES ).signatures for (signature in signatures) { val message = packageName + " " + signature.toCharsString() val md = MessageDigest.getInstance("SHA-1") val hashBytes = md.digest(message.toByteArray(Charsets.UTF_8)) val hashHex = String.format("%040x", BigInteger(1, hashBytes)) appCodes.add(hashHex.substring(0, 11)) } } catch (e: PackageManager.NameNotFoundException) { e.printStackTrace() } catch (e: NoSuchAlgorithmException) { e.printStackTrace() } return appCodes } }在你的Fragment中调用
AppSignatureHelper(requireContext()).getAppSignatures()就能获取到哈希字符串。如果你的应用使用Google Play App Signing,还需要从Google Play Console获取对应的签名哈希。调整短信格式:短信必须满足以下格式(哈希需单独占一行且位于末尾):
Your code is 221-222 FA+9qCX9VSu另外短信整体长度不能超过140字节,验证码需为4-10位的清晰数字串。
2. 广播接收器的生命周期管理问题
你在onResume中注册了广播接收器,但没有提到在页面暂停/销毁时注销,这可能导致接收器泄漏,或者在某些场景下无法正常接收广播。
解决方法:
在onPause中添加注销逻辑:
override fun onPause() { super.onPause() try { activity?.unregisterReceiver(smsVerificationReceiver) Log.d(TAG, "unregistered sms verification receiver") } catch (e: IllegalArgumentException) { Log.e(TAG, "Receiver not registered", e) } }
3. 权限与API版本兼容问题
虽然SMS Retriever API不需要READ_SMS权限,但你当前只在API 26及以上版本注册接收器,而API本身支持API 19及以上设备。建议兼容低版本设备的注册逻辑:
override fun onResume() { super.onResume() val intentFilter = IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { activity?.registerReceiver(smsVerificationReceiver, intentFilter, SmsRetriever.SEND_PERMISSION, null) } else { activity?.registerReceiver(smsVerificationReceiver, intentFilter) } Log.d(TAG, "registered the sms verification receiver") }
4. 短信内容的隐性要求
除了哈希,API对短信还有一些细节要求:
- 短信必须来自非联系人号码(你的情况符合,但如果后续测试联系人号码可能不会触发);
- 验证码尽量使用纯数字串(带分隔符如
221-222理论上不影响,但建议测试纯数字验证码排除格式问题); - 短信中不能包含链接、广告类内容,否则可能被API过滤。
先优先检查并添加应用哈希字符串,这是绝大多数此类问题的核心解决点。
内容的提问来源于stack exchange,提问作者android enthusiast

