安卓文件访问限制
Android 10(API 级别 29)引入了Scoped Storage 机制,旨在提升用户数据隐私性和安全性。此机制下,应用对设备外部存储的访问被限制,默认情况下只能访问应用自己的沙盒目录(如 /storage/emulated/0/Android/data/<package_name>/
)。
在 Scoped Storage 下,应用无法直接访问 /storage/emulated/0/31010
这样的路径,除非使用特殊权限或框架。
1.特殊权限 manageExternalStorage
从 Android 11(API 级别 30)开始,引入了 MANAGE_EXTERNAL_STORAGE
权限,允许应用有管理外部存储的能力,可以访问所有文件。然而,使用这个权限有较高的要求,需要用户手动确认授予权限,
用法:
参考Android13关于获取外部存储文件的相关问题及解决方案记录_android13 申请非媒体文件管理权限-CSDN博客
注意在配置使用manageExternalStorage后如果启动报manifest格式错误,可尝试将
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
中的tools:ignore="ScopedStorage"删掉。导致该类错误的可能原因
- 权限声明冲突:
MANAGE_EXTERNAL_STORAGE
是一个特殊权限,可能导致与其他库或模块的权限声明发生冲突,进而导致 Manifest 合并错误。 - 权限要求过高:如果应用实际上并不需要这么高权限的存储访问,声明这个权限反而可能引发不必要的复杂性和错误。
- Android 版本兼容性问题:不同 Android 版本对该权限的处理方式不同,在某些版本上声明该权限可能会导致问题。
2.Storage Access Framework (SAF)
示例:
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
void pickFile() async {
final result = await FilePicker.platform.pickFiles(
initialDirectory: '/storage/emulated/0/31010',
);
if (result != null) {
final file = result.files.first;
print('Picked file: ${file.path}');
} else {
// User canceled the picker
}
}
注意:该方法只能用于用户手动选择文件,并不能在程序内部按预定好的路径去自动读取。