开发者技术支持 - 后台音频播放
【摘要】 后台播放音频,目前已知支持avPlayer和阿里云播放器
一、问题说明:
app切换到后台或者返回桌面时,音频停止播放!
二、原因分析:
音频播放没有配置后台长时任务!
三、解决思路:
为音频播放功能配置后台长时任务.
四、解决方案:
前言:
此文章是一篇针对音频后台播放功能解决方案
4.1、入口模块配置后台任务权限
此权限是系统开放权限,无需向用户申请,直接用即可
"requestPermissions": [
{
"name": "ohos.permission.KEEP_BACKGROUND_RUNNING",
//在所属模块的resource-base-element-string.json文件中配置即可
"reason": "$string:background_permission_reason",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "always"
}
}
]
4.2、在入口模块的module.json5文件中声明后台任务类型
"module": {
"abilities": [
{
"backgroundModes": [
// 长时任务类型的配置项
"audioPlayback"//后台播放音频类型
]
}
],
// ...
}
4.3、导入模块
import { backgroundTaskManager } from '@kit.BackgroundTasksKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { wantAgent, WantAgent } from '@kit.AbilityKit';
// 在元服务中,请删除WantAgent导入
4.4、创建会话
用于管理后续请求
//三个参数分别为:上下文、后台任务标签、后台任务类型
this.session = await avSession.createAVSession(getContext(), 'BackgroundPlaying', 'audio')
await this.session.activate()
4.5、配置wantAgentInfo参数并获取wantAgentObj对象
//配置wantAgentInfo参数
let wantAgentInfo: wantAgent.WantAgentInfo = {
// 点击通知后,将要执行的动作列表
// 添加需要被拉起应用的bundleName和abilityName
wants: [{
bundleName: "应用包名",//可在App.json5文件中查看,也可通过bundleManager获取
abilityName: "入口ability(EntryAbility)",
} as Want],
// 使用者自定义的一个私有值
requestCode: 100,
actionType: wantAgent.OperationType.START_ABILITY,//不加此参数,报错:提示输入参数无效
wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]//可加可不加
};
//获取wantAgentObj对象
let wantAgentObj = await wantAgent.getWantAgent(wantAgentInfo)
4.6、创建后台任务
await backgroundTaskManager.startBackgroundRunning(context, backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK,
wantAgentObj);
4.7、停止后台任务
backgroundTaskManager.stopBackgroundRunning(getContext()).then(() => {
console.info(`Succeeded in operationing stopBackgroundRunning.`);
}).catch((err: BusinessError) => {
console.error(`Failed to operation stopBackgroundRunning. Code is ${err.code}, message is ${err.message}`);
});
4.8、封装长时任务工具类
import { Want, wantAgent } from '@kit.AbilityKit';
import { avSession } from '@kit.AVSessionKit';
import { backgroundTaskManager } from '@kit.BackgroundTasksKit';
export class ContinuousTaskManager {
session?: avSession.AVSession;
private static _instance?: ContinuousTaskManager
public static getInstance() {
if (!ContinuousTaskManager._instance) {
ContinuousTaskManager._instance = new ContinuousTaskManager()
}
return ContinuousTaskManager._instance
}
async getSession() {
if (!this.session) {
this.session = await avSession.createAVSession(getContext(), 'BackgroundPlaying', 'audio')
}
return this.session;
}
// 申请长时任务
async startBackgroundRunning() {
try {
const context = getContext()
Logger.info(JSON.stringify(context))
if (this.session) {
// YAlert(`已存在长时任务:\n\r sessionId:${this.session.sessionId} \n\r sessionType:${this.session.sessionType} `)
return;
}
// 重点1: 提供音频后台约束能力,音频接入AVSession后,可以进行后台音频播放
const session = await this.getSession()
await session.activate()
let wantAgentInfo: wantAgent.WantAgentInfo = {
// 点击通知后,将要执行的动作列表
// 添加需要被拉起应用的bundleName和abilityName
wants: [{
bundleName: "应用包名",
abilityName: "入口ability(EntryAbility)",
} as Want],
// 使用者自定义的一个私有值
requestCode: 100,
actionType: wantAgent.OperationType.START_ABILITY, //不加此参数,报错:提示输入参数无效
// wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG]//加不加都行
};
let wantAgentObj = await wantAgent.getWantAgent(wantAgentInfo)
//方便断点调式
Logger.info('wantAgentObj:', JSON.stringify(wantAgentInfo))
// 重点2: 创建后台任务
await backgroundTaskManager.startBackgroundRunning(context, backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK,
wantAgentObj);
// YAlert('后台任务建立成功')
} catch (err) {
Logger.info('开启后台任务失败: ', JSON.stringify(err))
YAlertError('开启后台任务失败', err.code, err.message);
}
}
// 停止后台任务
async stopBackgroundRunning() {
backgroundTaskManager.stopBackgroundRunning(getContext())
// this.session?.deactivate()
//下方两行代码避免返回重进进入创建会话失败
this.session?.destroy()
this.session = undefined;
}
}
export function YAlertError(tip: string, code: number, message: string) {
AlertDialog.show({ message: `${tip} \n\r code:${code} \n\r message:${message}`, autoCancel: true })
}
export function YAlert(message: string) {
AlertDialog.show({ message: `${message}`, autoCancel: true })
}
4.9、使用方法
//在播放接口调用上方或者下方调用都可 例:
this.avPlayer?.play();
ContinuousTaskManager.getInstance.startBackgroundRunning();
//注意在aboutToDisappear或者停止播放(不是暂停)时停止会话,避免内存泄露
ContinuousTaskManager.getInstance.stopBackgroundRunning();
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)