ArkTS音乐播放器:后台播放与通知栏控制实现

ArkTS音乐播放器:后台播放与通知栏控制实现

【免费下载链接】harmonyos-tutorial HarmonyOS Tutorial. 《跟老卫学HarmonyOS开发》 【免费下载链接】harmonyos-tutorial 项目地址: https://gitcode.com/GitHub_Trending/ha/harmonyos-tutorial

你是否遇到过这样的困扰:手机音乐播放器切换到后台就停止播放?或者想听下一首歌还要重新打开应用?本文将带你基于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。

【免费下载链接】harmonyos-tutorial HarmonyOS Tutorial. 《跟老卫学HarmonyOS开发》 【免费下载链接】harmonyos-tutorial 项目地址: https://gitcode.com/GitHub_Trending/ha/harmonyos-tutorial

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值