Flutter删除音频文件触发权限拒绝异常,已授权仍无法解决
问题根源
你要删除的是外置SD卡路径下的音频文件,Android 11(API 30)及以上版本对外部存储权限管控大幅收紧:普通的READ/WRITE_EXTERNAL_STORAGE权限仅能操作本APP创建的文件,无法删除外置SD卡上的非本APP生成文件,必须申请MANAGE_EXTERNAL_STORAGE特殊权限,且该权限的请求逻辑和普通存储权限不同。
解决步骤
1. 修正权限请求逻辑
需根据Android版本区分权限请求:
- Android 10及以下:使用常规
Permission.storage权限 - Android 11及以上:必须请求
Permission.manageExternalStorage权限,且系统不会弹出权限弹窗,需引导用户到应用设置页手动开启
2. 替换代码实现
将原权限请求逻辑替换为以下代码:
import 'package:permission_handler/permission_handler.dart'; import 'package:flutter/services.dart'; import 'package:device_info_plus/device_info_plus.dart'; // 检查并获取必要权限 Future<bool> checkAndRequestPermissions() async { final androidInfo = await DeviceInfoPlugin().androidInfo; final sdkVersion = androidInfo.version.sdkInt; if (sdkVersion >= 30) { // Android 11+ 请求特殊存储权限 var status = await Permission.manageExternalStorage.request(); if (status.isDenied) { // 引导用户跳转到应用设置页开启权限 await openAppSettings(); return false; } return status.isGranted; } else { // Android 10及以下 请求常规存储权限 var status = await Permission.storage.request(); return status.isGranted; } } // 执行删除操作 if (await checkAndRequestPermissions()) { if (song != null) { String? path = song.data; File file = File(path); bool isExist = await file.exists(); if (isExist) { try { await file.delete(recursive: true); print("文件删除成功"); } catch (e) { print("删除失败: $e"); } } } }
3. 完善AndroidManifest配置
确保权限声明符合版本要求,添加必要的兼容性配置:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" /> <!-- 仅Android 10及以下需要 --> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" /> <!-- 忽略分区存储警告 --> <application android:label="Example" android:name="${applicationName}" android:icon="@mipmap/ic_launcher" android:usesCleartextTraffic="true" android:requestLegacyExternalStorage="true"> <!-- Android 10兼容分区存储 --> <!-- 其他应用配置 --> </application>
4. 额外优化建议
MANAGE_EXTERNAL_STORAGE属于特殊权限,Google Play对其使用有严格审核要求。如果你的应用仅处理媒体文件,推荐使用MediaStore API删除文件(无需特殊权限),示例代码:
import 'package:flutter/services.dart'; // 通过MediaStore删除音频文件(Android 10+推荐) Future<void> deleteMediaFile(String filePath) async { final ContentResolver contentResolver = await getContentResolver(); final Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; final String selection = "_data = ?"; final List<String> selectionArgs = [filePath]; await contentResolver.delete(uri, selection, selectionArgs); }
内容的提问来源于stack exchange,提问作者Dr_Usman
相关产品推荐
相关产品推荐

