Flutter集成SMS Retriever API后,Truecaller为默认短信应用时OTP自动读取失效的问题咨询
嘿,我之前做Flutter项目集成OTP自动读取的时候,也踩过Truecaller当默认短信应用的坑,太懂这种正常场景没问题、换个默认应用就罢工的烦躁了!先把你的问题背景理清楚:
- 你在Flutter中集成了Android的SMS Retriever API,常规情况下OTP自动读取功能正常
- 但将Truecaller设为默认短信应用后,自动读取完全失效
- 你的AndroidManifest.xml中接收器配置如下:
<receiver android:name="com.npst.coreplugin.SmsBroadcastReciever" android:exported="true"> <intent-filter android:priority="9999"> <action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/> </intent-filter> </receiver>
- 发送的OTP短信格式也符合规范:
<#> Your OTP for Mobile Banking is 325033. It is valid for 1 mins. Do not share the OTP to anybody. Bank will NEVER ask, for you to verify it gWcC3DfezLK.- payimane
给你几个亲测有效的解决思路:
第一个推荐方案:换成SMS User Consent API
这是我当时解决问题的关键!SMS Retriever API其实依赖系统默认短信应用转发SMS_RETRIEVED广播,但Truecaller这类第三方默认短信应用根本不会转发这个广播,导致你的应用收不到回调。而SMS User Consent API是系统直接弹个小窗口让用户同意读取当前的OTP短信,不管默认短信应用是谁,系统都会触发这个流程,兼容性拉满。而且这个API不需要申请读取短信的敏感权限,完全符合现在的隐私要求。你在Flutter里可以自己写个平台通道调用Android原生API,或者找个靠谱的Flutter插件封装一下,很快就能搞定。
备选方案:申请读取短信权限,直接监听原始短信广播
如果你不在乎申请敏感权限的话,这也是个可行的路子。你可以在AndroidManifest里给广播接收器加上android.provider.Telephony.SMS_RECEIVED这个action,把优先级设得比9999更高(比如10000),然后在Flutter代码里动态申请READ_SMS权限。这样你的应用就能直接收到短信广播,自己解析里面的OTP,不用看默认短信应用的脸色。不过要注意,这个权限是敏感权限,上架应用市场的时候可能需要额外说明用途,得权衡一下。
辅助提示:让用户检查Truecaller设置
有些用户可能在Truecaller里开了拦截第三方应用短信的设置,你可以在应用的帮助文档或者OTP输入页面加个提示,告诉用户如果自动读取失效,去Truecaller的权限设置里允许你的应用接收短信相关事件。不过这个是用户侧的操作,只能作为补充方案,毕竟咱们不能要求所有用户都去改设置对吧?
内容来源于stack exchange

