Flutter:Path_provider无法获取Android外部存储根目录怎么办?
解决方案
1. 先明确Android存储权限限制
从Android 10(API 29)开始,系统引入Scoped Storage机制,默认禁止应用直接访问外部存储根目录及其他应用的专属目录。哪怕你申请了READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限,也只能访问媒体文件,无法直接获取根目录路径并自由写入非媒体文件。
2. 分Android版本处理
(1)Android 9及以下(API 28及更低)
可以通过Flutter调用原生Android API获取根目录,步骤如下:
- 原生Android端(Kotlin示例):
import android.os.Environment import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel class MainActivity : FlutterActivity() { private val CHANNEL = "com.example.storage/path" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> if (call.method == "getExternalStorageRoot") { val rootPath = Environment.getExternalStorageDirectory().absolutePath result.success(rootPath) } else { result.notImplemented() } } } }
- Flutter端调用代码:
import 'package:flutter/services.dart'; Future<String?> getExternalStorageRoot() async { const platform = MethodChannel('com.example.storage/path'); try { final String? path = await platform.invokeMethod('getExternalStorageRoot'); return path; } on PlatformException catch (e) { print("获取根目录失败: '${e.message}'."); return null; } }
注意:要确保AndroidManifest.xml里已经添加了READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限,并且在运行时动态请求权限。
(2)Android 10及以上(API 29+)
受Scoped Storage限制,无法直接获取根目录并自由写入:
- 如果是访问根目录下的媒体文件(图片、视频、音频等),可以使用
path_provider_ex扩展插件,但它只能获取公共媒体目录,仍拿不到根目录路径。 - 若必须访问根目录(非媒体场景),可在
AndroidManifest.xml的<application>标签里添加android:requestLegacyExternalStorage="true",但这个属性仅对Android 10生效,Android 11及以上版本会强制启用Scoped Storage,该属性失效。
3. 推荐的替代方案
如果你的核心需求是存储文件,优先考虑:
- 使用
getExternalStorageDirectory()返回的应用专属目录,无需额外权限,文件会随应用卸载自动删除。 - 存储媒体文件时,使用
media_store插件访问系统媒体库,符合Scoped Storage规范。
内容的提问来源于stack exchange,提问作者Артём Колдунов
相关产品推荐
相关产品推荐

