Flutter在Android 13中如何访问外部存储的PDF与文本文件?
在Flutter中访问Android 13外部存储的PDF/文本文件(含权限处理)
一、核心权限逻辑
Android 13拆分媒体权限后,PDF、文本这类非媒体文件并不适用那三个媒体权限,适配逻辑分版本:
- Android 13及以上:无需申请媒体权限,优先通过用户主动选择文件的方式获取访问权;若需批量扫描存储,可申请
READ_MEDIA_VISUAL_USER_SELECTED(针对用户授权的文件集合),或特殊场景下用MANAGE_EXTERNAL_STORAGE(需Google审核,不推荐普通应用使用)。 - Android 12及以下:仍需申请传统的
READ_EXTERNAL_STORAGE权限。
二、具体实现步骤
1. 引入依赖插件
在pubspec.yaml中添加必要的权限管理和文件操作插件:
dependencies: permission_handler: ^10.2.0 # 权限管理 file_picker: ^5.3.0 # 文件选择器(推荐方式)
2. 配置AndroidManifest.xml
在android/app/src/main/AndroidManifest.xml中声明对应权限:
<!-- Android 12及以下权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Android 13及以上,针对用户授权文件集合的权限 --> <uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" /> <!-- 仅文件管理器类应用使用,需Google审核 --> <!-- <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> -->
3. 代码实现
方式一:用户主动选择文件(推荐,无审核风险)
通过file_picker让用户自主选择PDF/文本文件,无需额外权限申请(Android 13及以上):
import 'package:file_picker/file_picker.dart'; import 'dart:io'; Future<void> pickTargetFile() async { FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.custom, allowedExtensions: ['pdf', 'txt'], // 指定允许的文件类型 ); if (result != null) { String filePath = result.files.single.path!; // 读取文件内容示例 String fileContent = await File(filePath).readAsString(); print('文件内容:$fileContent'); } else { print('用户取消了文件选择'); } }
方式二:权限申请后扫描存储(需合规)
若需批量扫描存储中的目标文件,先申请对应权限再操作:
import 'package:permission_handler/permission_handler.dart'; import 'package:path_provider/path_provider.dart'; import 'dart:io'; // 申请存储权限 Future<bool> requestStoragePermission() async { PermissionStatus status; if (await DeviceInfoPlugin().androidInfo.version.sdkInt >= 33) { // Android 13及以上申请对应权限 status = await Permission.mediaVisualUserSelected.request(); } else { // Android 12及以下申请传统存储权限 status = await Permission.storage.request(); } return status.isGranted; } // 扫描下载目录中的PDF/文本文件 Future<void> scanDownloadsFolder() async { if (await requestStoragePermission()) { Directory? downloadsDir = await getExternalStorageDirectory(); if (downloadsDir != null) { List<FileSystemEntity> files = downloadsDir.listSync(); for (var file in files) { String path = file.path; if (path.endsWith('.pdf') || path.endsWith('.txt')) { print('找到目标文件:$path'); } } } } else { print('权限未授予,无法访问存储'); } }
三、注意事项
MANAGE_EXTERNAL_STORAGE权限需在Google Play后台提交权限使用说明,非文件管理类应用大概率会被拒审,尽量避免使用。- Android 13及以上系统对非媒体文件的直接访问限制严格,用户主动选择文件是最合规的实现方式。
内容的提问来源于stack exchange,提问作者vike
相关产品推荐
相关产品推荐

