Flutter应用无READ SMS权限时控制台打印异常问题求助
问题描述
我编写了如下Flutter代码,希望在应用没有读取SMS权限时控制台打印“no permission”,但运行时报错:
SmsQuery query = new SmsQuery(); List<SmsMessage> AllMessages = []; Timer? _timer; var SMSPermStatus = Permission.sms.status; @override void initState() { if (SMSPermStatus.isDenied == true) { print("give me read SMS perm"); } else { _timer = Timer.periodic(const Duration(seconds: 1), (Timer t) { try { GetAllMessages(); } catch(e) { print("give me read SMS perm"); } print("refreshed"); print(AllMessages); // [] }); } super.initState(); } Future<void> GetAllMessages() async { List<SmsMessage> messages = await query.querySms( kinds: [SmsQueryKind.inbox], count: 50, ); setState(() { AllMessages = messages; }); }
报错截图:
请问该如何解决这个错误?
解决方案
你的代码存在两个核心问题,导致权限判断失效并触发报错:
1. 错误处理异步权限状态
Permission.sms.status返回的是Future<PermissionStatus>,并非直接的权限状态值。你直接调用SMSPermStatus.isDenied,本质是对Future对象访问不存在的属性,这会直接引发错误。必须通过await在异步环境中获取真实的权限状态。
2. 未正确捕获异步异常
GetAllMessages()是异步方法,你在try块中直接调用却未使用await,导致异步抛出的异常无法被当前catch块捕获。
修正后的完整代码
SmsQuery query = SmsQuery(); List<SmsMessage> allMessages = []; Timer? _timer; @override void initState() { _initPermissionAndTimer(); super.initState(); } // 异步处理权限与定时器初始化 Future<void> _initPermissionAndTimer() async { final permissionStatus = await Permission.sms.status; if (permissionStatus.isDenied) { print("no permission"); // 可选:主动请求权限 // final requestResult = await Permission.sms.request(); // if (requestResult.isGranted) _startMessageTimer(); } else { _startMessageTimer(); } } void _startMessageTimer() { _timer = Timer.periodic(const Duration(seconds: 1), (Timer t) async { try { await getAllMessages(); // 使用await捕获异步异常 } catch (e) { print("no permission"); // 可选:捕获异常后停止定时器 // t.cancel(); } print("refreshed"); print(allMessages); }); } Future<void> getAllMessages() async { final messages = await query.querySms( kinds: [SmsQueryKind.inbox], count: 50, ); setState(() { allMessages = messages; }); } @override void dispose() { _timer?.cancel(); // 页面销毁时取消定时器,避免内存泄漏 super.dispose(); }
额外优化说明
- 遵循Dart命名规范:变量和方法名采用小驼峰格式(如
allMessages、getAllMessages) - 在
dispose方法中取消定时器,防止页面销毁后定时器持续运行引发内存泄漏 - 可在权限被拒绝时主动调用
Permission.sms.request()发起权限请求,优化用户体验
内容的提问来源于stack exchange,提问作者Emir Bolat
相关产品推荐
相关产品推荐

