Android 13中Flutter项目存储权限失效问题求助
解决Android 13下Flutter存储权限不显示及申请失败问题
问题根源
- Android 13(API 33)已废弃
READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限,这两个权限不会再出现在系统权限设置界面中。 - 调试提示**"清单中未找到权限:[]22"**,其中22对应
MANAGE_EXTERNAL_STORAGE权限的代码,说明你未在Manifest中声明该权限,直接导致权限申请失败。 MANAGE_EXTERNAL_STORAGE是Android 10+的特殊权限,无法通过常规弹窗申请,必须引导用户到系统设置中手动开启。
解决方案一:使用MANAGE_EXTERNAL_STORAGE权限(适合需访问全存储场景)
1. 修正AndroidManifest.xml配置
添加MANAGE_EXTERNAL_STORAGE权限,并保留旧版本兼容的存储权限:
<uses-permission android:name="android.permission.INTERNET" /> <!-- 兼容Android 9及以下版本 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="29" /> <!-- Android 10+ 全存储访问权限 --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" />
2. 修正权限申请代码
针对Android 10+调整权限申请逻辑,引导用户到特殊权限设置页面:
import 'package:device_info_plus/device_info_plus.dart'; import 'package:permission_handler/permission_handler.dart'; Future<bool> requestStoragePermission() async { AndroidDeviceInfo deviceInfo = await DeviceInfoPlugin().androidInfo; if (deviceInfo.version.sdkInt >= 30) { final status = await Permission.manageExternalStorage.status; if (status.isGranted) { return true; } else { // 引导用户到系统设置开启特殊权限 await openAppSettings(); // 再次检查权限状态 return await Permission.manageExternalStorage.status.isGranted; } } else { // Android 9及以下,申请传统存储权限 final status = await Permission.storage.status; if (status.isGranted) { return true; } else { final result = await Permission.storage.request(); return result.isGranted; } } }
解决方案二:无需特殊权限,直接写入公共Downloads目录(推荐)
如果仅需下载PDF到公共Downloads目录,完全不需要申请存储权限,用MediaStore API直接写入即可,避免权限申请流程:
import 'dart:io'; import 'dart:typed_data'; import 'package:media_store_plus/media_store_plus.dart'; Future<void> savePdfToPublicDownloads(Uint8List pdfBytes, String fileName) async { try { if (Platform.isAndroid) { final mediaStore = MediaStore(); // 创建并写入到公共Downloads目录 final uri = await mediaStore.createFile( path: MediaStore.downloadsDirectory, mimeType: 'application/pdf', displayName: fileName, ); await File.fromUri(uri).writeAsBytes(pdfBytes); } else { // iOS端保存到应用沙盒目录 final dir = await getApplicationDocumentsDirectory(); final file = File('${dir.path}/$fileName'); await file.writeAsBytes(pdfBytes); } } catch (e) { print('PDF保存失败:$e'); } }
注:需在
pubspec.yaml中添加media_store_plus依赖。
关键注意事项
- 使用
MANAGE_EXTERNAL_STORAGE权限时,需在Google Play控制台提交权限声明,明确说明应用需要全存储访问的原因,否则可能无法通过审核。 - 优先选择解决方案二,符合Android 13权限规范,无需处理复杂的权限申请逻辑。
内容的提问来源于stack exchange,提问作者Ashraful Alam
相关产品推荐
相关产品推荐

