Flutter使用telephony包发送短信报错:获取SmsManager失败
问题解决:Telephony包发送短信出现PlatformException(failed_to_fetch_sms)
原因排查及修复方案
1. 补全权限配置
除了动态申请权限,必须在AndroidManifest.xml中添加基础权限声明:
<uses-permission android:name="android.permission.SEND_SMS"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <!-- 部分设备需额外添加 -->
注意Android 13及以上版本,SEND_SMS属于危险权限,必须通过代码动态申请,仅清单配置无效。
2. 确保权限已成功授权
调用sendSms前必须确认权限已获取,不能跳过检查直接执行发送:
final bool hasPermission = await Telephony.instance.requestSmsPermissions; if (hasPermission) { await Telephony.instance.sendSms( to: controller1.text, message: controller2.text ); } else { // 处理权限被拒绝的逻辑 }
3. 排查实例冲突与资源占用
- 检查项目中是否同时引入了其他短信相关插件,这类插件可能会抢占SmsManager资源导致获取失败,建议暂时移除冲突插件测试。
- 重启测试设备或模拟器,避免进程内资源残留问题。
4. 适配定制ROM权限限制
部分国产定制ROM(如小米、华为)对短信权限有额外管控,需手动进入系统设置,确认当前应用已开启「发送短信」权限。优先使用物理设备测试,模拟器可能存在SmsManager模拟异常。
5. 备选:改用原生Intent发送短信
如果上述方案无效,可以通过原生Intent方式替代telephony包的发送逻辑:
import 'package:flutter/services.dart'; void sendSms(String phone, String content) async { try { await MethodChannel('app.sms.channel').invokeMethod( 'sendSms', {'phone': phone, 'content': content} ); } on PlatformException catch (e) { // 处理发送错误 } }
对应Android原生代码(在MainActivity中配置):
class MainActivity : FlutterActivity() { private val CHANNEL = "app.sms.channel" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> if (call.method == "sendSms") { val phone = call.argument<String>("phone") val content = call.argument<String>("content") try { val intent = Intent(Intent.ACTION_VIEW).apply { data = Uri.parse("smsto:$phone") putExtra("sms_body", content) } startActivity(intent) result.success(true) } catch (e: Exception) { result.error("SEND_FAILED", "短信发送失败", e.message) } } else { result.notImplemented() } } } }
内容的提问来源于stack exchange,提问作者Vepa Sabyrow
相关产品推荐
相关产品推荐

