如何解决Flutter中OS Error: Operation not permitted, errno = 1报错问题
解决方案
核心原因
该报错由两个常见问题共同导致:Android 13+ 存储权限规则变更、文件名包含安卓文件系统不支持的特殊字符。
具体修复步骤
1. 调整AndroidManifest.xml权限配置
适配不同安卓版本的权限要求,修改权限声明如下:
<!-- 安卓12及以下存储权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> <!-- 安卓13及以上图片权限 --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
注意:如果你的targetSdkVersion >= 33,android:requestLegacyExternalStorage="true"配置会自动失效,无需保留。
2. 修正权限申请逻辑
permission_handler 8.1.6版本在安卓13+上不能再使用Permission.storage申请权限,需要按系统版本区分申请:
import 'dart:io'; import 'package:permission_handler/permission_handler.dart'; import 'package:device_info_plus/device_info_plus.dart'; Future<bool> _requestPermission() async { if (Platform.isAndroid) { final androidInfo = await DeviceInfoPlugin().androidInfo; late Permission permission; if (androidInfo.version.sdkInt >= 33) { permission = Permission.photos; } else { permission = Permission.storage; } // 先检查权限是否已授予 if (await permission.isGranted) { return true; } // 未授予则申请 final status = await permission.request(); return status.isGranted; } // iOS权限逻辑可自行补充 return false; }
调用下载前先判断权限返回结果,只有返回true时才执行下载逻辑。上面代码用到的DeviceInfoPlugin来自device_info_plus包,需要自行引入到pubspec.yaml依赖中。
3. 修正文件名
安卓文件系统不支持文件名包含:、/、\、*等特殊字符,你当前的文件名带时间冒号,需要替换:
Future<File> downloadImage(Uint8List data, String name) async { // 替换文件名中的非法字符 final safeName = name.replaceAll(':', '-').replaceAll('/', '-'); Directory tempDir = await DownloadsPathProvider.downloadsDirectory; String tempPath = tempDir.path; var filePath = '$tempPath/$safeName'; var bytes = ByteData.view(data.buffer); final buffer = bytes.buffer; return File(filePath).writeAsBytes( buffer.asUint8List(data.offsetInBytes, data.lengthInBytes)); }
4. 可选优化
downloads_path_provider已经停止维护,长期使用建议替换为gal或者image_gallery_saver等仍在更新的媒体存储库,适配性更好。
内容的提问来源于stack exchange,提问作者qing
相关产品推荐
相关产品推荐

