You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

低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调用原生代码完成权限申请:

  1. 配置AndroidManifest.xml权限声明
    在android/app/src/main/AndroidManifest.xml中添加对应权限:

    <!-- 仅适配Android 10及以下版本 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29"/>
    
  2. 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)
            }
        }
    }
    
  3. 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版本:

  1. 修改pubspec.yaml依赖

    dependencies:
      permission_handler: ^9.2.0
    

    执行flutter pub get更新依赖。

  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 15:40:24