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&lt;void&gt; | Requests a continuous task.|
62e41f4b71Sopenharmony_ci| stopBackgroundRunning(context: Context): Promise&lt;void&gt; | 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