Flutter安卓端读取外部JSON文件遇存储权限拒绝问题
Android 13+ 加载第三方JSON文件权限问题解决
问题重现
应用在Linux运行正常,但Android端点击按钮加载其他程序导出的JSON文件时,抛出权限错误:
I/flutter (24500): [MethodChannelFilePicker] Platform exception: PlatformException(read_external_storage_denied, User did not allow reading external storage, null, null) E/flutter (24500): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(read_external_storage_denied, User did not allow reading external storage, null, null)
问题根源
- Android 13+权限模型变更:targetSdkVersion≥33时,原
READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE权限已被拆分,通过系统文件选择器(FilePicker依赖组件)访问用户主动选择的文件,无需提前申请存储权限。 - 权限申请逻辑错误:
Permission.storage.request()在Android 13+实际申请的是媒体文件权限(图片/视频类),与JSON文件需求不匹配,属于冗余操作。 - 冗余权限配置:
MANAGE_EXTERNAL_STORAGE是特殊全局权限,仅适用于文件管理器类应用,Google Play审核严格,无需添加。
解决方案
1. 清理AndroidManifest.xml权限
删除冗余存储权限,仅保留必要权限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <uses-permission android:name="android.permission.INTERNET"/> </manifest>
2. 移除无效权限申请逻辑
删除requestPermission()方法及调用,系统文件选择器会在用户选择文件后自动授予临时访问权限,无需提前申请。
3. 优化文件读取代码
避免直接依赖文件路径(Android 13+第三方文件路径可能无法直接访问),优先使用FilePicker提供的字节流读取:
import 'dart:convert'; import 'dart:typed_data'; import 'package:file_picker/file_picker.dart'; Future<void> pickFile(parent) async { FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.custom, allowedExtensions: ['json'], withData: true, // 直接获取文件字节数据 ); if (result != null) { try { final Uint8List? bytes = result.files.single.bytes; if (bytes != null) { String fileContent = utf8.decode(bytes); Map<String, dynamic> jsonData = jsonDecode(fileContent); // 处理解析后的JSON数据 } } catch (e) { print('读取或解析JSON错误: $e'); } } }
兼容旧版本(可选)
若需兼容Android 12及以下版本,可添加版本判断的权限申请:
import 'package:permission_handler/permission_handler.dart'; import 'package:device_info_plus/device_info_plus.dart'; Future<void> checkLegacyStoragePermission() async { final androidInfo = await DeviceInfoPlugin().androidInfo; if (androidInfo.version.sdkInt < 33) { final status = await Permission.storage.status; if (!status.isGranted) { await Permission.storage.request(); } } }
验证方案
编译运行应用,点击按钮调用文件选择器,选择第三方导出的JSON文件,可正常读取解析,无权限错误。
内容的提问来源于stack exchange,提问作者Xaver
相关产品推荐
相关产品推荐

