ArkTS音乐播放器:后台播放与通知栏控制实现
你是否遇到过这样的困扰:手机音乐播放器切换到后台就停止播放?或者想听下一首歌还要重新打开应用?本文将带你基于HarmonyOS的ArkTS语言,实现一个支持后台播放和通知栏控制的音乐播放器,让音乐体验更加流畅便捷。读完本文后,你将掌握ArkTS中音频播放、后台任务管理和通知栏交互的核心技能。
项目结构与核心组件
本项目是一个功能完善的音乐播放器示例,位于项目的samples/ArkTSMusicPlayer目录下。该示例采用了模块化的架构设计,主要包含以下核心组件:
- 页面组件:位于
samples/ArkTSMusicPlayer/entry/src/main/ets/pages/Index.ets,是应用的主界面入口,负责UI布局和用户交互。 - 播放器组件:位于
samples/ArkTSMusicPlayer/entry/src/main/ets/components/Player.ets,实现音乐播放控制功能。 - 内容组件:位于
samples/ArkTSMusicPlayer/entry/src/main/ets/components/Content.ets,负责展示音乐列表和专辑封面。 - 常量定义:位于
samples/ArkTSMusicPlayer/entry/src/main/ets/common/constants/PlayerConstants.ets,定义播放器相关的常量。
播放器UI实现
播放器的UI界面主要由Index.ets文件实现,采用了Stack布局,分为头部、中部和底部三个部分:
@Entry
@Component
struct Index {
@State currentBreakpoint: string = BreakpointConstants.BREAKPOINT_SM;
build() {
Stack({ alignContent: Alignment.Top }) {
// 头部
Header({ currentBreakpoint: $currentBreakpoint })
// 中部
Content({ currentBreakpoint: $currentBreakpoint })
// 底部
Player({ currentBreakpoint: $currentBreakpoint })
}
.width(StyleConstants.FULL_WIDTH)
}
}
其中,底部的Player组件是音乐播放控制的核心,实现了播放/暂停、上一曲、下一曲等功能,并通过动画效果提升用户体验。
播放控制区域设计
Player.ets组件实现了播放器的控制界面,主要包括专辑封面、歌曲信息和控制按钮:
Row() {
Row() {
Image(this.songList[this.selectIndex]?.label)
.height($r('app.float.cover_height'))
.width($r('app.float.cover_width'))
.borderRadius($r('app.float.label_border_radius'))
.margin({ right: $r('app.float.cover_margin') })
.rotate({ angle: this.isPlay ? PlayerConstants.ROTATE : 0 })
.animation({
duration: PlayerConstants.ANIMATION_DURATION,
iterations: PlayerConstants.ITERATIONS,
curve: Curve.Linear
})
Column() {
Text(this.songList[this.selectIndex].title)
.fontColor($r('app.color.song_name'))
.fontSize(new BreakpointType({
sm: $r('app.float.song_title_sm'),
md: $r('app.float.song_title_md'),
lg: $r('app.float.song_title_lg')
}).getValue(this.currentBreakpoint))
Row() {
Image($r('app.media.ic_vip'))
.height($r('app.float.vip_icon_height'))
.width($r('app.float.vip_icon_width'))
.margin({ right: $r('app.float.vip_icon_margin') })
Text(this.songList[this.selectIndex].singer)
.fontColor($r('app.color.singer'))
.fontSize(new BreakpointType({
sm: $r('app.float.singer_title_sm'),
md: $r('app.float.singer_title_md'),
lg: $r('app.float.singer_title_lg')
}).getValue(this.currentBreakpoint))
.opacity($r('app.float.singer_opacity'))
}
}
.alignItems(HorizontalAlign.Start)
}
.layoutWeight(PlayerConstants.LAYOUT_WEIGHT_PLAYER_CONTROL)
Blank()
Row() {
Image($r('app.media.ic_previous'))
.height($r('app.float.control_icon_height'))
.width($r('app.float.control_icon_width'))
.margin({ right: $r('app.float.control_icon_margin') })
.displayPriority(PlayerConstants.DISPLAY_PRIORITY_TWO)
Image(this.isPlay ? $r('app.media.ic_play') : $r('app.media.ic_pause'))
.height($r('app.float.control_icon_height'))
.width($r('app.float.control_icon_width'))
.displayPriority(PlayerConstants.DISPLAY_PRIORITY_THREE)
Image($r('app.media.ic_next'))
.height($r('app.float.control_icon_height'))
.width($r('app.float.control_icon_width'))
.margin({
right: $r('app.float.control_icon_margin'),
left: $r('app.float.control_icon_margin')
})
.displayPriority(PlayerConstants.DISPLAY_PRIORITY_TWO)
Image($r('app.media.ic_music_list'))
.height($r('app.float.control_icon_height'))
.width($r('app.float.control_icon_width'))
.displayPriority(PlayerConstants.DISPLAY_PRIORITY_ONE)
}
}
专辑封面旋转动画
播放器实现了专辑封面的旋转动画效果,当音乐播放时,封面会持续旋转:
.rotate({ angle: this.isPlay ? PlayerConstants.ROTATE : 0 })
.animation({
duration: PlayerConstants.ANIMATION_DURATION,
iterations: PlayerConstants.ITERATIONS,
curve: Curve.Linear
})
其中,旋转角度、动画持续时间和重复次数等常量在PlayerConstants.ets中定义:
export class PlayerConstants {
static readonly ROTATE: number = 360;
static readonly ANIMATION_DURATION: number = 3000;
static readonly ITERATIONS: number = -1;
}
后台播放实现
要实现音乐的后台播放功能,需要使用HarmonyOS的后台任务管理能力。具体实现步骤如下:
1. 配置应用权限
在config.json文件中添加后台任务权限:
"reqPermissions": [
{
"name": "ohos.permission.KEEP_BACKGROUND_RUNNING"
}
]
2. 启动后台任务
在音乐播放时,调用后台任务管理API启动后台任务:
import backgroundTaskManager from '@ohos.backgroundTaskManager';
let wantAgent = null;
try {
let wantAgentInfo = {
wants: [
{
bundleName: "com.example.musicplayer",
abilityName: "com.example.musicplayer.MainAbility"
}
],
operationType: backgroundTaskManager.OperationType.START_ABILITY,
requestCode: 0
};
wantAgent = await backgroundTaskManager.getWantAgent(wantAgentInfo);
} catch (error) {
console.error("getWantAgent failed, error: " + JSON.stringify(error));
}
let delayRequest = {
delayTime: 10,
wantAgent: wantAgent
};
try {
backgroundTaskManager.startBackgroundRunning(this.context, backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK, delayRequest);
console.log("startBackgroundRunning success");
} catch (error) {
console.error("startBackgroundRunning failed, error: " + JSON.stringify(error));
}
通知栏控制实现
通知栏控制功能允许用户在不打开应用的情况下控制音乐播放,实现步骤如下:
1. 创建通知
使用NotificationManager创建音乐播放通知:
import notificationManager from '@ohos.notificationManager';
import wantAgent from '@ohos.app.ability.wantAgent';
let notificationId = 1;
let wantAgentObj = null;
// 创建WantAgent
async function createWantAgent(operationType, abilityName) {
let wantInfo = {
bundleName: "com.example.musicplayer",
abilityName: abilityName
};
let wantAgentInfo = {
wants: [wantInfo],
operationType: operationType,
requestCode: 0
};
return await wantAgent.getWantAgent(wantAgentInfo);
}
// 创建通知
async function createNotification() {
// 创建上一曲、播放/暂停、下一曲按钮的WantAgent
let prevAgent = await createWantAgent(wantAgent.OperationType.START_ABILITY, "PreviousAbility");
let playAgent = await createWantAgent(wantAgent.OperationType.START_ABILITY, "PlayAbility");
let nextAgent = await createWantAgent(wantAgent.OperationType.START_ABILITY, "NextAbility");
let notificationContent = {
contentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: "正在播放",
text: "歌曲名称 - 歌手名称",
additionalText: ""
}
};
let notificationActionButton1 = {
title: "上一曲",
wantAgent: prevAgent
};
let notificationActionButton2 = {
title: "播放",
wantAgent: playAgent
};
let notificationActionButton3 = {
title: "下一曲",
wantAgent: nextAgent
};
let notificationActions = {
buttons: [notificationActionButton1, notificationActionButton2, notificationActionButton3]
};
let notificationRequest = {
id: notificationId,
content: notificationContent,
actions: notificationActions,
classification: notificationManager.Classification.MUSIC,
isOngoing: true,
isCleared: false
};
try {
await notificationManager.publish(notificationRequest);
console.log("Notification published successfully");
} catch (err) {
console.error(`Failed to publish notification. Code: ${err.code}, message: ${err.message}`);
}
}
2. 处理通知按钮事件
在对应的Ability中处理通知按钮事件:
onWantReceived(want) {
let action = want.parameters.action;
switch (action) {
case "previous":
// 处理上一曲逻辑
break;
case "play_pause":
// 处理播放/暂停逻辑
break;
case "next":
// 处理下一曲逻辑
break;
default:
break;
}
}
ArkTS音乐播放器
总结
本文详细介绍了如何使用ArkTS实现一个支持后台播放和通知栏控制的音乐播放器。通过合理的UI布局和动画效果提升用户体验,同时利用HarmonyOS的后台任务管理和通知功能实现了更完善的音乐播放体验。
完整的代码示例可以在项目的samples/ArkTSMusicPlayer目录下找到,你可以根据自己的需求进行修改和扩展,实现更多个性化的功能。
希望本文对你理解ArkTS音乐播放器开发有所帮助,如果你有任何问题或建议,欢迎在项目的GitHub仓库提交issue或PR。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



