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

Flutter开发音频播放器:如何重命名/删除本地音频文件?

Flutter音频播放器:文件重命名与删除功能实现方案

核心前提:权限配置

操作本地音频文件需先获取对应权限,不同平台配置如下:

  • Android:
    在AndroidManifest.xml中添加权限:
    <!-- Android 12及以下 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
    <!-- Android 13+ -->
    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
    
  • iOS:
    在Info.plist中添加权限描述:
    <key>NSFileProviderDomainUsageDescription</key>
    <string>需访问音频文件以完成重命名和删除操作</string>
    <key>NSAppleMusicUsageDescription</key>
    <string>需访问媒体库以获取音频文件列表</string>
    

一、单个文件重命名实现

利用Dart的dart:io包操作文件,结合on_audio_query获取的音频路径完成重命名,步骤如下:

  1. 获取目标音频路径:从on_audio_query返回的AudioModel对象中取出data字段(即音频文件的本地路径)。
  2. 构造新文件路径:保留原文件后缀,替换文件名,推荐使用path包处理路径(需在pubspec.yaml中添加path依赖)。
  3. 执行重命名并刷新媒体库:调用File.rename()完成操作后,需刷新on_audio_query的音频列表,同时通知系统媒体库更新(避免缓存残留)。

示例代码:

import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:on_audio_query/on_audio_query.dart';

Future<void> renameAudio(AudioModel audio, String newFileName) async {
  final originalFile = File(audio.data!);
  if (!await originalFile.exists()) return;

  // 保留原文件后缀,构造新路径
  final fileExt = p.extension(audio.data!);
  final newFilePath = p.join(p.dirname(audio.data!), '$newFileName$fileExt');

  // 检查新路径是否已存在,避免覆盖
  if (await File(newFilePath).exists()) {
    print('文件名已存在,请更换名称');
    return;
  }

  try {
    await originalFile.rename(newFilePath);
    // 刷新音频列表
    await OnAudioQuery().querySongs();
    // Android平台通知媒体库更新(需通过MethodChannel调用原生代码)
    if (Platform.isAndroid) {
      await const MethodChannel('com.your.app.audio_scanner')
          .invokeMethod('scanFile', {'path': newFilePath});
    }
  } catch (e) {
    print('重命名失败: $e');
  }
}

Android原生侧的MediaScanner调用(需在MainActivity.kt中添加MethodChannel逻辑):

class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.your.app.audio_scanner"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "scanFile") {
                val path = call.argument<String>("path")
                path?.let {
                    MediaScannerConnection.scanFile(
                        this,
                        arrayOf(it),
                        null
                    ) { _, _ -> result.success(null) }
                } ?: result.error("INVALID_PATH", "文件路径为空", null)
            } else {
                result.notImplemented()
            }
        }
    }
}

二、单个/多个文件删除实现

基于dart:io的File.delete()方法,批量删除可通过Future.wait()实现并行处理,步骤如下:

  1. 遍历选中的音频列表:对每个音频对象获取本地路径。
  2. 执行删除操作:检查文件存在后调用delete(),批量处理时用Future.wait()等待所有操作完成。
  3. 刷新媒体库与音频列表:删除后需通知系统媒体库移除已删除文件,同时刷新on_audio_query的查询结果。

示例代码:

import 'dart:io';
import 'package:on_audio_query/on_audio_query.dart';

Future<void> deleteSelectedAudios(List<AudioModel> selectedAudios) async {
  final deleteTasks = selectedAudios.map((audio) async {
    final audioFile = File(audio.data!);
    if (await audioFile.exists()) {
      await audioFile.delete();
      // Android平台通知媒体库更新
      if (Platform.isAndroid) {
        await const MethodChannel('com.your.app.audio_scanner')
            .invokeMethod('scanFile', {'path': audio.data!});
      }
    }
  });

  try {
    await Future.wait(deleteTasks);
    // 刷新音频列表
    await OnAudioQuery().querySongs();
  } catch (e) {
    print('删除失败: $e');
  }
}

注意事项

  • 异常处理:需捕获文件不存在、权限不足、文件被占用等异常,给用户友好提示。
  • 文件名唯一性:重命名前务必检查新路径是否存在,避免覆盖用户文件。
  • iOS媒体库更新:iOS平台删除或重命名后,可通过NSFileManager发送NSMetadataQueryDidUpdateNotification通知系统刷新媒体库。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:06:19