You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何申请外部存储访问权限删除歌曲文件 现有删除代码对外部存储无效

外部存储歌曲删除功能适配方案

原有直接调用File.delete()的逻辑仅对应用私有目录下的文件生效,安卓10及以上版本引入了分区存储限制,公共外部存储目录的媒体文件无法直接通过文件路径删除,需要适配分区存储规则实现。

1. 权限适配

  • 安卓10(API 29)及以下:声明并动态申请WRITE_EXTERNAL_STORAGE权限,获取权限后可直接通过路径操作公共媒体文件
  • 安卓11(API 30)及以上:操作公共音频文件无需申请所有文件访问权限,仅需申请音频媒体权限,非自身应用生成的媒体文件删除时会触发系统级授权弹窗,用户确认后可完成删除
  • 如需上架Google Play,禁止随意申请MANAGE_EXTERNAL_STORAGE权限,不符合平台政策会直接被拒审

2. 适配实现步骤(Flutter场景)

2.1 引入依赖

在pubspec.yaml中添加权限处理和设备信息依赖:

dependencies:
  permission_handler: ^10.2.0
  device_info_plus: ^9.0.2
  media_store: ^0.1.3 # 用于调用安卓媒体库API

2.2 权限申请逻辑封装

import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:permission_handler/permission_handler.dart';

Future<bool> requestAudioOperatePermission() async {
  if (!Platform.isAndroid) return true;
  final androidInfo = await DeviceInfoPlugin().androidInfo;
  final sdkInt = androidInfo.version.sdkInt;
  if (sdkInt >= 33) {
    return await Permission.audio.request().isGranted;
  } else if (sdkInt >= 29) {
    return await Permission.storage.request().isGranted;
  } else {
    return await Permission.writeExternalStorage.request().isGranted;
  }
}

2.3 替换原有删除逻辑

import 'package:media_store/media_store.dart';

Future<void> deleteTargetSong() async {
  // 先校验权限
  final hasPermission = await requestAudioOperatePermission();
  if (!hasPermission) {
    print("无音频文件操作权限");
    return;
  }
  final androidInfo = await DeviceInfoPlugin().androidInfo;
  // 高版本安卓走媒体库API删除
  if (Platform.isAndroid && androidInfo.version.sdkInt >= 30) {
    // 注意:singleTrack需要提前存储对应媒体库的id字段,可在扫描歌曲时获取
    final deleteResult = await MediaStore.delete(
      uri: Uri.parse("content://media/external/audio/media/${widget.singleTrack!.mediaId}"),
    );
    if (deleteResult) {
      widget.allSongs!.remove(widget.singleTrack);
    } else {
      print('Song not deleted');
    }
    return;
  }
  // 低版本安卓/其他平台沿用原有文件删除逻辑
  File file = File(widget.singleTrack!.data);
  try {
    await file.delete();
    if (await file.exists()) {
      print('Song not deleted');
    } else {
      widget.allSongs!.remove(widget.singleTrack);
    }
  } catch (e) {
    print('$e');
  }
}

3. 注意事项

  • 安卓11及以上操作公共媒体文件必须依赖媒体库ID,仅靠文件路径无法完成操作,需要在首次扫描本地歌曲时同步获取并存储对应媒体ID
  • 删除完成后可主动触发媒体库刷新,避免系统扫描到已删除的无效文件

内容的提问来源于stack exchange,提问作者Sudesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 13:36:04