返回
Android 11文件管理适配扫盲指南,助您轻松上手!
Android
2023-11-28 12:00:50
Android 11 的文件管理革新:开发者适配指南
Android 11 中的文件管理革命
Android 11 在文件管理方面进行了全面改革,带来了全新的存储访问框架 (SAF)、分区存储和外部存储调整。这些变化旨在增强安全性和用户隐私,同时也为开发者带来了新的挑战。
存储访问框架 (SAF)
SAF 统一了对所有存储设备的访问,包括内部存储、外部存储和云存储。应用不再可以直接访问文件系统,而是必须使用 SAF 来请求对文件的访问权限。这有助于防止恶意应用访问用户数据。
分区存储
分区存储将内部存储划分为两个分区:
- 应用分区: 仅用于存储应用自己的数据,例如应用设置和缓存。
- 媒体分区: 用于存储用户生成的数据,例如照片、视频和音乐。
这种分区有助于将应用数据与用户数据分隔开来,增强了安全性。
外部存储
Android 11 中,应用不再能够直接访问外部存储。必须通过 SAF 来访问外部存储,这提供了更严格的访问控制。
开发者适配指南
为了在 Android 11 上顺畅运行,开发者需要对应用进行适配:
使用 SAF 访问文件
使用 SAF 访问文件的步骤:
- 创建一个 Intent,指定要执行的操作(例如,选择文件或创建文件)。
- 设置 Intent 的过滤器,以指定要访问的文件类型。
- 启动 Intent,并处理用户选择的或创建的文件。
处理分区存储
- 将用户生成的数据存储到媒体分区。
- 将应用专属数据存储到应用分区。
处理外部存储
- 通过 SAF 访问外部存储。
- 不要直接访问外部存储。
注意事项
- 更新应用的目标 SDK 版本到 Android 11 或更高。
- 使用 AndroidX 库。
- 彻底测试应用,确保在 Android 11 设备上正常运行。
常见问题解答
1. 如何使用 SAF 获取文件的读取权限?
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT);
2. 如何将文件写入媒体分区?
Uri uri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, "image.jpg");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
Uri newUri = getContentResolver().insert(uri, values);
OutputStream outputStream = getContentResolver().openOutputStream(newUri);
// 将数据写入输出流...
3. 为什么我的应用无法访问外部存储?
确保已通过 SAF 访问外部存储,并且已请求并获得了必要的权限。
4. 如何将应用数据从内部存储迁移到媒体分区?
// 获取要迁移的数据的 URI
Uri dataUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI;
// 创建新的内容 URI,指向媒体分区
Uri mediaUri = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL);
// 迁移数据
try {
getContentResolver().move(dataUri, mediaUri);
} catch (IOException e) {
// 处理错误
}
5. 如何处理SAF授权变更?
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_OPEN_DOCUMENT && resultCode == RESULT_OK) {
// 检查授权是否已被撤销
if (DocumentFile.isDocumentUri(this, data.getData())) {
DocumentFile documentFile = DocumentFile.fromSingleUri(this, data.getData());
if (documentFile != null && !documentFile.canRead()) {
// 授权已被撤销,提示用户重新授权
requestReadAccess(documentFile);
}
}
}
}