开发者技术支持 - 后台音频播放
        【摘要】 后台播放音频,目前已知支持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)