Flutter中使用just_audio播放音乐时如何显示媒体通知?
实现带媒体控制的通知栏播放器
要实现类似音乐APP的通知栏播放器,用flutter_local_notifications完全可行,核心是配置媒体样式通知,并和just_audio的播放状态联动,下面是具体实现步骤:
1. 添加依赖与权限配置
首先在pubspec.yaml中引入所需依赖:
dependencies: flutter_local_notifications: ^最新版本号 just_audio: ^最新版本号
Android端配置
- 在
AndroidManifest.xml添加通知权限与后台播放权限:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
iOS端配置
- 在
Info.plist中开启后台音频权限:
<key>UIBackgroundModes</key> <array> <string>audio</string> </array>
2. 初始化通知插件
先完成通知插件的初始化,同时创建专属的媒体通知通道:
late FlutterLocalNotificationsPlugin notificationsPlugin; void initNotifications() async { notificationsPlugin = FlutterLocalNotificationsPlugin(); // 初始化配置 const AndroidInitializationSettings androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); const DarwinInitializationSettings iosInit = DarwinInitializationSettings( requestAlertPermission: false, requestBadgePermission: false, requestSoundPermission: false, ); const InitializationSettings initSettings = InitializationSettings( android: androidInit, iOS: iosInit, ); // 绑定通知点击回调 await notificationsPlugin.initialize( initSettings, onDidReceiveNotificationResponse: (response) => handleNotificationAction(response.actionId!), ); // 创建媒体专属通知通道(Android必填) const AndroidNotificationChannel mediaChannel = AndroidNotificationChannel( 'music_player_channel', '音乐播放器', description: '显示音乐播放控制按钮', importance: Importance.high, playSound: false, enableVibration: false, groupKey: AndroidNotificationChannelGroup.mediaGroupId, ); await notificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.createNotificationChannel(mediaChannel); }
3. 创建并显示媒体通知
根据当前播放状态生成带控制按钮的通知,重点是配置MediaStyleInformation实现媒体样式:
void showMusicNotification({ required String songTitle, required String artistName, String? albumArtLocalPath, required bool isPlaying, }) async { // 定义通知操作按钮 final List<AndroidNotificationAction> actions = [ const AndroidNotificationAction( 'prev', '上一曲', showsUserInterface: false, icon: DrawableResourceAndroidBitmap('ic_skip_previous'), ), AndroidNotificationAction( isPlaying ? 'pause' : 'play', isPlaying ? '暂停' : '播放', showsUserInterface: false, icon: DrawableResourceAndroidBitmap(isPlaying ? 'ic_pause' : 'ic_play'), ), const AndroidNotificationAction( 'next', '下一曲', showsUserInterface: false, icon: DrawableResourceAndroidBitmap('ic_skip_next'), ), ]; // Android媒体通知详情配置 final AndroidNotificationDetails androidDetails = AndroidNotificationDetails( 'music_player_channel', '音乐播放器', importance: Importance.high, priority: Priority.high, ongoing: true, // 通知无法被滑动删除 autoCancel: false, styleInformation: const MediaStyleInformation( mediaSessionId: 'music_session', showCancelButton: false, ), actions: actions, largeIcon: albumArtLocalPath != null ? FilePathAndroidBitmap(albumArtLocalPath) : null, smallIcon: const DrawableResourceAndroidBitmap('ic_music_note'), ); // iOS通知配置 final DarwinNotificationDetails iosDetails = DarwinNotificationDetails( categoryIdentifier: 'music_player', presentAlert: false, presentBadge: false, presentSound: false, ); final NotificationDetails notificationDetails = NotificationDetails( android: androidDetails, iOS: iosDetails, ); // 显示/更新通知(固定ID实现覆盖更新) await notificationsPlugin.show( 1, songTitle, artistName, notificationDetails, ); }
4. 联动just_audio播放状态
监听AudioPlayer的状态变化,实时更新通知内容:
late AudioPlayer audioPlayer; void initAudioPlayer() async { audioPlayer = AudioPlayer(); // 监听播放状态变更,同步更新通知 audioPlayer.playbackEventStream.listen((event) { final bool isPlaying = event.processingState == ProcessingState.playing; showMusicNotification( songTitle: '你的歌曲标题', artistName: '歌手名称', albumArtLocalPath: '本地封面图路径', // 网络图需先下载到本地再传入 isPlaying: isPlaying, ); }); // 加载音频资源 await audioPlayer.setUrl('音频文件URL'); }
5. 处理通知按钮点击事件
实现按钮对应的播放控制逻辑:
void handleNotificationAction(String actionId) async { switch (actionId) { case 'play': await audioPlayer.play(); break; case 'pause': await audioPlayer.pause(); break; case 'prev': // 自定义上一曲逻辑 break; case 'next': // 自定义下一曲逻辑 break; } }
注意事项
- Android通知图标需放在
res/drawable或res/mipmap目录,确保为透明背景的符合系统规范的图标。 - 网络封面图需先下载到本地存储,再通过
FilePathAndroidBitmap传入。 - iOS媒体通知样式相对简洁,控制按钮需提前在
Info.plist配置通知类别。
内容的提问来源于stack exchange,提问作者mohammad
相关产品推荐
相关产品推荐

