HarmonyOS 鸿蒙Next中Web组件使用音视频/拨打电话时可以申请长时任务吗

HarmonyOS 鸿蒙Next中Web组件使用音视频/拨打电话时可以申请长时任务吗 Web 组件加载 Html 后使用音视频/拨打电话时也可以申请长时任务吗,申请后会起作用吗

4 回复

支持,以web后台播放音频为例。

【解决方案】 系统为了省电和稳定,会强制终止H5的后台行为,Web组件要实现音频后台播放,必须通过“长时任务”向系统申请许可,否则用户一退到后台,音频就会停止播放。 实现步骤如下:

  • 需要module.json5中配置ohos.permission.KEEP_BACKGROUND_RUNNING权限。
{
  "module" : {
    // To do sth.
    "requestPermissions":[
      {
        "name": "ohos.permission.KEEP_BACKGROUND_RUNNING",
        "reason": "$string:reason",
        "usedScene": {
          "abilities": [
            "FormAbility"
          ],
          "when":"inuse"
        }
      }
    ]
  }
}
  • 声明后台模式类型。 在module.json5文件中为需要使用长时任务的UIAbility声明相应的长时任务类型,配置文件中填写长时任务类型的配置项。音频、视频在后台播放需配置为audioPlayback。
 "module": {
     "abilities": [
         {
             "backgroundModes": [
              // 长时任务类型的配置项
             "audioPlayback"
             ]
         }
     ],
     // To do sth.
 }
  • 如果应用本身没有后台播放业务,可以通过监听生命周期函数onBackground来判断应用是否已进入后台。 在EntryAblity.ets中的回调中获取前后台的状态,通过AppStorage将状态保存,然后在Web页面通过@Watch来监听变量的变化。
export default class EntryAbility extends UIAbility {
  onForeground(): void {
    // 切到前台,设置isForeGround值为true
    AppStorage.setOrCreate('isForeGround', true);
  }

  onBackground(): void {
    // 切到后台,设置isForeGround值为false
    AppStorage.setOrCreate('isForeGround', false)
  }
}
  • 在Web加载H5音频页面并创建长时任务。 注意:创建wantAgent.WantAgentInfo时添加需要被拉起应用的bundleName和abilityName。
import { webview } from '@kit.ArkWeb'
import { backgroundTaskManager } from '@kit.BackgroundTasksKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { wantAgent, WantAgent } from '@kit.AbilityKit';

@Entry
@Component
export struct WebAudioPage {
  // 通过getUIContext().getHostContext()方法,来获取page所在的UIAbility上下文
  private context: Context | undefined = this.getUIContext().getHostContext();
  controller: webview.WebviewController = new webview.WebviewController()
  // 启动长时任务的函数(独立函数,避免this指向错误)
  // 监听isForeGround的值
  [@Watch](/user/Watch)('network') @StorageLink('isForeGround') isForeGround: boolean = false;

  network() {
    // 切换到前台了,视频播放
    if (this.isForeGround) {
      this.stopContinuousTask()
    } else {
      // 切换到后台了,视频停止播放
      this.startContinuousTask()
    }
  }

  startContinuousTask() {
    // 指定任务类型为audioPlayback
    const taskTypes = ["audioPlayback"];
    // 指定要启动的Ability(EntryAbility)
    let wantAgentInfo: wantAgent.WantAgentInfo = {wants: [{
      bundleName: "com.example.xxx", // 替换为你的实际包名
      abilityName: "EntryAbility",
    }],
      actionType: wantAgent.OperationType.START_ABILITY,
      // 使用者自定义的一个私有值
      requestCode: 0,
      // 点击通知后,动作执行属性
      actionFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG],
    };

    try {
      wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj) => {
        backgroundTaskManager.startBackgroundRunning(this.context, taskTypes, wantAgentObj)
          .then((res: backgroundTaskManager.ContinuousTaskNotification) => {
            console.info('长时任务启动成功,音频将在后台持续播放');
          })
          .catch((error: BusinessError) => {
            console.error(`启动长时任务失败: code=${error.code}, message=${error.message}`);
          });
      }).catch((error: BusinessError) => {
        console.error('获取 WantAgent 失败:', error);
      });
    } catch (error) {
      console.error('异常:', error);
    }
  }

  stopContinuousTask() {
    backgroundTaskManager.stopBackgroundRunning(this.context).then(() => {
      console.info(`Succeeded in operationing stopBackgroundRunning.`);
    }).catch((err: BusinessError) => {
      console.error(`Failed to operation stopBackgroundRunning. Code is ${err.code}, message is ${err.message}`);
    });
  }

  build() {
    Column() {
      Web({
        src: $rawfile('audio.html'),
        controller: this.controller
      })
        .domStorageAccess(true)
    }
    .width('100%')
    .height('100%')
  }
}

audio.html代码如下:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
    <meta charset="UTF-8" />
    <title>音频播放测试</title>
</head>
<body>
<h2>点击播放音频</h2>
<audio id="myAudio" controls autoplay loop>
    <source src="audio.mp3" type="audio/mpeg">
</audio>
<script>
    // 防止自动播放被拦截,建议用户交互后播放
    document.getElementById('myAudio').addEventListener('click', function () {
      this.play().catch(e => console.error('播放被阻止:', e));
    });
</script>
</body>
</html>

【背景知识】 ArkWeb:用于在应用程序中显示Web页面内容。 长时任务:应用退至后台后,在后台需要长时间运行用户可感知的任务,如播放音乐、导航等。为防止应用进程被挂起,导致对应功能异常,可以申请长时任务,使应用在后台长时间运行。在长时任务中,支持同时申请多种类型的任务,也可以对任务类型进行更新。应用退至后台执行业务时,系统会做一致性校验,确保应用在执行相应的长时任务。 应用在申请长时任务成功后,通知栏会显示与长时任务相关联的消息,用户删除通知栏消息时,系统会自动停止长时任务。

更多关于HarmonyOS 鸿蒙Next中Web组件使用音视频/拨打电话时可以申请长时任务吗的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


我的意思是,web 组件加载 html 页面,在 html 里有相关任务,如果在 ArkTS 方面申请的话会不会被撤销请求,

在HarmonyOS鸿蒙Next中,Web组件使用音视频或拨打电话功能时,可以通过长时任务管理器申请长时任务。具体使用backgroundTaskManager模块,调用requestSuspendDelay方法申请延迟挂起,并在onTimeOut回调中执行保活逻辑。需在module.json5中声明ohos.permission.KEEP_BACKGROUND_RUNNING权限。

在HarmonyOS Next中,Web组件加载HTML后使用音视频或拨打电话功能时,可以申请长时任务(Long-Term Task)。通过调用backgroundTaskManager.requestSuspendDelay()方法申请延迟挂起,系统会确保任务在后台持续运行,避免因应用挂起导致音视频中断或通话断开。申请成功后,系统会授予延迟挂起权限,任务将按预期执行。需注意合理管理任务生命周期,及时释放资源。

回到顶部