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获取的音频路径完成重命名,步骤如下:
- 获取目标音频路径:从
on_audio_query返回的AudioModel对象中取出data字段(即音频文件的本地路径)。 - 构造新文件路径:保留原文件后缀,替换文件名,推荐使用
path包处理路径(需在pubspec.yaml中添加path依赖)。 - 执行重命名并刷新媒体库:调用
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()实现并行处理,步骤如下:
- 遍历选中的音频列表:对每个音频对象获取本地路径。
- 执行删除操作:检查文件存在后调用
delete(),批量处理时用Future.wait()等待所有操作完成。 - 刷新媒体库与音频列表:删除后需通知系统媒体库移除已删除文件,同时刷新
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
相关产品推荐
相关产品推荐

