低Android SDK下Flutter permission_handler报错,求存储权限解决方案
问题概述
我开发了一款类似Udemy的Flutter应用,支持用户从服务器下载视频到本地观看。这个功能在Debug模式下正常运行,但切换到Profile模式后完全失效,推测是存储权限未正确申请导致的。引入permission_handler包尝试解决权限问题时,遇到了编译错误:
C:\src\flutter\.pub-cache\hosted\pub.dartlang.org\permission_handler_android-10.2.0\android\src\main\java\com\baseflow\permissionhandler\PermissionManager.java:469: error: cannot find symbol if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
由于项目需要兼容低版本Android SDK,无法升级SDK版本来适配TIRAMISU(API 33),现寻求无需使用permission_handler或基于该包的存储权限申请解决方案。
解决方案
方案一:不依赖permission_handler,原生代码实现权限申请
针对不同Android版本的存储权限逻辑,直接通过Flutter的MethodChannel调用原生代码完成权限申请:
配置AndroidManifest.xml权限声明
在android/app/src/main/AndroidManifest.xml中添加对应权限:<!-- 仅适配Android 10及以下版本 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29"/>Android原生端代码(Kotlin示例)
在MainActivity中实现权限申请逻辑:class MainActivity : FlutterActivity() { private val PERMISSION_CHANNEL = "com.your.app/storage_permission" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, PERMISSION_CHANNEL) .setMethodCallHandler { call, result -> when (call.method) { "requestStoragePermission" -> { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1001 ) } else { result.success(true) } } else { // Android 11+ 无需申请存储权限,直接返回成功 result.success(true) } } else -> result.notImplemented() } } } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == 1001) { val channel = MethodChannel(flutterEngine?.dartExecutor?.binaryMessenger, PERMISSION_CHANNEL) channel.invokeMethod("permissionResult", grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) } } }Flutter端调用代码
通过MethodChannel与原生交互:import 'package:flutter/services.dart'; const MethodChannel _permissionChannel = MethodChannel('com.your.app/storage_permission'); Future<bool> requestStoragePermission() async { try { return await _permissionChannel.invokeMethod('requestStoragePermission') as bool; } on PlatformException catch (e) { print("权限申请出错:${e.message}"); return false; } } // 监听权限申请结果 void initState() { super.initState(); _permissionChannel.setMethodCallHandler((call) async { if (call.method == 'permissionResult') { bool isGranted = call.arguments as bool; // 根据权限结果处理后续下载逻辑 } }); }
方案二:降级permission_handler版本适配低SDK
选择不依赖TIRAMISU(API 33)的旧版本permission_handler,例如9.2.0版本:
修改pubspec.yaml依赖
dependencies: permission_handler: ^9.2.0执行
flutter pub get更新依赖。Flutter端权限申请逻辑
import 'package:permission_handler/permission_handler.dart'; import 'package:device_info_plus/device_info_plus.dart'; Future<bool> checkAndRequestStoragePermission() async { if (Platform.isAndroid) { final androidInfo = await DeviceInfoPlugin().androidInfo; if (androidInfo.version.sdkInt <= 29) { final status = await Permission.storage.request(); return status.isGranted; } else { // Android 11+ 无需申请存储权限 return true; } } else { // iOS平台权限申请逻辑 final status = await Permission.storage.request(); return status.isGranted; } }
额外注意事项
- Profile模式下Flutter的Debug权限豁免机制失效,必须确保权限申请流程完整且正确
- Android 11+版本优先使用App专属目录(如
getExternalFilesDir(Environment.DIRECTORY_MOVIES))存储下载视频,无需申请存储权限即可写入 - 测试时务必切换到Profile模式验证功能,避免Debug模式的权限豁免误导判断
内容的提问来源于stack exchange,提问作者suman chakravarty
相关产品推荐
相关产品推荐

