HarmonyOS 鸿蒙Next中播控中心未显示当前播放的音频
HarmonyOS 鸿蒙Next中播控中心未显示当前播放的音频 我使用AVPlayer播放本地mp3音频,然后开启了后台长时任务,现在可以实现切换后台或者锁屏后继续播放。但是在系统的播控中心里,不展示当前播放的音频。我按照官方文档去设置了AVSession的原数据,打印日志也设置成功了,但是不知道为啥就是不在播控中心展示
开发者您好,按播控中心接入流程,当前播控中心的显示规则为:
-
创建会话类型为“audio”或“video”的AVSession,设置媒体信息,注册至少一个回调,会在播控中心展示媒体信息。
-
创建会话类型为“voice_call”或“video_call”的AVSession,应用上架的一级分类必须是应用(13),二级分类必须是商务(10000001)或社交(10000016)https://developer.huawei.com/consumer/cn/doc/app/agc-help-connect-api-appendix-apptype-0000002271160689,且处于响铃或通话状态,会在播控中心展示通话卡片。
-
创建会话类型为“photo”的AVSession,播控中心不展示。
更多关于HarmonyOS 鸿蒙Next中播控中心未显示当前播放的音频的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
播控中心不展示,99% 不是 AVPlayer 的问题,而是 AVSession 没有处在“系统认为可展示的激活播放态”。你虽然 setAVMetadata 成功了,但只要下面任意一条没满足,播控中心就可能不出卡片/不显示音频信息。
必查点(按优先级)
1)session.activate() 调用时机不对 / 没激活成功
官方接入流程里强调:元数据、控制命令注册完成之后再 activate,否则可能被系统判定为无效会话或展示不完整。 正确顺序应是:
- create session
- setAVMetadata
- 注册控制命令回调(play/pause/next/prev/seek 等,至少要有 play/pause)
await session.activate()- 播放开始后持续上报播放状态(state/position/speed 等)
(流程见“应用接入AVSession场景介绍”) Sources: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/avsession-access-scene
2)你只设置了元数据,但 没有上报播放状态 / 或 state 不为 PLAY
播控中心是否展示,很依赖 setAVPlaybackState 里的状态。例如你元数据设置了,但一直上报的是 Pause/Stop,或根本没上报 position,系统可能不展示。
最低要求建议你在开始播放后做一次:
state = PLAYBACK_STATE_PLAYposition = 当前播放进度(ms)speed = 1.0
并且播放过程中建议定时更新 position(比如 500ms~1000ms 一次)。
3)AVSession 实例被释放(最常见“日志成功但界面没东西”)
如果你在某个函数里 let session = await createAVSession(...),后面没有被成员变量/单例持有,页面切换或 GC 后 session 可能被释放,播控中心就不会显示。
做法:把 session 放到 Ability 级单例或页面的成员字段里,确保播放期间一直存在。
4)没有注册控制命令(至少 play/pause)
播控中心的卡片本质是“可控的媒体会话”。如果你只上报 metadata,但 没有注册播控回调,有些版本会不展示或展示异常。
建议至少注册:
on('play')on('pause')(如果你想要进度条可拖动再加on('seek'))
一个最小正确骨架(你对照改)
import { avSession as AVSessionManager } from '@kit.AVSessionKit';
class PlayerSessionHolder {
session?: AVSessionManager.AVSession
async init(ctx: Context, durationMs: number) {
this.session = await AVSessionManager.createAVSession(ctx, 'MY_AUDIO_SESSION', 'audio');
await this.session.setAVMetadata({
assetId: 'local_mp3_001',
title: '本地歌曲',
artist: '未知',
duration: durationMs,
});
// 至少注册 play/pause
this.session.on('play', () => { /* player.play() */ });
this.session.on('pause', () => { /* player.pause() */ });
await this.session.activate(); // 注意:放在 metadata + on(...) 之后
// 播放开始后上报播放态
await this.session.setAVPlaybackState({
state: AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY,
position: 0,
speed: 1.0,
});
}
async updatePosition(posMs: number) {
if (!this.session) return
await this.session.setAVPlaybackState({
state: AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY,
position: posMs,
speed: 1.0,
});
}
}
你发我两段信息,我可以直接帮你定位是哪一条没满足
- 你创建/激活 session 的代码片段(是否把 session 保存成成员变量?activate 放在哪里?)
- 你有没有调用
setAVPlaybackState,以及你上报的 state/position/duration 分别是多少(日志即可)
Sources:
这通可能因为AVSession的接入流程不完整所致。根据相关开发指南,要实现播控中心正常显示和控制,除了设置元数据,还必须完成以下几个关键步骤:
- 注册控制命令:即使元数据设置成功,如果未注册任何控制命令(如
play、pause),系统会认为你的应用不需要交互,从而不会在播控中心显示会话。你必须在创建AVSession后,立即为其注册命令监听器。 - 激活AVSession:创建AVSession后,必须调用其
activate()方法,会话才会生效。 - 实时更新播放状态:播控中心上的播放/暂停按钮状态和进度信息,依赖于应用通过
setAVPlaybackState方法主动更新的AVPlaybackState。你需要在播放器的状态(如开始、暂停、跳转)发生变化时,及时调用此方法同步状态。 - 确保AVSession对象持久化:应用在后台播放期间,必须确保AVSession对象实例一直存在,避免将其置于局部变量中而被系统回收。
检查下是否已经为AVSession注册了on('play')和on('pause')等控制命令监听,播放器状态变化时调用了setAVPlaybackState。这两步是播控中心得以显示和交互的核心。
在鸿蒙Next中,播控中心未显示当前音频,通常因应用未正确创建并激活MediaSession。需在播放前调用MediaSession.create(context)并设置元数据(setMetadata),且调用setActive(true)。同时需确保Ability的onStart/onStop生命周期中回调播控会话。若上述均实现,检查应用是否注册了mediaSession权限。
您的问题可能是AVSession激活或元数据必要字段缺失导致。请检查:
- 创建AVSession后务必调用
session.activate()激活会话,否则系统不会获取。 - 元数据必须至少包含
AVMediaDescription.Builder中的KEY_TITLE,否则播控中心不予展示。示例:metaBuilder.setString(AVMediaDescription.KEY_TITLE, "歌名")。 - 确认会话类型为
AVSession.SESSION_TYPE_AUDIO。 - 设置元数据后,必须调用
session.setAVMetadata(metadata)并随后通过session.setAVPlaybackState(state)更新播放状态(如播放、暂停),即使不传完整状态对象也需提供一个含合法状态值的Builder构建。 - 若锁屏不显示,需在后台任务中保持AVSession前台服务属性(长时任务声明中关联session即可,无需额外代码)。
完成以上步骤后,播控中心应能正常展示当前音频信息。


