1e41f4b71Sopenharmony_ci# Continuous task (ArkTS) 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ci## Overview 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci### Introduction 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ciIf an application has a perceivable task that needs to run in an extended period of time in the background, it can request a continuous task to prevent itself from being suspended. Examples of continuous tasks include music playback and navigation in the background. 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ciAfter an application requests a continuous task, the system verifies whether the application is actually executing the continuous task. It also attaches a notification to the continuous task. If the user deletes the notification, the system automatically stops the task. 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ci### Use Cases 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ciThe table below lists the types of continuous tasks, which are used in various scenarios. You can select a task type suitable for your case based on the description. 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci**Table 1** Continuous task types 19e41f4b71Sopenharmony_ci| Name| Description| Item| Example Scenario| 20e41f4b71Sopenharmony_ci| -------- | -------- | -------- | -------- | 21e41f4b71Sopenharmony_ci| DATA_TRANSFER | Data transfer| dataTransfer | The browser downloads a large file in the background.| 22e41f4b71Sopenharmony_ci| AUDIO_PLAYBACK | Audio and video playback| audioPlayback | A music application plays music in the background.<br>It can be used in atomic services.| 23e41f4b71Sopenharmony_ci| AUDIO_RECORDING | Audio recording| audioRecording | A recorder records audio in the background.| 24e41f4b71Sopenharmony_ci| LOCATION | Positioning and navigation| location | A navigation application provides navigation in the background.| 25e41f4b71Sopenharmony_ci| BLUETOOTH_INTERACTION | Bluetooth-related task| bluetoothInteraction | Transfer a file through Bluetooth.| 26e41f4b71Sopenharmony_ci| MULTI_DEVICE_CONNECTION | Multi-device connection| multiDeviceConnection | Carry out distributed service connection.<br>It can be used in atomic services.| 27e41f4b71Sopenharmony_ci| <!--DelRow-->WIFI_INTERACTION | WLAN-related task (for system applications only)| wifiInteraction | Transfer a file over WLAN.| 28e41f4b71Sopenharmony_ci| VOIP<sup>13+</sup> | Audio and video calls| voip | Use a chat application to make an audio and video call in the background.| 29e41f4b71Sopenharmony_ci| TASK_KEEPING | <!--RP1-->Computing task (for specific devices only)<!--RP1End--> | taskKeeping | Run antivirus software.| 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_ci- If an application calls the [upload and download agent API](../reference/apis-basic-services-kit/js-apis-request.md) to delegate the upload and download task to the system, the application will be suspended regardless of whether it has requested such a continuous task. For a continuous task used for download, the application needs to update the download progress. If the progress is not updated for more than 10 minutes, the continuous task will be canceled. You are advised to use the [new API](../reference/apis-backgroundtasks-kit/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagerstartbackgroundrunning12) to request a continuous task of the DATA_TRANSFER type and update the notification progress. 32e41f4b71Sopenharmony_ci- Only audio and video applications that use [AVSession](../media/avsession/avsession-overview.md) can request a continuous task of the AUDIO_PLAYBACK type to implement background playback. 33e41f4b71Sopenharmony_ci 34e41f4b71Sopenharmony_ci### Constraints 35e41f4b71Sopenharmony_ci 36e41f4b71Sopenharmony_ci- **Ability restrictions**: In the stage model, only the UIAbility can request continuous tasks. In the FA model, only the ServiceAbility can request continuous tasks. 37e41f4b71Sopenharmony_ci 38e41f4b71Sopenharmony_ci- **Quantity restrictions**: A UIAbility (ServiceAbility in the FA model) can request only one continuous task at a time. If a UIAbility has a running continuous task, it can request another one only after the running task is finished. If an application needs to request multiple continuous tasks at the same time, it must create multiple UIAbilities. After a UIAbility requests a continuous task, all the processes of the application are not suspended. 39e41f4b71Sopenharmony_ci 40e41f4b71Sopenharmony_ci- **Running restrictions**: The system verifies continuous tasks on mobile phones. 41e41f4b71Sopenharmony_ci - Scenario 1: If an application requests a continuous task but does not execute or has finished the task of the requested type, the system performs certain control. For example, if the system detects that an application has requested a continuous task of the AUDIO_PLAYBACK type but does not play audio, the system cancels the continuous task. 42e41f4b71Sopenharmony_ci - Scenario 2: If an application does not request a continuous task of a given type but executes such a continuous task, the system performs certain control. For example, if the system detects that an application requests a continuous task of the AUDIO_PLAYBACK type, but the application is playing audio (corresponding to the AUDIO_PLAYBACK type) and recording (corresponding to the AUDIO_RECORDING type), the system performs control on the application. 43e41f4b71Sopenharmony_ci - Scenario 3: If the background load of the process that runs a continuous task is higher than the corresponding typical load for a long period of time, the system performs certain control. 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ci> **NOTE** 46e41f4b71Sopenharmony_ci> 47e41f4b71Sopenharmony_ci> The application shall proactively cancel a continuous task when it is finished. Otherwise, the system will forcibly cancel the task. For example, when a user taps the UI to pause music playback, the application must cancel the continuous task in a timely manner. When the user taps the UI again to continue music playback, the application needs to request a continuous task. 48e41f4b71Sopenharmony_ci> 49e41f4b71Sopenharmony_ci> If an application that plays an audio in the background is [interrupted](../media/audio/audio-playback-concurrency.md), the system automatically detects and stops the continuous task. The application must request a continuous task again to restart the playback. 50e41f4b71Sopenharmony_ci> 51e41f4b71Sopenharmony_ci> When an application that plays audio stops a continuous task in the background, it must suspend or stop the audio stream. Otherwise, the application will be forcibly terminated by the system. 52e41f4b71Sopenharmony_ci 53e41f4b71Sopenharmony_ci## Available APIs 54e41f4b71Sopenharmony_ci 55e41f4b71Sopenharmony_ciThe table below uses promise as an example to describe the APIs used for developing continuous tasks. For details about more APIs and their usage, see [Background Task Management](../reference/apis-backgroundtasks-kit/js-apis-resourceschedule-backgroundTaskManager.md). 56e41f4b71Sopenharmony_ci 57e41f4b71Sopenharmony_ci**Table 2** Main APIs for continuous tasks 58e41f4b71Sopenharmony_ci 59e41f4b71Sopenharmony_ci| API| Description| 60e41f4b71Sopenharmony_ci| -------- | -------- | 61e41f4b71Sopenharmony_ci| startBackgroundRunning(context: Context, bgMode: BackgroundMode, wantAgent: [WantAgent](../reference/apis-ability-kit/js-apis-app-ability-wantAgent.md)): Promise<void> | Requests a continuous task.| 62e41f4b71Sopenharmony_ci| stopBackgroundRunning(context: Context): Promise<void> | Cancels a continuous task.| 63e41f4b71Sopenharmony_ci 64e41f4b71Sopenharmony_ci## How to Develop 65e41f4b71Sopenharmony_ci 66e41f4b71Sopenharmony_ciThe following walks you through how to request a continuous task for recording. In this example, the application provides two buttons: **Request Continuous Task** and **Cancel Continuous Task**. 67e41f4b71Sopenharmony_ci- When a user touches **Request Continuous Task**, the application requests a continuous task for recording, and a message is displayed in the notification bar, indicating that a recording task is running. 68e41f4b71Sopenharmony_ci- When a user touches **Cancel Continuous Task**, the application cancels the continuous task, and the notification message is removed. 69e41f4b71Sopenharmony_ci 70e41f4b71Sopenharmony_ci### Stage Model 71e41f4b71Sopenharmony_ci 72e41f4b71Sopenharmony_ci1. Declare the **ohos.permission.KEEP_BACKGROUND_RUNNING** permission. For details, see [Declaring Permissions](../security/AccessToken/declare-permissions.md). 73e41f4b71Sopenharmony_ci 74e41f4b71Sopenharmony_ci2. Declare the background mode and add configurations such as **uris**. 75e41f4b71Sopenharmony_ci - (Mandatory) Declare the background mode. Specifically, declare the type of the continuous task for the target UIAbility in the **module.json5** file. (Set the corresponding configuration item in the configuration file.) 76e41f4b71Sopenharmony_ci - (Optional) Add configurations such as **uris**. If redirection features such as deep linking and app linking are used, refer to the sample code below. The mandatory parameters cannot be modified. For details about the optional parameters, see [Overview of Application Redirection](../application-models/link-between-apps-overview.md). 77e41f4b71Sopenharmony_ci 78e41f4b71Sopenharmony_ci ```json 79e41f4b71Sopenharmony_ci "module": { 80e41f4b71Sopenharmony_ci "abilities": [ 81e41f4b71Sopenharmony_ci { 82e41f4b71Sopenharmony_ci "backgroundModes": [ 83e41f4b71Sopenharmony_ci // Configuration item of the continuous task type 84e41f4b71Sopenharmony_ci "audioRecording" 85e41f4b71Sopenharmony_ci ], 86e41f4b71Sopenharmony_ci "skills": [ 87e41f4b71Sopenharmony_ci // Mandatory: entities and actions values for the request for a continuous task. 88e41f4b71Sopenharmony_ci { 89e41f4b71Sopenharmony_ci "entities": [ 90e41f4b71Sopenharmony_ci "entity.system.home" 91e41f4b71Sopenharmony_ci ], 92e41f4b71Sopenharmony_ci "actions": [ 93e41f4b71Sopenharmony_ci "action.system.home" 94e41f4b71Sopenharmony_ci ] 95e41f4b71Sopenharmony_ci }, 96e41f4b71Sopenharmony_ci // Optional: required for redirection features such as deep linking and app linking. 97e41f4b71Sopenharmony_ci { 98e41f4b71Sopenharmony_ci "entities": [ 99e41f4b71Sopenharmony_ci "test" 100e41f4b71Sopenharmony_ci ], 101e41f4b71Sopenharmony_ci "actions": [ 102e41f4b71Sopenharmony_ci "test" 103e41f4b71Sopenharmony_ci ], 104e41f4b71Sopenharmony_ci "uris": [ 105e41f4b71Sopenharmony_ci { 106e41f4b71Sopenharmony_ci "scheme": "test" 107e41f4b71Sopenharmony_ci } 108e41f4b71Sopenharmony_ci ] 109e41f4b71Sopenharmony_ci } 110e41f4b71Sopenharmony_ci ] 111e41f4b71Sopenharmony_ci } 112e41f4b71Sopenharmony_ci ], 113e41f4b71Sopenharmony_ci ... 114e41f4b71Sopenharmony_ci } 115e41f4b71Sopenharmony_ci ``` 116e41f4b71Sopenharmony_ci 117e41f4b71Sopenharmony_ci3. Import the modules. 118e41f4b71Sopenharmony_ci 119e41f4b71Sopenharmony_ci Import the modules related to continuous tasks: @ohos.resourceschedule.backgroundTaskManager and @ohos.app.ability.wantAgent. Import other modules based on the project requirements. 120e41f4b71Sopenharmony_ci 121e41f4b71Sopenharmony_ci ```ts 122e41f4b71Sopenharmony_ci import { backgroundTaskManager } from '@kit.BackgroundTasksKit'; 123e41f4b71Sopenharmony_ci import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 124e41f4b71Sopenharmony_ci import { window } from '@kit.ArkUI'; 125e41f4b71Sopenharmony_ci import { rpc } from '@kit.IPCKit' 126e41f4b71Sopenharmony_ci import { BusinessError } from '@kit.BasicServicesKit'; 127e41f4b71Sopenharmony_ci import { wantAgent, WantAgent } from '@kit.AbilityKit'; 128e41f4b71Sopenharmony_ci ``` 129e41f4b71Sopenharmony_ci 130e41f4b71Sopenharmony_ci4. Request and cancel a continuous task. 131e41f4b71Sopenharmony_ci 132e41f4b71Sopenharmony_ci - In the stage model, an application can request a continuous task for itself or another application either on the local device or on a remote device.<!--RP2--><!--RP2End--> 133e41f4b71Sopenharmony_ci <!--Del--> 134e41f4b71Sopenharmony_ci - When a continuous task is executed across devices or applications in the background, the UIAbility can be created and run in the background in call mode. For details, see [Using Call to Implement UIAbility Interaction (for System Applications Only)](../application-models/uiability-intra-device-interaction.md#using-call-to-implement-uiability-interaction-for-system-applications-only) and [Using Cross-Device Call](../application-models/hop-multi-device-collaboration.md#using-cross-device-call).<!--DelEnd--> 135e41f4b71Sopenharmony_ci 136e41f4b71Sopenharmony_ci The code snippet below shows how an application requests a continuous task for itself. 137e41f4b71Sopenharmony_ci 138e41f4b71Sopenharmony_ci ```ts 139e41f4b71Sopenharmony_ci @Entry 140e41f4b71Sopenharmony_ci @Component 141e41f4b71Sopenharmony_ci struct Index { 142e41f4b71Sopenharmony_ci @State message: string = 'ContinuousTask'; 143e41f4b71Sopenharmony_ci // Use getContext to obtain the context of the UIAbility for the page. 144e41f4b71Sopenharmony_ci private context: Context = getContext(this); 145e41f4b71Sopenharmony_ci 146e41f4b71Sopenharmony_ci startContinuousTask() { 147e41f4b71Sopenharmony_ci let wantAgentInfo: wantAgent.WantAgentInfo = { 148e41f4b71Sopenharmony_ci // List of operations to be executed after the notification is clicked. 149e41f4b71Sopenharmony_ci // Add the bundleName and abilityName of the application to start. 150e41f4b71Sopenharmony_ci wants: [ 151e41f4b71Sopenharmony_ci { 152e41f4b71Sopenharmony_ci bundleName: "com.example.myapplication", 153e41f4b71Sopenharmony_ci abilityName: "com.example.myapplication.MainAbility" 154e41f4b71Sopenharmony_ci } 155e41f4b71Sopenharmony_ci ], 156e41f4b71Sopenharmony_ci // Specify the action to perform (starting the ability) after the notification message is clicked. 157e41f4b71Sopenharmony_ci actionType: wantAgent.OperationType.START_ABILITY, 158e41f4b71Sopenharmony_ci // Custom request code. 159e41f4b71Sopenharmony_ci requestCode: 0, 160e41f4b71Sopenharmony_ci // Execution attribute of the operation to perform after the notification is clicked. 161e41f4b71Sopenharmony_ci actionFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] 162e41f4b71Sopenharmony_ci }; 163e41f4b71Sopenharmony_ci 164e41f4b71Sopenharmony_ci // Obtain the WantAgent object by using the getWantAgent API of the wantAgent module. 165e41f4b71Sopenharmony_ci wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj: WantAgent) => { 166e41f4b71Sopenharmony_ci backgroundTaskManager.startBackgroundRunning(this.context, 167e41f4b71Sopenharmony_ci backgroundTaskManager.BackgroundMode.AUDIO_RECORDING, wantAgentObj).then(() => { 168e41f4b71Sopenharmony_ci // Execute the continuous task logic, for example, music playback. 169e41f4b71Sopenharmony_ci console.info(`Succeeded in operationing startBackgroundRunning.`); 170e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 171e41f4b71Sopenharmony_ci console.error(`Failed to operation startBackgroundRunning. Code is ${err.code}, message is ${err.message}`); 172e41f4b71Sopenharmony_ci }); 173e41f4b71Sopenharmony_ci }); 174e41f4b71Sopenharmony_ci } 175e41f4b71Sopenharmony_ci 176e41f4b71Sopenharmony_ci stopContinuousTask() { 177e41f4b71Sopenharmony_ci backgroundTaskManager.stopBackgroundRunning(this.context).then(() => { 178e41f4b71Sopenharmony_ci console.info(`Succeeded in operationing stopBackgroundRunning.`); 179e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 180e41f4b71Sopenharmony_ci console.error(`Failed to operation stopBackgroundRunning. Code is ${err.code}, message is ${err.message}`); 181e41f4b71Sopenharmony_ci }); 182e41f4b71Sopenharmony_ci } 183e41f4b71Sopenharmony_ci 184e41f4b71Sopenharmony_ci build() { 185e41f4b71Sopenharmony_ci Row() { 186e41f4b71Sopenharmony_ci Column() { 187e41f4b71Sopenharmony_ci Text("Index") 188e41f4b71Sopenharmony_ci .fontSize(50) 189e41f4b71Sopenharmony_ci .fontWeight(FontWeight.Bold) 190e41f4b71Sopenharmony_ci 191e41f4b71Sopenharmony_ci Button() { 192e41f4b71Sopenharmony_ci Text('Request continuous task').fontSize(25).fontWeight(FontWeight.Bold) 193e41f4b71Sopenharmony_ci } 194e41f4b71Sopenharmony_ci .type(ButtonType.Capsule) 195e41f4b71Sopenharmony_ci .margin({ top: 10 }) 196e41f4b71Sopenharmony_ci .backgroundColor('#0D9FFB') 197e41f4b71Sopenharmony_ci .width(250) 198e41f4b71Sopenharmony_ci .height(40) 199e41f4b71Sopenharmony_ci .onClick(() => { 200e41f4b71Sopenharmony_ci // Request a continuous task by clicking a button. 201e41f4b71Sopenharmony_ci this.startContinuousTask(); 202e41f4b71Sopenharmony_ci }) 203e41f4b71Sopenharmony_ci 204e41f4b71Sopenharmony_ci Button() { 205e41f4b71Sopenharmony_ci Text ('Cancel continuous task').fontSize (25).fontWeight (FontWeight.Bold) 206e41f4b71Sopenharmony_ci } 207e41f4b71Sopenharmony_ci .type(ButtonType.Capsule) 208e41f4b71Sopenharmony_ci .margin({ top: 10 }) 209e41f4b71Sopenharmony_ci .backgroundColor('#0D9FFB') 210e41f4b71Sopenharmony_ci .width(250) 211e41f4b71Sopenharmony_ci .height(40) 212e41f4b71Sopenharmony_ci .onClick(() => { 213e41f4b71Sopenharmony_ci // Stop the continuous task. 214e41f4b71Sopenharmony_ci 215e41f4b71Sopenharmony_ci // Cancel the continuous task by clicking a button. 216e41f4b71Sopenharmony_ci this.stopContinuousTask(); 217e41f4b71Sopenharmony_ci }) 218e41f4b71Sopenharmony_ci } 219e41f4b71Sopenharmony_ci .width('100%') 220e41f4b71Sopenharmony_ci } 221e41f4b71Sopenharmony_ci .height('100%') 222e41f4b71Sopenharmony_ci } 223e41f4b71Sopenharmony_ci } 224e41f4b71Sopenharmony_ci ``` 225e41f4b71Sopenharmony_ci <!--Del--> 226e41f4b71Sopenharmony_ci 227e41f4b71Sopenharmony_ci The code snippet below shows how an application requests a continuous task across devices or applications. 228e41f4b71Sopenharmony_ci 229e41f4b71Sopenharmony_ci ```ts 230e41f4b71Sopenharmony_ci const MSG_SEND_METHOD: string = 'CallSendMsg' 231e41f4b71Sopenharmony_ci 232e41f4b71Sopenharmony_ci let mContext: Context; 233e41f4b71Sopenharmony_ci 234e41f4b71Sopenharmony_ci function startContinuousTask() { 235e41f4b71Sopenharmony_ci let wantAgentInfo : wantAgent.WantAgentInfo = { 236e41f4b71Sopenharmony_ci // List of operations to be executed after the notification is clicked. 237e41f4b71Sopenharmony_ci wants: [ 238e41f4b71Sopenharmony_ci { 239e41f4b71Sopenharmony_ci bundleName: "com.example.myapplication", 240e41f4b71Sopenharmony_ci abilityName: "com.example.myapplication.MainAbility", 241e41f4b71Sopenharmony_ci } 242e41f4b71Sopenharmony_ci ], 243e41f4b71Sopenharmony_ci // Type of the operation to perform after the notification is clicked. 244e41f4b71Sopenharmony_ci actionType: wantAgent.OperationType.START_ABILITY, 245e41f4b71Sopenharmony_ci // Custom request code. 246e41f4b71Sopenharmony_ci requestCode: 0, 247e41f4b71Sopenharmony_ci // Execution attribute of the operation to perform after the notification is clicked. 248e41f4b71Sopenharmony_ci actionFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] 249e41f4b71Sopenharmony_ci }; 250e41f4b71Sopenharmony_ci 251e41f4b71Sopenharmony_ci // Obtain the WantAgent object by using the getWantAgent API of the wantAgent module. 252e41f4b71Sopenharmony_ci wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj : WantAgent) => { 253e41f4b71Sopenharmony_ci backgroundTaskManager.startBackgroundRunning(mContext, 254e41f4b71Sopenharmony_ci backgroundTaskManager.BackgroundMode.AUDIO_RECORDING, wantAgentObj).then(() => { 255e41f4b71Sopenharmony_ci console.info(`Succeeded in operationing startBackgroundRunning.`); 256e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 257e41f4b71Sopenharmony_ci console.error(`Failed to operation startBackgroundRunning. Code is ${err.code}, message is ${err.message}`); 258e41f4b71Sopenharmony_ci }); 259e41f4b71Sopenharmony_ci }); 260e41f4b71Sopenharmony_ci } 261e41f4b71Sopenharmony_ci 262e41f4b71Sopenharmony_ci function stopContinuousTask() { 263e41f4b71Sopenharmony_ci backgroundTaskManager.stopBackgroundRunning(mContext).then(() => { 264e41f4b71Sopenharmony_ci console.info(`Succeeded in operationing stopBackgroundRunning.`); 265e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 266e41f4b71Sopenharmony_ci console.error(`Failed to operation stopBackgroundRunning. Code is ${err.code}, message is ${err.message}`); 267e41f4b71Sopenharmony_ci }); 268e41f4b71Sopenharmony_ci } 269e41f4b71Sopenharmony_ci 270e41f4b71Sopenharmony_ci class MyParcelable implements rpc.Parcelable { 271e41f4b71Sopenharmony_ci num: number = 0; 272e41f4b71Sopenharmony_ci str: string = ''; 273e41f4b71Sopenharmony_ci 274e41f4b71Sopenharmony_ci constructor(num: number, string: string) { 275e41f4b71Sopenharmony_ci this.num = num; 276e41f4b71Sopenharmony_ci this.str = string; 277e41f4b71Sopenharmony_ci } 278e41f4b71Sopenharmony_ci 279e41f4b71Sopenharmony_ci marshalling(messageSequence: rpc.MessageSequence) { 280e41f4b71Sopenharmony_ci messageSequence.writeInt(this.num); 281e41f4b71Sopenharmony_ci messageSequence.writeString(this.str); 282e41f4b71Sopenharmony_ci return true; 283e41f4b71Sopenharmony_ci } 284e41f4b71Sopenharmony_ci 285e41f4b71Sopenharmony_ci unmarshalling(messageSequence: rpc.MessageSequence) { 286e41f4b71Sopenharmony_ci this.num = messageSequence.readInt(); 287e41f4b71Sopenharmony_ci this.str = messageSequence.readString(); 288e41f4b71Sopenharmony_ci return true; 289e41f4b71Sopenharmony_ci } 290e41f4b71Sopenharmony_ci } 291e41f4b71Sopenharmony_ci 292e41f4b71Sopenharmony_ci function sendMsgCallback(data: rpc.MessageSequence) { 293e41f4b71Sopenharmony_ci console.info('BgTaskAbility funcCallBack is called ' + data); 294e41f4b71Sopenharmony_ci let receivedData: MyParcelable = new MyParcelable(0, ''); 295e41f4b71Sopenharmony_ci data.readParcelable(receivedData); 296e41f4b71Sopenharmony_ci console.info(`receiveData[${receivedData.num}, ${receivedData.str}]`); 297e41f4b71Sopenharmony_ci // You can execute different methods based on the str value in the sequenceable data sent by the caller object. 298e41f4b71Sopenharmony_ci if (receivedData.str === 'start_bgtask') { 299e41f4b71Sopenharmony_ci // Request a continuous task. 300e41f4b71Sopenharmony_ci startContinuousTask(); 301e41f4b71Sopenharmony_ci } else if (receivedData.str === 'stop_bgtask') { 302e41f4b71Sopenharmony_ci // Cancel the continuous task. 303e41f4b71Sopenharmony_ci stopContinuousTask(); 304e41f4b71Sopenharmony_ci } 305e41f4b71Sopenharmony_ci return new MyParcelable(10, 'Callee test'); 306e41f4b71Sopenharmony_ci } 307e41f4b71Sopenharmony_ci 308e41f4b71Sopenharmony_ci export default class BgTaskAbility extends UIAbility { 309e41f4b71Sopenharmony_ci // Create an ability. 310e41f4b71Sopenharmony_ci onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { 311e41f4b71Sopenharmony_ci console.info("[Demo] BgTaskAbility onCreate"); 312e41f4b71Sopenharmony_ci try { 313e41f4b71Sopenharmony_ci this.callee.on(MSG_SEND_METHOD, sendMsgCallback) 314e41f4b71Sopenharmony_ci } catch (error) { 315e41f4b71Sopenharmony_ci console.error(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`); 316e41f4b71Sopenharmony_ci } 317e41f4b71Sopenharmony_ci mContext = this.context; 318e41f4b71Sopenharmony_ci } 319e41f4b71Sopenharmony_ci 320e41f4b71Sopenharmony_ci // Destroy an ability. 321e41f4b71Sopenharmony_ci onDestroy() { 322e41f4b71Sopenharmony_ci console.info('[Demo] BgTaskAbility onDestroy'); 323e41f4b71Sopenharmony_ci } 324e41f4b71Sopenharmony_ci 325e41f4b71Sopenharmony_ci onWindowStageCreate(windowStage: window.WindowStage) { 326e41f4b71Sopenharmony_ci console.info('[Demo] BgTaskAbility onWindowStageCreate'); 327e41f4b71Sopenharmony_ci 328e41f4b71Sopenharmony_ci windowStage.loadContent('pages/Index', (error, data) => { 329e41f4b71Sopenharmony_ci if (error.code) { 330e41f4b71Sopenharmony_ci console.error(`load content failed with error ${JSON.stringify(error)}`); 331e41f4b71Sopenharmony_ci return; 332e41f4b71Sopenharmony_ci } 333e41f4b71Sopenharmony_ci console.info(`load content succeed with data ${JSON.stringify(data)}`); 334e41f4b71Sopenharmony_ci }); 335e41f4b71Sopenharmony_ci } 336e41f4b71Sopenharmony_ci 337e41f4b71Sopenharmony_ci onWindowStageDestroy() { 338e41f4b71Sopenharmony_ci console.info('[Demo] BgTaskAbility onWindowStageDestroy'); 339e41f4b71Sopenharmony_ci } 340e41f4b71Sopenharmony_ci 341e41f4b71Sopenharmony_ci onForeground() { 342e41f4b71Sopenharmony_ci console.info('[Demo] BgTaskAbility onForeground'); 343e41f4b71Sopenharmony_ci } 344e41f4b71Sopenharmony_ci 345e41f4b71Sopenharmony_ci onBackground() { 346e41f4b71Sopenharmony_ci console.info('[Demo] BgTaskAbility onBackground'); 347e41f4b71Sopenharmony_ci } 348e41f4b71Sopenharmony_ci }; 349e41f4b71Sopenharmony_ci ``` 350e41f4b71Sopenharmony_ci 351e41f4b71Sopenharmony_ci <!--DelEnd--> 352e41f4b71Sopenharmony_ci 353e41f4b71Sopenharmony_ci<!--Del--> 354e41f4b71Sopenharmony_ci### FA Model 355e41f4b71Sopenharmony_ci 356e41f4b71Sopenharmony_ci1. Start and connect to a ServiceAbility. 357e41f4b71Sopenharmony_ci 358e41f4b71Sopenharmony_ci - If no user interaction is required, use **startAbility()** to start the ServiceAbility. For details, see [ServiceAbility Component](../application-models/serviceability-overview.md). In the **onStart** callback of the ServiceAbility, call the APIs to request and cancel continuous tasks. 359e41f4b71Sopenharmony_ci 360e41f4b71Sopenharmony_ci - If user interaction is required (for example, in music playback scenarios), use **connectAbility()** to start and connect to the ServiceAbility. For details, see [ServiceAbility Component](../application-models/serviceability-overview.md). After obtaining the agent of the ServiceAbility, the application can communicate with the ServiceAbility and control the request and cancellation of continuous tasks. 361e41f4b71Sopenharmony_ci 362e41f4b71Sopenharmony_ci2. Configure permissions and declare the continuous task type. 363e41f4b71Sopenharmony_ci 364e41f4b71Sopenharmony_ci Declare the **ohos.permission.KEEP_BACKGROUND_RUNNING** permission in the **config.json** file. For details, see [Declaring Permissions](../security/AccessToken/declare-permissions.md). In addition, declare the continuous task type for the ServiceAbility. 365e41f4b71Sopenharmony_ci 366e41f4b71Sopenharmony_ci ```json 367e41f4b71Sopenharmony_ci "module": { 368e41f4b71Sopenharmony_ci "package": "com.example.myapplication", 369e41f4b71Sopenharmony_ci "abilities": [ 370e41f4b71Sopenharmony_ci { 371e41f4b71Sopenharmony_ci "backgroundModes": [ 372e41f4b71Sopenharmony_ci "audioRecording", 373e41f4b71Sopenharmony_ci ], // Background mode 374e41f4b71Sopenharmony_ci "type": "service" // The ability type is Service. 375e41f4b71Sopenharmony_ci } 376e41f4b71Sopenharmony_ci ], 377e41f4b71Sopenharmony_ci "reqPermissions": [ 378e41f4b71Sopenharmony_ci { 379e41f4b71Sopenharmony_ci "name": "ohos.permission.KEEP_BACKGROUND_RUNNING" // Continuous task permission 380e41f4b71Sopenharmony_ci } 381e41f4b71Sopenharmony_ci ] 382e41f4b71Sopenharmony_ci } 383e41f4b71Sopenharmony_ci ``` 384e41f4b71Sopenharmony_ci 385e41f4b71Sopenharmony_ci3. Import the modules. 386e41f4b71Sopenharmony_ci 387e41f4b71Sopenharmony_ci ```js 388e41f4b71Sopenharmony_ci import { backgroundTaskManager } from '@kit.BackgroundTasksKit'; 389e41f4b71Sopenharmony_ci import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 390e41f4b71Sopenharmony_ci import { window } from '@kit.ArkUI'; 391e41f4b71Sopenharmony_ci import { rpc } from '@kit.IPCKit' 392e41f4b71Sopenharmony_ci import { BusinessError } from '@kit.BasicServicesKit'; 393e41f4b71Sopenharmony_ci import { wantAgent, WantAgent } from '@kit.AbilityKit'; 394e41f4b71Sopenharmony_ci ``` 395e41f4b71Sopenharmony_ci 396e41f4b71Sopenharmony_ci4. Request and cancel a continuous task. In the ServiceAbility, call [startBackgroundRunning](#available-apis) and [stopBackgroundRunning](#available-apis) to request and cancel a continuous task. Use JavaScript code to implement this scenario. 397e41f4b71Sopenharmony_ci 398e41f4b71Sopenharmony_ci ```js 399e41f4b71Sopenharmony_ci function startContinuousTask() { 400e41f4b71Sopenharmony_ci let wantAgentInfo: wantAgent.WantAgentInfo = { 401e41f4b71Sopenharmony_ci // List of operations to be executed after the notification is clicked. 402e41f4b71Sopenharmony_ci wants: [ 403e41f4b71Sopenharmony_ci { 404e41f4b71Sopenharmony_ci bundleName: "com.example.myapplication", 405e41f4b71Sopenharmony_ci abilityName: "com.example.myapplication.MainAbility" 406e41f4b71Sopenharmony_ci } 407e41f4b71Sopenharmony_ci ], 408e41f4b71Sopenharmony_ci // Type of the operation to perform after the notification is clicked. 409e41f4b71Sopenharmony_ci actionType: wantAgent.OperationType.START_ABILITY, 410e41f4b71Sopenharmony_ci // Custom request code. 411e41f4b71Sopenharmony_ci requestCode: 0, 412e41f4b71Sopenharmony_ci // Execution attribute of the operation to perform after the notification is clicked. 413e41f4b71Sopenharmony_ci actionFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] 414e41f4b71Sopenharmony_ci }; 415e41f4b71Sopenharmony_ci 416e41f4b71Sopenharmony_ci // Obtain the WantAgent object by using the getWantAgent API of the wantAgent module. 417e41f4b71Sopenharmony_ci wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj: WantAgent) => { 418e41f4b71Sopenharmony_ci backgroundTaskManager.startBackgroundRunning(featureAbility.getContext(), 419e41f4b71Sopenharmony_ci backgroundTaskManager.BackgroundMode.AUDIO_RECORDING, wantAgentObj).then(() => { 420e41f4b71Sopenharmony_ci console.info(`Succeeded in operationing startBackgroundRunning.`); 421e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 422e41f4b71Sopenharmony_ci console.error(`Failed to operation startBackgroundRunning. Code is ${err.code}, message is ${err.message}`); 423e41f4b71Sopenharmony_ci }); 424e41f4b71Sopenharmony_ci }); 425e41f4b71Sopenharmony_ci } 426e41f4b71Sopenharmony_ci 427e41f4b71Sopenharmony_ci function stopContinuousTask() { 428e41f4b71Sopenharmony_ci backgroundTaskManager.stopBackgroundRunning(featureAbility.getContext()).then(() => { 429e41f4b71Sopenharmony_ci console.info(`Succeeded in operationing stopBackgroundRunning.`); 430e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 431e41f4b71Sopenharmony_ci console.error(`Failed to operation stopBackgroundRunning. Code is ${err.code}, message is ${err.message}`); 432e41f4b71Sopenharmony_ci }); 433e41f4b71Sopenharmony_ci } 434e41f4b71Sopenharmony_ci 435e41f4b71Sopenharmony_ci async function processAsyncJobs() { 436e41f4b71Sopenharmony_ci // Execute the continuous task. 437e41f4b71Sopenharmony_ci 438e41f4b71Sopenharmony_ci // After the continuous task is complete, call the API to release resources. 439e41f4b71Sopenharmony_ci stopContinuousTask(); 440e41f4b71Sopenharmony_ci } 441e41f4b71Sopenharmony_ci 442e41f4b71Sopenharmony_ci let mMyStub: MyStub; 443e41f4b71Sopenharmony_ci 444e41f4b71Sopenharmony_ci // Start the service by calling connectAbility(). 445e41f4b71Sopenharmony_ci class MyStub extends rpc.RemoteObject { 446e41f4b71Sopenharmony_ci constructor(des: string) { 447e41f4b71Sopenharmony_ci super(des); 448e41f4b71Sopenharmony_ci } 449e41f4b71Sopenharmony_ci 450e41f4b71Sopenharmony_ci onRemoteRequest(code: number, data: rpc.MessageParcel, reply: rpc.MessageParcel, option: rpc.MessageOption) { 451e41f4b71Sopenharmony_ci console.log('ServiceAbility onRemoteRequest called'); 452e41f4b71Sopenharmony_ci // Custom request code. 453e41f4b71Sopenharmony_ci if (code === 1) { 454e41f4b71Sopenharmony_ci // Receive the request code for requesting a continuous task. 455e41f4b71Sopenharmony_ci startContinuousTask(); 456e41f4b71Sopenharmony_ci // Execute the continuous task. 457e41f4b71Sopenharmony_ci } else if (code === 2) { 458e41f4b71Sopenharmony_ci // Receive the request code for canceling the continuous task. 459e41f4b71Sopenharmony_ci stopContinuousTask(); 460e41f4b71Sopenharmony_ci } else { 461e41f4b71Sopenharmony_ci console.log('ServiceAbility unknown request code'); 462e41f4b71Sopenharmony_ci } 463e41f4b71Sopenharmony_ci return true; 464e41f4b71Sopenharmony_ci } 465e41f4b71Sopenharmony_ci } 466e41f4b71Sopenharmony_ci 467e41f4b71Sopenharmony_ci // Start the service by calling startAbility(). 468e41f4b71Sopenharmony_ci class ServiceAbility { 469e41f4b71Sopenharmony_ci onStart(want: Want) { 470e41f4b71Sopenharmony_ci console.info('ServiceAbility onStart'); 471e41f4b71Sopenharmony_ci mMyStub = new MyStub("ServiceAbility-test"); 472e41f4b71Sopenharmony_ci // Call the API to start the task. 473e41f4b71Sopenharmony_ci startContinuousTask(); 474e41f4b71Sopenharmony_ci processAsyncJobs(); 475e41f4b71Sopenharmony_ci } 476e41f4b71Sopenharmony_ci 477e41f4b71Sopenharmony_ci onStop() { 478e41f4b71Sopenharmony_ci console.info('ServiceAbility onStop'); 479e41f4b71Sopenharmony_ci } 480e41f4b71Sopenharmony_ci 481e41f4b71Sopenharmony_ci onConnect(want: Want) { 482e41f4b71Sopenharmony_ci console.info('ServiceAbility onConnect'); 483e41f4b71Sopenharmony_ci return mMyStub; 484e41f4b71Sopenharmony_ci } 485e41f4b71Sopenharmony_ci 486e41f4b71Sopenharmony_ci onReconnect(want: Want) { 487e41f4b71Sopenharmony_ci console.info('ServiceAbility onReconnect'); 488e41f4b71Sopenharmony_ci } 489e41f4b71Sopenharmony_ci 490e41f4b71Sopenharmony_ci onDisconnect() { 491e41f4b71Sopenharmony_ci console.info('ServiceAbility onDisconnect'); 492e41f4b71Sopenharmony_ci } 493e41f4b71Sopenharmony_ci 494e41f4b71Sopenharmony_ci onCommand(want: Want, startId: number) { 495e41f4b71Sopenharmony_ci console.info('ServiceAbility onCommand'); 496e41f4b71Sopenharmony_ci } 497e41f4b71Sopenharmony_ci } 498e41f4b71Sopenharmony_ci 499e41f4b71Sopenharmony_ci export default new ServiceAbility(); 500e41f4b71Sopenharmony_ci ``` 501e41f4b71Sopenharmony_ci<!--DelEnd--> 502e41f4b71Sopenharmony_ci 503