提交 fa2340b8 编写于 作者: G Gloria

Update docs against 16246+16893++16836+16709+16805

Signed-off-by: wusongqing<wusongqing@huawei.com>
上级 3f7b26bf
...@@ -27,8 +27,7 @@ This section uses the operation of using a browser to open a website as an examp ...@@ -27,8 +27,7 @@ This section uses the operation of using a browser to open a website as an examp
"host": "www.test.com", "host": "www.test.com",
"port": "8080", "port": "8080",
// Prefix matching is used. // Prefix matching is used.
"pathStartWith": "query", "pathStartWith": "query"
"type": "text/*"
}, },
{ {
"scheme": "http", "scheme": "http",
...@@ -53,12 +52,11 @@ function implicitStartAbility() { ...@@ -53,12 +52,11 @@ function implicitStartAbility() {
let context = getContext(this) as common.UIAbilityContext; let context = getContext(this) as common.UIAbilityContext;
let wantInfo = { let wantInfo = {
// Uncomment the line below if you want to implicitly query data only in the specific bundle. // Uncomment the line below if you want to implicitly query data only in the specific bundle.
// bundleName: "com.example.myapplication", // bundleName: 'com.example.myapplication',
"action": "ohos.want.action.viewData", 'action': 'ohos.want.action.viewData',
// entities can be omitted. // entities can be omitted.
"entities": ["entity.system.browsable"], 'entities': ['entity.system.browsable'],
"uri": "https://www.test.com:8080/query/student", 'uri': 'https://www.test.com:8080/query/student'
"type": "text/plain"
} }
context.startAbility(wantInfo).then(() => { context.startAbility(wantInfo).then(() => {
// ... // ...
...@@ -75,6 +73,6 @@ The matching process is as follows: ...@@ -75,6 +73,6 @@ The matching process is as follows:
3. If **uri** in the passed **want** parameter is included in **uris** under **skills** of the ability to match, which is concatenated into https://www.test.com:8080/query* (where * is a wildcard), the matching is successful. 3. If **uri** in the passed **want** parameter is included in **uris** under **skills** of the ability to match, which is concatenated into https://www.test.com:8080/query* (where * is a wildcard), the matching is successful.
4. If **type** in the passed **want** parameter is specified and is included in **type** under **skills** of the ability to match, the matching is successful. 4. If **type** in the passed **want** parameter is specified and is included in **type** under **skills** of the ability to match, the matching is successful.
When there are multiple matching applications, a dialog box is displayed for you to select one of them. The following figure shows an example. If there are multiple matching applications, the system displays a dialog box for you to select one of them. The following figure shows an example.
![](figures/ability-startup-with-implicit-want1.png) ![](figures/ability-startup-with-implicit-want1.png)
\ No newline at end of file
...@@ -19,10 +19,10 @@ ...@@ -19,10 +19,10 @@
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility { export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
let uiAbilityContext = this.context; let uiAbilityContext = this.context;
// ... // ...
} }
} }
``` ```
...@@ -34,21 +34,21 @@ ...@@ -34,21 +34,21 @@
```ts ```ts
import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility'; import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility';
export default class MyService extends ServiceExtensionAbility { export default class MyService extends ServiceExtensionAbility {
onCreate(want) { onCreate(want) {
let serviceExtensionContext = this.context; let serviceExtensionContext = this.context;
// ... // ...
} }
} }
``` ```
- [AbilityStageContext](../reference/apis/js-apis-inner-application-abilityStageContext.md): module-level context. It provides **HapModuleInfo** and **Configuration** in addition to those provided by the base class **Context**. - [AbilityStageContext](../reference/apis/js-apis-inner-application-abilityStageContext.md): module-level context. It provides **HapModuleInfo** and **Configuration** in addition to those provided by the base class **Context**.
```ts ```ts
import AbilityStage from "@ohos.app.ability.AbilityStage"; import AbilityStage from '@ohos.app.ability.AbilityStage';
export default class MyAbilityStage extends AbilityStage { export default class MyAbilityStage extends AbilityStage {
onCreate() { onCreate() {
let abilityStageContext = this.context; let abilityStageContext = this.context;
// ... // ...
} }
} }
``` ```
- [ApplicationContext](../reference/apis/js-apis-inner-application-applicationContext.md): application-level context. It provides APIs for subscribing to application component lifecycle changes, system memory changes, and system environment changes. The application-level context can be obtained from UIAbility, ExtensionAbility, and AbilityStage. - [ApplicationContext](../reference/apis/js-apis-inner-application-applicationContext.md): application-level context. It provides APIs for subscribing to application component lifecycle changes, system memory changes, and system environment changes. The application-level context can be obtained from UIAbility, ExtensionAbility, and AbilityStage.
...@@ -56,10 +56,10 @@ ...@@ -56,10 +56,10 @@
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility { export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
let applicationContext = this.context.getApplicationContext(); let applicationContext = this.context.getApplicationContext();
// ... // ...
} }
} }
``` ```
...@@ -71,7 +71,7 @@ This topic describes how to use the context in the following scenarios: ...@@ -71,7 +71,7 @@ This topic describes how to use the context in the following scenarios:
- [Obtaining the Application Development Path](#obtaining-the-application-development-path) - [Obtaining the Application Development Path](#obtaining-the-application-development-path)
- [Obtaining and Modifying Encrypted Areas](#obtaining-and-modifying-encrypted-areas) - [Obtaining and Modifying Encryption Areas](#obtaining-and-modifying-encryption-areas)
- [Creating Context of Another Application or Module](#creating-context-of-another-application-or-module) - [Creating Context of Another Application or Module](#creating-context-of-another-application-or-module)
- [Subscribing to UIAbility Lifecycle Changes in a Process](#subscribing-to-uiability-lifecycle-changes-in-a-process) - [Subscribing to UIAbility Lifecycle Changes in a Process](#subscribing-to-uiability-lifecycle-changes-in-a-process)
...@@ -84,13 +84,13 @@ The following table describes the application development paths obtained from co ...@@ -84,13 +84,13 @@ The following table describes the application development paths obtained from co
| Name| Type| Readable| Writable| Description| | Name| Type| Readable| Writable| Description|
| -------- | -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- | -------- |
| cacheDir | string | Yes| No| Cache directory of the application on the internal storage.<br>It is the content of **Storage** of an application under **Settings > Apps & services > Apps**.| | bundleCodeDir | string | Yes | No | Path for storing the application's installation package, that is, installation directory of the application on the internal storage. |
| tempDir | string | Yes| No| Temporary file directory of the application.<br>Files in this directory are deleted after the application is uninstalled.| | cacheDir | string | Yes| No| Path for storing the application's cache files, that is, cache directory of the application on the internal storage.<br>It is the content of **Storage** of an application under **Settings > Apps & services > Apps**.|
| filesDir | string | Yes| No| File directory of the application on the internal storage.<br>Files in this directory may be synchronized to other directories during application migration or backup.| | filesDir | string | Yes | No | Path for storing the application's common files, that is, file directory of the application on the internal storage.<br>Files in this directory may be synchronized to other directories during application migration or backup.|
| databaseDir | string | Yes| No| Storage directory of the local database.| | preferencesDir | string | Yes | Yes | Path for storing the application's preference files, that is, preferences directory of the application. |
| bundleCodeDir | string | Yes| No| Installation directory of the application on the internal storage.| | tempDir | string | Yes | No | Path for storing the application's temporary files.<br>Files in this directory are deleted after the application is uninstalled.|
| distributedFilesDir | string | Yes| No| Storage directory of distributed application data files.| | databaseDir | string | Yes | No | Path for storing the application's database, that is, storage directory of the local database. |
| preferencesDir | string | Yes| Yes| Preferences directory of the application.| | distributedFilesDir | string | Yes| No| Path for storing the application's distributed files.|
The capability of obtaining the application development path is provided by the base class **Context**. This capability is also provided by **ApplicationContext**, **AbilityStageContext**, **UIAbilityContext**, and **ExtensionContext**. However, the paths obtained from different contexts may differ, as shown below. The capability of obtaining the application development path is provided by the base class **Context**. This capability is also provided by **ApplicationContext**, **AbilityStageContext**, **UIAbilityContext**, and **ExtensionContext**. However, the paths obtained from different contexts may differ, as shown below.
...@@ -127,16 +127,16 @@ The sample code for obtaining the application development paths is as follows: ...@@ -127,16 +127,16 @@ The sample code for obtaining the application development paths is as follows:
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility { export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
let cacheDir = this.context.cacheDir; let cacheDir = this.context.cacheDir;
let tempDir = this.context.tempDir; let tempDir = this.context.tempDir;
let filesDir = this.context.filesDir; let filesDir = this.context.filesDir;
let databaseDir = this.context.databaseDir; let databaseDir = this.context.databaseDir;
let bundleCodeDir = this.context.bundleCodeDir; let bundleCodeDir = this.context.bundleCodeDir;
let distributedFilesDir = this.context.distributedFilesDir; let distributedFilesDir = this.context.distributedFilesDir;
let preferencesDir = this.context.preferencesDir; let preferencesDir = this.context.preferencesDir;
// ... // ...
} }
} }
``` ```
...@@ -144,45 +144,52 @@ export default class EntryAbility extends UIAbility { ...@@ -144,45 +144,52 @@ export default class EntryAbility extends UIAbility {
> >
> The sample code obtains the sandbox path of the application development path. The absolute path can be obtained by running the **find / -name <fileName>** command in the hdc shell after file creation or modification. > The sample code obtains the sandbox path of the application development path. The absolute path can be obtained by running the **find / -name <fileName>** command in the hdc shell after file creation or modification.
### Obtaining and Modifying Encrypted Areas ### Obtaining and Modifying Encryption Areas
You can read and write [the area attribute in the context](../reference/apis/js-apis-inner-application-context.md) to obtain and set an encrypted area. Two encryption levels are supported: Encrypting application files enhances data security by preventing files from unauthorized access. Different application files require different levels of protection. For private files, such as alarms and wallpapers, the application must place them in the device-level encryption area (EL1) to ensure that they can be accessed before the user enters the password. For sensitive files, such as personal privacy data, the application must place them in the user-level encryption area (EL2).
- AreaMode.EL1: device-level encryption area, which is accessible after the device is powered on. In practice, you need to select a proper encrypted area based on scenario-specific requirements to protect application data security. The proper use of EL1 and the EL2 can efficiently improve the security.
- AreaMode.EL2: user-level encryption area, which is accessible only after the device is powered on and the password is entered (for the first time). > **NOTE**
>
> - AreaMode.EL1: device-level encryption area, which is accessible after the device is powered on.
>
> - AreaMode.EL2: user-level encryption area, which is accessible only after the device is powered on and the password is entered (for the first time).
You can obtain and set the encryption area by reading and writing the [area attribute in Context](../reference/apis/js-apis-inner-application-context.md).
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility { export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
// Before storing common information, switch the encryption level to EL1. // Before storing common information, switch the encryption level to EL1.
if (this.context.area === 1) {// Obtain the area. if (this.context.area === 1) {// Obtain the area.
this.context.area = 0; // Modify the area. this.context.area = 0; // Modify the area.
}
// Store common information.
// Before storing sensitive information, switch the encryption level to EL2.
if (this.context.area === 0) { // Obtain the area.
this.context.area = 1; // Modify the area.
}
// Store sensitive information.
} }
// Store common information.
// Before storing sensitive information, switch the encryption level to EL2.
if (this.context.area === 0) { // Obtain the area.
this.context.area = 1; // Modify the area.
}
// Store sensitive information.
}
} }
``` ```
### Creating Context of Another Application or Module ### Creating Context of Another Application or Module
The base class **Context** provides the [createBundleContext(bundleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatebundlecontext), [createModuleContext(moduleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatemodulecontext), and [createModuleContext(bundleName:string, moduleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatemodulecontext-1) methods for creating the context of other applications or modules, so as to obtain the resource information, for example, [obtaining the application development paths](#obtaining-the-application-development-path) of other modules. The base class **Context** provides [createBundleContext(bundleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatebundlecontext), [createModuleContext(moduleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatemodulecontext), and [createModuleContext(bundleName:string, moduleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatemodulecontext-1) to create the context of other applications or modules, so as to obtain the resource information, for example, [obtaining the application development paths](#obtaining-the-application-development-path) of other modules.
- Call **createBundleContext(bundleName:string)** to create the context of another application. - Call **createBundleContext(bundleName:string)** to create the context of another application.
> **NOTE** > **NOTE**
> >
> To obtain the context of another application: > To obtain the context of another application:
> >
> - Request the **ohos.permission.GET_BUNDLE_INFO_PRIVILEGED** permission. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). > - Request the **ohos.permission.GET_BUNDLE_INFO_PRIVILEGED** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
>
> - This is a system API and cannot be called by third-party applications. > - This is a system API and cannot be called by third-party applications.
For example, application information displayed on the home screen includes the application name and icon. The home screen application calls the foregoing method to obtain the context information, so as to obtain the resource information including the application name and icon. For example, application information displayed on the home screen includes the application name and icon. The home screen application calls the foregoing method to obtain the context information, so as to obtain the resource information including the application name and icon.
...@@ -191,12 +198,12 @@ The base class **Context** provides the [createBundleContext(bundleName:string)] ...@@ -191,12 +198,12 @@ The base class **Context** provides the [createBundleContext(bundleName:string)]
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility { export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
let bundleName2 = "com.example.application"; let bundleName2 = 'com.example.application';
let context2 = this.context.createBundleContext(bundleName2); let context2 = this.context.createBundleContext(bundleName2);
let label2 = context2.applicationInfo.label; let label2 = context2.applicationInfo.label;
// ... // ...
} }
} }
``` ```
...@@ -205,99 +212,113 @@ The base class **Context** provides the [createBundleContext(bundleName:string)] ...@@ -205,99 +212,113 @@ The base class **Context** provides the [createBundleContext(bundleName:string)]
> >
> To obtain the context of a specified module of another application: > To obtain the context of a specified module of another application:
> >
> - Request the **ohos.permission.GET_BUNDLE_INFO_PRIVILEGED** permission. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). > - Request the **ohos.permission.GET_BUNDLE_INFO_PRIVILEGED** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
>
> - This is a system API and cannot be called by third-party applications. > - This is a system API and cannot be called by third-party applications.
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility { export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
let bundleName2 = "com.example.application"; let bundleName2 = 'com.example.application';
let moduleName2 = "module1"; let moduleName2 = 'module1';
let context2 = this.context.createModuleContext(bundleName2, moduleName2); let context2 = this.context.createModuleContext(bundleName2, moduleName2);
// ... // ...
} }
} }
``` ```
- Call **createModuleContext(moduleName:string)** to obtain the context of another module in the current application. After obtaining the context, you can obtain the resource information of that module. - Call **createModuleContext(moduleName:string)** to obtain the context of another module in the current application. After obtaining the context, you can obtain the resource information of that module.
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility { export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
let moduleName2 = "module1"; let moduleName2 = 'module1';
let context2 = this.context.createModuleContext(moduleName2); let context2 = this.context.createModuleContext(moduleName2);
// ... // ...
} }
} }
``` ```
### Subscribing to UIAbility Lifecycle Changes in a Process ### Subscribing to UIAbility Lifecycle Changes in a Process
In the DFX statistics scenario of an application, if you need to collect statistics on the stay duration and access frequency of a page, you can subscribe to UIAbility lifecycle changes. In the DFX statistics scenario of an application, if you need to collect statistics on the stay duration and access frequency of a page, you can subscribe to UIAbility lifecycle changes in a process.
[ApplicationContext](../reference/apis/js-apis-inner-application-applicationContext.md) provides APIs for subscribing to UIAbility lifecycle changes in a process. When the UIAbility lifecycle changes in a process, for example, being created or destroyed, becoming visible or invisible, or gaining or losing focus, the corresponding callback is triggered, and a listener ID is returned. The ID is incremented by 1 each time the listener is registered. When the number of listeners exceeds the upper limit (2^63-1), -1 is returned. The following uses [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) as an example. [ApplicationContext](../reference/apis/js-apis-inner-application-applicationContext) provides APIs for subscribing to UIAbility lifecycle changes in a process. When the UIAbility lifecycle changes in a process, for example, being created or destroyed, becoming visible or invisible, or gaining or losing focus, the corresponding callback is triggered. Each time the callback is registered, a listener lifecycle ID is returned, with the value incremented by 1 each time. When the number of listeners exceeds the upper limit (2^63-1), **-1** is returned. The following uses [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) as an example.
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window'; import window from '@ohos.window';
const TAG: string = "[Example].[Entry].[EntryAbility]"; const TAG: string = '[Example].[Entry].[EntryAbility]';
export default class EntryAbility extends UIAbility { export default class EntryAbility extends UIAbility {
lifecycleId: number; // Define a lifecycle ID.
lifecycleId: number;
onCreate(want, launchParam) {
let abilityLifecycleCallback = { onCreate(want, launchParam) {
onAbilityCreate(uiability) { // Define a lifecycle callback object.
console.info(TAG, "onAbilityCreate uiability:" + JSON.stringify(uiability)); let abilityLifecycleCallback = {
}, // Called when a UIAbility is created.
onWindowStageCreate(uiability, windowStage) { onAbilityCreate(uiAbility) {
console.info(TAG, "onWindowStageCreate uiability:" + JSON.stringify(uiability)); console.log(TAG, `onAbilityCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.info(TAG, "onWindowStageCreate windowStage:" + JSON.stringify(windowStage)); },
}, // Called when a window is created.
onWindowStageActive(uiability, windowStage) { onWindowStageCreate(uiAbility, windowStage: window.WindowStage) {
console.info(TAG, "onWindowStageActive uiability:" + JSON.stringify(uiability)); console.log(TAG, `onWindowStageCreate uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.info(TAG, "onWindowStageActive windowStage:" + JSON.stringify(windowStage)); console.log(TAG, `onWindowStageCreate windowStage: ${JSON.stringify(windowStage)}`);
}, },
onWindowStageInactive(uiability, windowStage) { // Called when the window becomes active.
console.info(TAG, "onWindowStageInactive uiability:" + JSON.stringify(uiability)); onWindowStageActive(uiAbility, windowStage: window.WindowStage) {
console.info(TAG, "onWindowStageInactive windowStage:" + JSON.stringify(windowStage)); console.log(TAG, `onWindowStageActive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
}, console.log(TAG, `onWindowStageActive windowStage: ${JSON.stringify(windowStage)}`);
onWindowStageDestroy(uiability, windowStage) { },
console.info(TAG, "onWindowStageDestroy uiability:" + JSON.stringify(uiability)); // Called when the window becomes inactive.
console.info(TAG, "onWindowStageDestroy windowStage:" + JSON.stringify(windowStage)); onWindowStageInactive(uiAbility, windowStage: window.WindowStage) {
}, console.log(TAG, `onWindowStageInactive uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
onAbilityDestroy(uiability) { console.log(TAG, `onWindowStageInactive windowStage: ${JSON.stringify(windowStage)}`);
console.info(TAG, "onAbilityDestroy uiability:" + JSON.stringify(uiability)); },
}, // Called when the window is destroyed.
onAbilityForeground(uiability) { onWindowStageDestroy(uiAbility, windowStage: window.WindowStage) {
console.info(TAG, "onAbilityForeground uiability:" + JSON.stringify(uiability)); console.log(TAG, `onWindowStageDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
}, console.log(TAG, `onWindowStageDestroy windowStage: ${JSON.stringify(windowStage)}`);
onAbilityBackground(uiability) { },
console.info(TAG, "onAbilityBackground uiability:" + JSON.stringify(uiability)); // Called when the UIAbility is destroyed.
}, onAbilityDestroy(uiAbility) {
onAbilityContinue(uiability) { console.log(TAG, `onAbilityDestroy uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
console.info(TAG, "onAbilityContinue uiability:" + JSON.stringify(uiability)); },
} // Called when the UIAbility is switched from the background to the foreground.
} onAbilityForeground(uiAbility) {
// 1. Obtain the application context through the context attribute. console.log(TAG, `onAbilityForeground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
let applicationContext = this.context.getApplicationContext(); },
// 2. Register a listener for the lifecycle changes through the application context. // Called when the UIAbility is switched from the foreground to the background.
this.lifecycleId = applicationContext.on("abilityLifecycle", abilityLifecycleCallback); onAbilityBackground(uiAbility) {
console.info(TAG, "register callback number: " + JSON.stringify(this.lifecycleId)); console.log(TAG, `onAbilityBackground uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
},
// Called when UIAbility is continued on another device.
onAbilityContinue(uiAbility) {
console.log(TAG, `onAbilityContinue uiAbility.launchWant: ${JSON.stringify(uiAbility.launchWant)}`);
}
} }
// Obtain the application context.
let applicationContext = this.context.getApplicationContext();
// Register the application lifecycle callback.
this.lifecycleId = applicationContext.on('abilityLifecycle', abilityLifecycleCallback);
console.log(TAG, `register callback number: ${this.lifecycleId}`);
}
onDestroy() { // ...
let applicationContext = this.context.getApplicationContext();
applicationContext.off("abilityLifecycle", this.lifecycleId, (error, data) => { onDestroy() {
console.info(TAG, "unregister callback success, err: " + JSON.stringify(error)); // Obtain the application context.
}); let applicationContext = this.context.getApplicationContext();
} // Deregister the application lifecycle callback.
applicationContext.off('abilityLifecycle', this.lifecycleId);
}
} }
``` ```
...@@ -30,7 +30,7 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol ...@@ -30,7 +30,7 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol
- An application is considered as a foreground application only when the application process gains focus or its UIAbility component is running in the foreground. - An application is considered as a foreground application only when the application process gains focus or its UIAbility component is running in the foreground.
- Verify the **ohos.permission.START_ABILITIES_FROM_BACKGROUND** permission. - Verify the **ohos.permission.START_ABILITIES_FROM_BACKGROUND** permission.
- **When the startAbilityByCall() method is used, verify the call permission.** For details, see [Using Ability Call to Implement UIAbility Interaction](uiability-intra-device-interaction.md#using-ability-call-to-implement-uiability-interaction) and [Using Cross-Device Ability Call](hop-multi-device-collaboration.md#using-cross-device-ability-call). - **When the startAbilityByCall() method is used, verify the call permission.** For details, see [Using Call to Implement UIAbility Interaction](uiability-intra-device-interaction.md#using-call-to-implement-uiability-interaction) and [Using Cross-Device Call](hop-multi-device-collaboration.md#using-cross-device-call).
- Verify the **ohos.permission.ABILITY_BACKGROUND_COMMUNICATION** permission. - Verify the **ohos.permission.ABILITY_BACKGROUND_COMMUNICATION** permission.
......
...@@ -76,22 +76,22 @@ In the FA model, you can call **getContext** of **featureAbility** to obtain the ...@@ -76,22 +76,22 @@ In the FA model, you can call **getContext** of **featureAbility** to obtain the
The following code snippet shows how to use **getContext()** to obtain the application context and distributed directory: The following code snippet shows how to use **getContext()** to obtain the application context and distributed directory:
```ts ```ts
import featureAbility from '@ohos.ability.featureAbility' import featureAbility from '@ohos.ability.featureAbility';
import fileIo from '@ohos.fileio' import fs from '@ohos.file.fs';
(async () => { (async () => {
let dir: string let dir: string;
try { try {
console.info('Begin to getOrCreateDistributedDir') console.info('Begin to getOrCreateDistributedDir');
dir = await featureAbility.getContext().getOrCreateDistributedDir() dir = await featureAbility.getContext().getOrCreateDistributedDir();
console.info('distribute dir is ' + dir) console.info('distribute dir is ' + dir)
} catch (error) { } catch (error) {
console.error('getOrCreateDistributedDir failed with ' + error) console.error('getOrCreateDistributedDir failed with ' + error);
} }
let fd: number; let fd: number;
let path = dir + "/a.txt"; let path = dir + "/a.txt";
fd = fileIo.openSync(path, 0o2 | 0o100, 0o666); fd = fs.openSync(path, fs.OpenMode.READ_WRITE).fd;
fileIo.close(fd); fs.close(fd);
})() })()
``` ```
...@@ -2,20 +2,20 @@ ...@@ -2,20 +2,20 @@
Users often need to share data (such as a text or an image) from one application to another. The following uses PDF file sharing as an example to describe how to use Want to share data between applications. Users often need to share data (such as a text or an image) from one application to another. The following uses PDF file sharing as an example to describe how to use Want to share data between applications.
Data sharing requires two UIAbility components (one for the sharing party and the other for the shared party) and one system component (used as the application selector). When the sharing party initiates data sharing by calling **startAbility()**, the system implicitly matches and displays all applications that support the type of data to share. After the user selects an application, the system starts the application to complete data sharing. Data sharing requires two UIAbility components (one for the sharing party and the other for the shared party) and one system component (used as the application sharing box). When the sharing party initiates data sharing by calling **startAbility()**, the system implicitly matches and displays all applications that support the type of data to share. After the user selects an application, the system starts the application to complete data sharing.
In this section, data sharing is triggered by touching a button. You can use other ways to trigger data sharing during application development. This section focuses on how to configure Want to implement data sharing. In this section, data sharing is triggered by touching a button. You can use other ways to trigger data sharing during application development. This section focuses on how to configure Want to implement data sharing.
The following actions are involved for data sharing: The following actions are involved for data sharing:
- **ohos.want.action.select**: action of starting the application selector. - **ohos.want.action.select**: action of starting the application sharing box.
- **ohos.want.action.sendData**: action of sending a single data record, that is, transferring data to the shared party. - **ohos.want.action.sendData**: action of sending a single data record, that is, transferring data to the shared party.
## Sharing Party ## Sharing Party
The sharing party starts an application selector and transfers the data to the shared party. Therefore, Want of the sharing party must be nested at two layers. In the first layer, implicit Want is used together with the **ohos.want.action.select** action to display the application selector. In the second layer, the data to share is declared The sharing party starts an application sharing box and transfers the data to the shared party. Therefore, Want of the sharing party must be nested at two layers. In the first layer, implicit Want is used together with the **ohos.want.action.select** action to display the application sharing box. In the second layer, the data to share is declared
in the custom field **parameters**, and then the Want that includes the **ohos.want.action.sendData** action and the **parameters** field is transferred to the application selector. The shared party obtains the shared data from **parameters**. in the custom field **parameters**, and then the Want that includes the **ohos.want.action.sendData** action and the **parameters** field is transferred to the application sharing box. The shared party obtains the shared data from **parameters**.
```ts ```ts
import common from '@ohos.app.ability.common'; import common from '@ohos.app.ability.common';
...@@ -28,21 +28,21 @@ let fileSize; // Obtain the size of the file to share. ...@@ -28,21 +28,21 @@ let fileSize; // Obtain the size of the file to share.
function implicitStartAbility() { function implicitStartAbility() {
let context = getContext(this) as common.UIAbilityContext; let context = getContext(this) as common.UIAbilityContext;
let wantInfo = { let wantInfo = {
/ This action is used to implicitly match the application selector. / This action is used to implicitly match the application sharing box.
action: 'ohos.want.action.select', action: 'ohos.want.action.select',
// This is the custom parameter in the first layer of Want, // This is the custom parameter in the first layer of Want,
/ which is intended to add information to the application selector. / which is intended to add information to the application sharing box.
parameters: { parameters: {
// MIME type of PDF. // MIME type of PDF.
"ability.picker.type": fileType, 'ability.picker.type': fileType,
"ability.picker.fileNames": [fileName], 'ability.picker.fileNames': [fileName],
"ability.picker.fileSizes": [fileSize], 'ability.picker.fileSizes': [fileSize],
// This is nested Want ,which will be directly sent to the selected application. // This is nested Want ,which will be directly sent to the selected application.
"ability.want.params.INTENT": { 'ability.want.params.INTENT': {
"action": "ohos.want.action.sendData", 'action': 'ohos.want.action.sendData',
"type": "application/pdf", 'type': 'application/pdf',
"parameters": { 'parameters': {
"keyFd": { "type": "FD", "value": fileFd } 'keyFd': { 'type': 'FD', 'value': fileFd }
} }
} }
} }
...@@ -59,14 +59,15 @@ function implicitStartAbility() { ...@@ -59,14 +59,15 @@ function implicitStartAbility() {
> >
> Data sharing can be implemented only in FD format. For details about how to obtain the FD and file name, see [File Management](../reference/apis/js-apis-file-fs.md). > Data sharing can be implemented only in FD format. For details about how to obtain the FD and file name, see [File Management](../reference/apis/js-apis-file-fs.md).
In the preceding code, under the custom field **parameters**, the following **ability.picker.*** fields are used to pass the information to be displayed on the application selector: In the preceding code, under the custom field **parameters**, the following **ability.picker.*** fields are used to pass the information to be displayed on the application sharing box:
- **ability.picker.type**: file type icon. - **ability.picker.type**: file type icon.
- **ability.picker.fileNames**: file name. - **ability.picker.fileNames**: file name.
- **ability.picker.fileSizes**: file size, in bytes. - **ability.picker.fileSizes**: file size, in bytes.
- **ability.picker.fileNames** and **ability.picker.fileSizes** are arrays and have a one-to-one mapping. - **ability.picker.fileNames** and **ability.picker.fileSizes** are arrays and have a one-to-one mapping.
The following figure shows an example. The following figure shows an example.
![](figures/ability-startup-with-implicit-want2.png) ![](figures/ability-startup-with-implicit-want2.png)
## Shared Party ## Shared Party
......
...@@ -62,7 +62,7 @@ The system matches the **action** attribute in the **want** parameter passed by ...@@ -62,7 +62,7 @@ The system matches the **action** attribute in the **want** parameter passed by
**Figure 1** Matching rules of action in the want parameter **Figure 1** Matching rules of action in the want parameter
![want-action](figures/want-action.png) ![want-action](figures/want-action.png)
### Matching Rules of entities in the want Parameter ### Matching Rules of entities in the want Parameter
...@@ -79,19 +79,15 @@ The system matches the **entities** attribute in the **want** parameter passed b ...@@ -79,19 +79,15 @@ The system matches the **entities** attribute in the **want** parameter passed b
- If **entities** in the passed **want** parameter is specified, and **entities** under **skills** of an ability is specified but does not contain **entities** in the passed **want** parameter, the matching fails. - If **entities** in the passed **want** parameter is specified, and **entities** under **skills** of an ability is specified but does not contain **entities** in the passed **want** parameter, the matching fails.
Figure 2 Matching rule of entities in the want parameter **Figure 2** Matching rule of entities in the want parameter
![want-entities](figures/want-entities.png) ![want-entities](figures/want-entities.png)
### Matching Rules of uri and type in the want Parameter ### Matching Rules of uri and type in the want Parameter
When the **uri** and **type** parameters are specified in the **want** parameter to initiate a component startup request, the system traverses the list of installed components and matches the **uris** array under **skills** of the abilities one by one. If one of the **uris** arrays under **skills** matches the **uri** and **type** in the passed **want**, the matching is successful. When the **uri** and **type** parameters are specified in the **want** parameter to initiate a component startup request, the system traverses the list of installed components and matches the **uris** array under **skills** of the abilities one by one. If one of the **uris** arrays under **skills** matches the **uri** and **type** in the passed **want**, the matching is successful.
Figure 3 Matching rules when uri and type are specified in the want parameter
![want-uri-type1](figures/want-uri-type1.png)
There are four combinations of **uri** and **type** settings. The matching rules are as follows: There are four combinations of **uri** and **type** settings. The matching rules are as follows:
- Neither **uri** or **type** is specified in the **want** parameter. - Neither **uri** or **type** is specified in the **want** parameter.
...@@ -111,11 +107,17 @@ There are four combinations of **uri** and **type** settings. The matching rules ...@@ -111,11 +107,17 @@ There are four combinations of **uri** and **type** settings. The matching rules
- If the **uris** array under **skills** of an ability is unspecified, the matching fails. - If the **uris** array under **skills** of an ability is unspecified, the matching fails.
- If the **uris** array under **skills** of an ability contains an element whose [uri is matched](#matching-rules-of-uri) and [type is matched](#matching-rules-of-type), the matching is successful. Otherwise, the matching fails. - If the **uris** array under **skills** of an ability contains an element whose [uri is matched](#matching-rules-of-uri) and [type is matched](#matching-rules-of-type), the matching is successful. Otherwise, the matching fails.
Leftmost URI matching: When only **scheme**, a combination of **scheme** and **host**, or a combination of **scheme**, **host**, and **port** is configured in the **uris** array under **skills** of the ability,
the matching is successful only if the leftmost URI in the passed **want** parameter matches **scheme**, the combination of **scheme** and **host**, or the combination of **scheme**, **host**, and **port**.
To simplify the description, **uri** and **type** passed in the **want** parameter are called **w_uri** and **w_type**, respectively; the **uris** array under **skills** of an ability to match is called **s_uris**; each element in the array is called **s_uri**. Matching is performed from top to bottom. **Figure 3** Matching rules when uri and type are specified in the want parameter
![want-uri-type1](figures/want-uri-type1.png)
To simplify the description, **uri** and **type** passed in the **want** parameter are called **w_uri** and **w_type**, respectively; the **uris** array under **skills** of an ability to match is called **s_uris**; each element in the array is called **s_uri**. Matching is performed from top to bottom.
Figure 4 Matching rules of uri and type in the want parameter **Figure 4** Matching rules of uri and type in the want parameter
![want-uri-type2](figures/want-uri-type2.png) ![want-uri-type2](figures/want-uri-type2.png)
...@@ -128,7 +130,9 @@ To simplify the description, **uri** in the passed **want** parameter is called ...@@ -128,7 +130,9 @@ To simplify the description, **uri** in the passed **want** parameter is called
- If **host** of **s_uri** is unspecified and **scheme** of **w_uri** and **scheme** of **s_uri** are the same, the matching is successful. Otherwise, the matching fails. - If **host** of **s_uri** is unspecified and **scheme** of **w_uri** and **scheme** of **s_uri** are the same, the matching is successful. Otherwise, the matching fails.
- If **path**, **pathStartWith**, and **pathRegex** of **s_uri** are unspecified and **w_uri** and **s_uri** are the same, the matching is successful. Otherwise, the matching fails. - If **port** of **s_uri** is unspecified and the combination of **scheme** and **host** of **w_uri** is the same as the combination of **scheme** and **host** of **s_uri**, the matching is successful. Otherwise, the matching fails.
- If **path**, **pathStartWith**, and **pathRegex** of **s_uri** are unspecified and the combination of **scheme**, **host**, and **port** of **w_uri** is the same as the combination of **scheme**, **host**, and **port** of **s_uri**, the matching is successful. Otherwise, the matching fails.
- If **path** of **s_uri** is specified and the **full path expressions** of **w_uri** and **s_uri** are the same, the matching is successful. Otherwise, the matching of **pathStartWith** continues. - If **path** of **s_uri** is specified and the **full path expressions** of **w_uri** and **s_uri** are the same, the matching is successful. Otherwise, the matching of **pathStartWith** continues.
...@@ -139,12 +143,17 @@ To simplify the description, **uri** in the passed **want** parameter is called ...@@ -139,12 +143,17 @@ To simplify the description, **uri** in the passed **want** parameter is called
> **NOTE** > **NOTE**
> >
> The **scheme**, **host**, **port**, **path**, **pathStartWith**, and **pathRegex** attributes of **uris** under **skills** of an ability are concatenated. If **path**, **pathStartWith**, and **pathRegex** are declared in sequence, **uris** can be concatenated into the following expressions: > The **scheme**, **host**, **port**, **path**, **pathStartWith**, and **pathRegex** attributes of **uris** under **skills** of an ability are concatenated. If **path**, **pathStartWith**, and **pathRegex** are declared in sequence, **uris** can be concatenated into the following expressions:
> >
> - **Full path expression**: `scheme://host:port/path` > - **Full path expression**: `scheme://host:port/path`
> >
> - **Prefix expression**: `scheme://host:port/pathStartWith` > - **Prefix expression**: `scheme://host:port/pathStartWith`
> >
> - **Regular expression**: `scheme://host:port/pathRegex` > - **Regular expression**: `scheme://host:port/pathRegex`
>
> - **Prefix URI expression**: When only **scheme**, a combination of **scheme** and **host**, or a combination of **scheme**, **host**, and **port** is configured in the configuration file, the matching is successful if a URI prefixed with the configuration file is passed in.
> * `scheme://`
> * `scheme://host`
> * `scheme://host:port`
### Matching Rules of type ### Matching Rules of type
......
# Cross-Device Migration (for System Applications Only)] # Cross-Device Migration (for System Applications Only)
## When to Use ## When to Use
...@@ -47,25 +47,16 @@ The table below describes the main APIs used for cross-device migration. For det ...@@ -47,25 +47,16 @@ The table below describes the main APIs used for cross-device migration. For det
## How to Develop ## How to Develop
1. Configure the data synchronization permission in the **module.json5** file. The sample code is as follows: 1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
```json
{
"module": {
"requestPermissions":[
{
"name" : "ohos.permission.DISTRIBUTED_DATASYNC",
}
]
}
}
```
2. Configure the fields related to cross-device migration in the configuration file. 2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
- Configure the application to support migration.
Set the **continuable** field in the **module.json5** file to **true**. The default value is **false**. If this parameter is set to **false**, the application cannot be continued on the target device. 3. Configure the fields related to cross-device migration in the configuration file.
Configure the application to support migration.
Set the **continuable** field in the **module.json5** file to **true**. The default value is **false**. If this parameter is set to **false**, the application cannot be continued on the target device.
```json ```json
{ {
"module": { "module": {
...@@ -80,47 +71,31 @@ The table below describes the main APIs used for cross-device migration. For det ...@@ -80,47 +71,31 @@ The table below describes the main APIs used for cross-device migration. For det
} }
``` ```
- Configure the application launch type. For details, see [UIAbility Component Launch Type](uiability-launch-type.md). Configure the application launch type. For details, see [UIAbility Component Launch Type](uiability-launch-type.md).
3. Request the data synchronization permission. The sample code for displaying a dialog box to request the permission is as follows:
```ts
requestPermission() {
let context = this.context
let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC']
context.requestPermissionsFromUser(permissions).then((data) => {
console.info("Succeed to request permission from user with data: "+ JSON.stringify(data))
}).catch((error) => {
console.info("Failed to request permission from user with error: "+ JSON.stringify(error))
})
}
```
4. Implement [onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) in the UIAbility of the initiator. 4. Implement [onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) in the UIAbility of the initiator.
[onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) is called on the initiator. You can save the data in this method to implement application compatibility check and migration decision. [onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) is called on the initiator. You can save the data in this method to implement application compatibility check and migration decision.
- Saving migrated data: You can save the data to be migrated in key-value pairs in **wantParam**. - Saving migrated data: You can save the data to be migrated in key-value pairs in **wantParam**.
- Checking application compatibility: You can obtain the version number of the target application from **wantParam** and check the compatibility between the target application and the current application. - Checking application compatibility: You can obtain the version number of the target application from **wantParam** and check the compatibility between the target application and the current application.
- Making a migration decision: You can determine whether to support the migration based on the return value of **onContinue()**. For details about the return value, see [Available APIs](#available-apis). - Making a migration decision: You can determine whether to support the migration based on the return value of **onContinue()**. For details about the return value, see [Available APIs](#available-apis).
The sample code is as follows: The sample code is as follows:
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
import AbilityConstant from '@ohos.app.ability.AbilityConstant'; import AbilityConstant from '@ohos.app.ability.AbilityConstant';
onContinue(wantParam : {[key: string]: any}) { onContinue(wantParam : {[key: string]: any}) {
console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`) console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`)
let workInput = AppStorage.Get<string>('ContinueWork'); let workInput = AppStorage.Get<string>('ContinueWork');
// Set the user input data into wantParam. // Set the user input data into wantParam.
wantParam["work"] = workInput // set user input data into want params wantParam["work"] = workInput // set user input data into want params
console.info(`onContinue input = ${wantParam["input"]}`); console.info(`onContinue input = ${wantParam["input"]}`);
return AbilityConstant.OnContinueResult.AGREE return AbilityConstant.OnContinueResult.AGREE
} }
``` ```
5. Implement **onCreate()** and **onNewWant()** in the UIAbility of the target application to implement data restoration. 5. Implement **onCreate()** and **onNewWant()** in the UIAbility of the target application to implement data restoration.
- Implementation example of **onCreate** in the multi-instance scenario - Implementation example of **onCreate** in the multi-instance scenario
......
...@@ -11,7 +11,7 @@ Multi-device coordination involves the following scenarios: ...@@ -11,7 +11,7 @@ Multi-device coordination involves the following scenarios:
- [Connecting to ServiceExtensionAbility Across Devices](#connecting-to-serviceextensionability-across-devices) - [Connecting to ServiceExtensionAbility Across Devices](#connecting-to-serviceextensionability-across-devices)
- [Using Cross-Device Ability Call](#using-cross-device-ability-call) - [Using Cross-Device Call](#using-cross-device-call)
## Multi-Device Collaboration Process ## Multi-Device Collaboration Process
...@@ -47,24 +47,12 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -47,24 +47,12 @@ On device A, touch the **Start** button provided by the initiator application to
### How to Develop ### How to Develop
1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). 1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
2. Request the data synchronization permission. The sample code for displaying a dialog box to request the permission is as follows: 2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
```ts
requestPermission() {
let context = this.context;
let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC'];
context.requestPermissionsFromUser(permissions).then((data) => {
console.info("Succeed to request permission from user with data: "+ JSON.stringify(data));
}).catch((error) => {
console.info("Failed to request permission from user with error: "+ JSON.stringify(error));
})
}
```
3. Obtain the device ID of the target device. 3. Obtain the device ID of the target device.
```ts ```ts
import deviceManager from '@ohos.distributedHardware.deviceManager'; import deviceManager from '@ohos.distributedHardware.deviceManager';
...@@ -94,7 +82,7 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -94,7 +82,7 @@ On device A, touch the **Start** button provided by the initiator application to
``` ```
4. Set the target component parameters, and call [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to start UIAbility or ServiceExtensionAbility. 4. Set the target component parameters, and call [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to start UIAbility or ServiceExtensionAbility.
```ts ```ts
let want = { let want = {
deviceId: getRemoteDeviceId(), deviceId: getRemoteDeviceId(),
...@@ -102,7 +90,7 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -102,7 +90,7 @@ On device A, touch the **Start** button provided by the initiator application to
abilityName: 'FuncAbility', abilityName: 'FuncAbility',
moduleName: 'module1', // moduleName is optional. moduleName: 'module1', // moduleName is optional.
} }
// context is the ability-level context of the initiator UIAbility. // context is the AbilityContext of the initiator UIAbility.
this.context.startAbility(want).then(() => { this.context.startAbility(want).then(() => {
// ... // ...
}).catch((err) => { }).catch((err) => {
...@@ -118,35 +106,23 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -118,35 +106,23 @@ On device A, touch the **Start** button provided by the initiator application to
### Available APIs ### Available APIs
**Table 2** APIs for starting an ability across devices and returning the result data **Table 2** APIs for starting a UIAbility across devices and returning the result data
| API| Description| | API| Description|
| -------- | -------- | | -------- | -------- |
| startAbilityForResult(want: Want, callback: AsyncCallback&lt;AbilityResult&gt;): void; | Starts a UIAbility. This API uses an asynchronous callback to return the result when the UIAbility is terminated.| | startAbilityForResult(want: Want, callback: AsyncCallback&lt;AbilityResult&gt;): void; | Starts a UIAbility. This API uses an asynchronous callback to return the result when the UIAbility is terminated.|
| terminateSelfWithResult(parameter: AbilityResult, callback: AsyncCallback&lt;void&gt;): void;| Terminates this UIAbility. This API uses an asynchronous callback to return the ability result information. It is used together with **startAbilityForResult**.| | terminateSelfWithResult(parameter: AbilityResult, callback: AsyncCallback&lt;void&gt;): void;| Terminates this UIAbility. This API uses an asynchronous callback to return the result information. It is used together with **startAbilityForResult**.|
| terminateSelfWithResult(parameter: AbilityResult): Promise&lt;void&gt;; | Terminates this UIAbility. This API uses a promise to return the ability result information. It is used together with **startAbilityForResult**.| | terminateSelfWithResult(parameter: AbilityResult): Promise&lt;void&gt;; | Terminates this UIAbility. This API uses a promise to return the result information. It is used together with **startAbilityForResult**.|
### How to Develop ### How to Develop
1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). 1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
2. Request the data synchronization permission. The sample code for displaying a dialog box to request the permission is as follows: 2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
```ts
requestPermission() {
let context = this.context;
let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC'];
context.requestPermissionsFromUser(permissions).then((data) => {
console.info("Succeed to request permission from user with data: "+ JSON.stringify(data));
}).catch((error) => {
console.info("Failed to request permission from user with error: "+ JSON.stringify(error));
})
}
```
3. Set the target component parameters on the initiator, and call **startAbilityForResult()** to start the target UIAbility. **data** in the asynchronous callback is used to receive the information returned by the target UIAbility to the initiator UIAbility after the target UIAbility terminates itself. For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-and-serviceextensionability-across-devices-no-data-returned). 3. Set the target component parameters on the initiator, and call **startAbilityForResult()** to start the target UIAbility. **data** in the asynchronous callback is used to receive the information returned by the target UIAbility to the initiator UIAbility after the target UIAbility terminates itself. For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-and-serviceextensionability-across-devices-no-data-returned).
```ts ```ts
let want = { let want = {
deviceId: getRemoteDeviceId(), deviceId: getRemoteDeviceId(),
...@@ -154,7 +130,7 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -154,7 +130,7 @@ On device A, touch the **Start** button provided by the initiator application to
abilityName: 'FuncAbility', abilityName: 'FuncAbility',
moduleName: 'module1', // moduleName is optional. moduleName: 'module1', // moduleName is optional.
} }
// context is the ability-level context of the initiator UIAbility. // context is the AbilityContext of the initiator UIAbility.
this.context.startAbilityForResult(want).then((data) => { this.context.startAbilityForResult(want).then((data) => {
// ... // ...
}).catch((err) => { }).catch((err) => {
...@@ -163,7 +139,7 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -163,7 +139,7 @@ On device A, touch the **Start** button provided by the initiator application to
``` ```
4. After the UIAbility task at the target device is complete, call **terminateSelfWithResult()** to return the data to the initiator UIAbility. 4. After the UIAbility task at the target device is complete, call **terminateSelfWithResult()** to return the data to the initiator UIAbility.
```ts ```ts
const RESULT_CODE: number = 1001; const RESULT_CODE: number = 1001;
let abilityResult = { let abilityResult = {
...@@ -174,20 +150,20 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -174,20 +150,20 @@ On device A, touch the **Start** button provided by the initiator application to
moduleName: 'module1', moduleName: 'module1',
}, },
} }
// context is the ability-level context of the target UIAbility. // context is the AbilityContext of the target UIAbility.
this.context.terminateSelfWithResult(abilityResult, (err) => { this.context.terminateSelfWithResult(abilityResult, (err) => {
// ... // ...
}); });
``` ```
5. The initiator UIAbility receives the information returned by the target UIAbility and processes the information. 5. The initiator UIAbility receives the information returned by the target UIAbility and processes the information.
```ts ```ts
const RESULT_CODE: number = 1001; const RESULT_CODE: number = 1001;
// ... // ...
// context is the ability-level context of the initiator UIAbility. // context is the UIAbilityContext of the initiator UIAbility.
this.context.startAbilityForResult(want).then((data) => { this.context.startAbilityForResult(want).then((data) => {
if (data?.resultCode === RESULT_CODE) { if (data?.resultCode === RESULT_CODE) {
// Parse the information returned by the target UIAbility. // Parse the information returned by the target UIAbility.
...@@ -218,21 +194,9 @@ A system application can connect to a service on another device by calling [conn ...@@ -218,21 +194,9 @@ A system application can connect to a service on another device by calling [conn
### How to Develop ### How to Develop
1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). 1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
2. Request the data synchronization permission. The sample code for displaying a dialog box to request the permission is as follows: 2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
```ts
requestPermission() {
let context = this.context;
let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC'];
context.requestPermissionsFromUser(permissions).then((data) => {
console.info("Succeed to request permission from user with data: "+ JSON.stringify(data));
}).catch((error) => {
console.info("Failed to request permission from user with error: "+ JSON.stringify(error));
})
}
```
3. (Optional) [Implement a background service](serviceextensionability.md#implementing-a-background-service). Perform this operation only if no background service is available. 3. (Optional) [Implement a background service](serviceextensionability.md#implementing-a-background-service). Perform this operation only if no background service is available.
...@@ -292,7 +256,7 @@ A system application can connect to a service on another device by calling [conn ...@@ -292,7 +256,7 @@ A system application can connect to a service on another device by calling [conn
For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-and-serviceextensionability-across-devices-no-data-returned). For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-and-serviceextensionability-across-devices-no-data-returned).
5. Disconnect the connection. Use **disconnectServiceExtensionAbility()** to disconnect from the background service. 5. Disconnect the connection. Use **disconnectServiceExtensionAbility()** to disconnect from the background service.
```ts ```ts
let connectionId = 1 // ID returned when the service is connected through connectServiceExtensionAbility. let connectionId = 1 // ID returned when the service is connected through connectServiceExtensionAbility.
this.context.disconnectServiceExtensionAbility(connectionId).then((data) => { this.context.disconnectServiceExtensionAbility(connectionId).then((data) => {
...@@ -303,145 +267,134 @@ A system application can connect to a service on another device by calling [conn ...@@ -303,145 +267,134 @@ A system application can connect to a service on another device by calling [conn
``` ```
## Using Cross-Device Ability Call ## Using Cross-Device Call
The basic principle of cross-device ability call is the same as that of intra-device ability call. For details, see [Using Ability Call to Implement UIAbility Interaction (for System Applications Only)](uiability-intra-device-interaction.md#using-ability-call-to-implement-uiability-interaction-for-system-applications-only). The basic principle of cross-device call is the same as that of intra-device call. For details, see [Using Call to Implement UIAbility Interaction (for System Applications Only)](uiability-intra-device-interaction.md#using-call-to-implement-uiability-interaction-for-system-applications-only).
The following describes how to implement multi-device collaboration through cross-device ability call. The following describes how to implement multi-device collaboration through cross-device call.
### Available APIs ### Available APIs
**Table 4** Ability call APIs **Table 4** Call APIs
| API| Description| | API| Description|
| -------- | -------- | | -------- | -------- |
| startAbilityByCall(want: Want): Promise&lt;Caller&gt;; | Starts a UIAbility in the foreground or background and obtains the caller object for communicating with the UIAbility.| | startAbilityByCall(want: Want): Promise&lt;Caller&gt;; | Starts a UIAbility in the foreground or background and obtains the caller object for communicating with the UIAbility.|
| on(method: string, callback: CalleeCallBack): void | Callback invoked when the callee ability registers a method.| | on(method: string, callback: CalleeCallBack): void | Callback invoked when the CalleeAbility registers a method.|
| off(method: string): void | Callback invoked when the callee ability deregisters a method.| | off(method: string): void | Callback invoked when the CalleeAbility deregisters a method.|
| call(method: string, data: rpc.Parcelable): Promise&lt;void&gt; | Sends agreed parcelable data to the callee ability.| | call(method: string, data: rpc.Parcelable): Promise&lt;void&gt; | Sends agreed parcelable data to the CalleeAbility.|
| callWithResult(method: string, data: rpc.Parcelable): Promise&lt;rpc.MessageSequence&gt;| Sends agreed parcelable data to the callee ability and obtains the agreed parcelable data returned by the callee ability.| | callWithResult(method: string, data: rpc.Parcelable): Promise&lt;rpc.MessageSequence&gt;| Sends agreed parcelable data to the CalleeAbility and obtains the agreed parcelable data returned by the CalleeAbility.|
| release(): void | Releases the caller object.| | release(): void | Releases the caller object.|
| on(type: "release", callback: OnReleaseCallback): void | Callback invoked when the caller object is released.| | on(type: "release", callback: OnReleaseCallback): void | Callback invoked when the caller object is released.|
### How to Develop ### How to Develop
1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). 1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
2. Request the data synchronization permission. The sample code for displaying a dialog box to request the permission is as follows:
```ts
requestPermission() {
let context = this.context;
let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC'];
context.requestPermissionsFromUser(permissions).then((data) => {
console.info("Succeed to request permission from user with data: "+ JSON.stringify(data));
}).catch((error) => {
console.info("Failed to request permission from user with error: "+ JSON.stringify(error));
})
}
```
3. Create the callee ability. 2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
3. Create the CalleeAbility.
For the callee ability, implement the callback to receive data and the methods to marshal and unmarshal data. When data needs to be received, use **on()** to register a listener. When data does not need to be received, use **off()** to deregister the listener. For the CalleeAbility, implement the callback to receive data and the methods to marshal and unmarshal data. When data needs to be received, use **on()** to register a listener. When data does not need to be received, use **off()** to deregister the listener.
1. Configure the launch type of the UIAbility. 1. Configure the launch type of the UIAbility.
Set **launchType** of the callee ability to **singleton** in the **module.json5** file.
| JSON Field| Description| Set **launchType** of the CalleeAbility to **singleton** in the **module.json5** file.
| -------- | -------- |
| "launchType"| Ability launch type. Set this parameter to **singleton**.|
An example of the UIAbility configuration is as follows: | JSON Field| Description|
| -------- | -------- |
| "launchType"| UIAbility launch type. Set this parameter to **singleton**.|
An example of the UIAbility configuration is as follows:
```json
"abilities":[{
"name": ".CalleeAbility",
"srcEntrance": "./ets/CalleeAbility/CalleeAbility.ts",
"launchType": "singleton",
"description": "$string:CalleeAbility_desc",
"icon": "$media:icon",
"label": "$string:CalleeAbility_label",
"visible": true
}]
```
2. Import the **UIAbility** module.
```ts
import Ability from '@ohos.app.ability.UIAbility';
```
3. Define the agreed parcelable data.
The data formats sent and received by the caller and callee abilities must be consistent. In the following example, the data formats are number and string.
```ts
export default class MyParcelable {
num: number = 0;
str: string = "";
constructor(num, string) {
this.num = num;
this.str = string;
}
marshalling(messageSequence) {
messageSequence.writeInt(this.num);
messageSequence.writeString(this.str);
return true;
}
unmarshalling(messageSequence) {
this.num = messageSequence.readInt();
this.str = messageSequence.readString();
return true;
}
}
```
4. Implement **Callee.on** and **Callee.off**.
In the following example, the **MSG_SEND_METHOD** listener is registered in **onCreate()** of the ability and deregistered in **onDestroy()**. After receiving parcelable data, the application processes the data and returns the data result. You need to implement processing based on service requirements.
```ts ```json
const TAG: string = '[CalleeAbility]'; "abilities":[{
const MSG_SEND_METHOD: string = 'CallSendMsg'; "name": ".CalleeAbility",
"srcEntrance": "./ets/CalleeAbility/CalleeAbility.ts",
function sendMsgCallback(data) { "launchType": "singleton",
console.info('CalleeSortFunc called'); "description": "$string:CalleeAbility_desc",
"icon": "$media:icon",
// Obtain the parcelable data sent by the caller ability. "label": "$string:CalleeAbility_label",
let receivedData = new MyParcelable(0, ''); "visible": true
data.readParcelable(receivedData); }]
console.info(`receiveData[${receivedData.num}, ${receivedData.str}]`); ```
2. Import the **UIAbility** module.
// Process the data.
// Return the parcelable data result to the caller ability. ```ts
return new MyParcelable(receivedData.num + 1, `send ${receivedData.str} succeed`); import Ability from '@ohos.app.ability.UIAbility';
} ```
3. Define the agreed parcelable data.
export default class CalleeAbility extends Ability {
onCreate(want, launchParam) { The data formats sent and received by the CallerAbility and CalleeAbility must be consistent. In the following example, the data formats are number and string.
try {
this.callee.on(MSG_SEND_METHOD, sendMsgCallback);
} catch (error) {
console.info(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`);
}
}
onDestroy() {
try {
this.callee.off(MSG_SEND_METHOD);
} catch (error) {
console.error(TAG, `${MSG_SEND_METHOD} unregister failed with error ${JSON.stringify(error)}`);
}
}
}
```
4. Obtain the caller object and access the callee ability.
```ts
export default class MyParcelable {
num: number = 0;
str: string = "";
constructor(num, string) {
this.num = num;
this.str = string;
}
marshalling(messageSequence) {
messageSequence.writeInt(this.num);
messageSequence.writeString(this.str);
return true;
}
unmarshalling(messageSequence) {
this.num = messageSequence.readInt();
this.str = messageSequence.readString();
return true;
}
}
```
4. Implement **Callee.on** and **Callee.off**.
In the following example, the **MSG_SEND_METHOD** listener is registered in **onCreate()** of the UIAbility and deregistered in **onDestroy()**. After receiving parcelable data, the application processes the data and returns the data result. You need to implement processing based on service requirements.
```ts
const TAG: string = '[CalleeAbility]';
const MSG_SEND_METHOD: string = 'CallSendMsg';
function sendMsgCallback(data) {
console.info('CalleeSortFunc called');
// Obtain the parcelable data sent by the CallerAbility.
let receivedData = new MyParcelable(0, '');
data.readParcelable(receivedData);
console.info(`receiveData[${receivedData.num}, ${receivedData.str}]`);
// Process the data.
// Return the parcelable data result to the CallerAbility.
return new MyParcelable(receivedData.num + 1, `send ${receivedData.str} succeed`);
}
export default class CalleeAbility extends Ability {
onCreate(want, launchParam) {
try {
this.callee.on(MSG_SEND_METHOD, sendMsgCallback);
} catch (error) {
console.info(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`);
}
}
onDestroy() {
try {
this.callee.off(MSG_SEND_METHOD);
} catch (error) {
console.error(TAG, `${MSG_SEND_METHOD} unregister failed with error ${JSON.stringify(error)}`);
}
}
}
```
4. Obtain the caller object and access the CalleeAbility.
1. Import the **UIAbility** module. 1. Import the **UIAbility** module.
```ts ```ts
...@@ -449,7 +402,7 @@ The following describes how to implement multi-device collaboration through cros ...@@ -449,7 +402,7 @@ The following describes how to implement multi-device collaboration through cros
``` ```
2. Obtain the caller object. 2. Obtain the caller object.
The **context** attribute of the ability implements **startAbilityByCall** to obtain the caller object for communication. The following example uses **this.context** to obtain the **context** attribute of the ability, uses **startAbilityByCall** to start the callee ability, obtain the caller object, and register the **onRelease** listener of the caller ability. You need to implement processing based on service requirements. The **context** attribute of the UIAbility implements **startAbilityByCall** to obtain the caller object for communication. The following example uses **this.context** to obtain the **context** attribute of the UIAbility, uses **startAbilityByCall** to start the CalleeAbility, obtain the caller object, and register the **onRelease** and **onRemoteStateChange** listeners of the CallerAbility. You need to implement processing based on service requirements.
```ts ```ts
...@@ -465,11 +418,19 @@ The following describes how to implement multi-device collaboration through cros ...@@ -465,11 +418,19 @@ The following describes how to implement multi-device collaboration through cros
if (data != null) { if (data != null) {
caller = data; caller = data;
console.info('get remote caller success'); console.info('get remote caller success');
// Register the onRelease() listener of the caller ability. // Register the onRelease listener of the CallerAbility.
caller.onRelease((msg) => { caller.onRelease((msg) => {
console.info(`remote caller onRelease is called ${msg}`); console.info(`remote caller onRelease is called ${msg}`);
}) })
console.info('remote caller register OnRelease succeed'); console.info('remote caller register OnRelease succeed');
// Register the onRemoteStateChange listener of the CallerAbility.
try {
caller.onRemoteStateChange((str) => {
console.log('Remote state changed ' + str);
});
} catch (error) {
console.log('Caller.onRemoteStateChange catch error, error.code: ${JSON.stringify(error.code)}, error.message: ${JSON.stringify(error.message)}');
}
} }
}).catch((error) => { }).catch((error) => {
console.error(`get remote caller failed with ${error}`); console.error(`get remote caller failed with ${error}`);
...@@ -479,8 +440,8 @@ The following describes how to implement multi-device collaboration through cros ...@@ -479,8 +440,8 @@ The following describes how to implement multi-device collaboration through cros
For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-and-serviceextensionability-across-devices-no-data-returned). For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-and-serviceextensionability-across-devices-no-data-returned).
5. Sends agreed parcelable data to the callee ability. 5. Sends agreed parcelable data to the CalleeAbility.
1. The parcelable data can be sent to the callee ability with or without a return value. The method and parcelable data must be consistent with those of the callee ability. The following example describes how to send data to the callee ability. 1. The parcelable data can be sent to the CalleeAbility with or without a return value. The method and parcelable data must be consistent with those of the CalleeAbility. The following example describes how to send data to the CalleeAbility.
```ts ```ts
const MSG_SEND_METHOD: string = 'CallSendMsg'; const MSG_SEND_METHOD: string = 'CallSendMsg';
...@@ -493,7 +454,7 @@ The following describes how to implement multi-device collaboration through cros ...@@ -493,7 +454,7 @@ The following describes how to implement multi-device collaboration through cros
} }
} }
``` ```
2. In the following, **CallWithResult** is used to send data **originMsg** to the callee ability and assign the data processed by the **CallSendMsg** method to **backMsg**. 2. In the following, **CallWithResult** is used to send data **originMsg** to the CalleeAbility and assign the data processed by the **CallSendMsg** method to **backMsg**.
```ts ```ts
const MSG_SEND_METHOD: string = 'CallSendMsg'; const MSG_SEND_METHOD: string = 'CallSendMsg';
...@@ -517,8 +478,8 @@ The following describes how to implement multi-device collaboration through cros ...@@ -517,8 +478,8 @@ The following describes how to implement multi-device collaboration through cros
6. Release the caller object. 6. Release the caller object.
When the caller object is no longer required, use **release()** to release it. When the caller object is no longer required, use **release()** to release it.
```ts ```ts
releaseCall() { releaseCall() {
try { try {
......
...@@ -30,102 +30,100 @@ Missions are managed by system applications (such as home screen), rather than t ...@@ -30,102 +30,100 @@ Missions are managed by system applications (such as home screen), rather than t
A UIAbility instance corresponds to an independent mission. Therefore, when an application calls [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to start a UIAbility, a mission is created. A UIAbility instance corresponds to an independent mission. Therefore, when an application calls [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to start a UIAbility, a mission is created.
To call [missionManager](../reference/apis/js-apis-application-missionManager.md) to manage missions, the home screen application must request the **ohos.permission.MANAGE_MISSIONS** permission. For details about the configuration, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
To call [missionManager](../reference/apis/js-apis-application-missionManager.md) to manage missions, the home screen application must request the **ohos.permission.MANAGE_MISSIONS** permission. For details about the configuration, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
You can use **missionManager** to manage missions, for example, listening for mission changes, obtaining mission information or snapshots, and clearing, locking, or unlocking missions.
You can use **missionManager** to manage missions, for example, listening for mission changes, obtaining mission information or snapshots, and clearing, locking, or unlocking missions. The sample code is as follows: ```ts
import missionManager from '@ohos.app.ability.missionManager'
let listener = {
```ts // Listen for mission creation.
import missionManager from '@ohos.app.ability.missionManager' onMissionCreated: function (mission) {
console.info("--------onMissionCreated-------")
let listener = { },
// Listen for mission creation. // Listen for mission destruction.
onMissionCreated: function (mission) { onMissionDestroyed: function (mission) {
console.info("--------onMissionCreated-------") console.info("--------onMissionDestroyed-------")
}, },
// Listen for mission destruction. // Listen for mission snapshot changes.
onMissionDestroyed: function (mission) { onMissionSnapshotChanged: function (mission) {
console.info("--------onMissionDestroyed-------") console.info("--------onMissionSnapshotChanged-------")
}, },
// Listen for mission snapshot changes. // Listen for switching the mission to the foreground.
onMissionSnapshotChanged: function (mission) { onMissionMovedToFront: function (mission) {
console.info("--------onMissionSnapshotChanged-------") console.info("--------onMissionMovedToFront-------")
}, },
// Listen for switching the mission to the foreground. // Listen for mission icon changes.
onMissionMovedToFront: function (mission) { onMissionIconUpdated: function (mission, icon) {
console.info("--------onMissionMovedToFront-------") console.info("--------onMissionIconUpdated-------")
}, },
// Listen for mission icon changes. // Listen for mission name changes.
onMissionIconUpdated: function (mission, icon) { onMissionLabelUpdated: function (mission) {
console.info("--------onMissionIconUpdated-------") console.info("--------onMissionLabelUpdated-------")
}, },
// Listen for mission name changes. // Listen for mission closure events.
onMissionLabelUpdated: function (mission) { onMissionClosed: function (mission) {
console.info("--------onMissionLabelUpdated-------") console.info("--------onMissionClosed-------")
}, }
// Listen for mission closure events. };
onMissionClosed: function (mission) {
console.info("--------onMissionClosed-------") // 1. Register a mission change listener.
} let listenerId = missionManager.on('mission', listener);
};
// 2. Obtain the latest 20 missions in the system.
// 1. Register a mission change listener. missionManager.getMissionInfos("", 20, (error, missions) => {
let listenerId = missionManager.on('mission', listener); console.info("getMissionInfos is called, error.code = " + error.code);
console.info("size = " + missions.length);
// 2. Obtain the latest 20 missions in the system. console.info("missions = " + JSON.stringify(missions));
missionManager.getMissionInfos("", 20, (error, missions) => { });
console.info("getMissionInfos is called, error.code = " + error.code);
console.info("size = " + missions.length); // 3. Obtain the detailed information about a mission.
console.info("missions = " + JSON.stringify(missions)); let missionId = 11; // The mission ID 11 is only an example.
}); let mission = missionManager.getMissionInfo("", missionId).catch(function (err) {
console.info(err);
// 3. Obtain the detailed information about a mission. });
let missionId = 11; // The mission ID 11 is only an example.
let mission = missionManager.getMissionInfo("", missionId).catch(function (err) { // 4. Obtain the mission snapshot.
console.info(err); missionManager.getMissionSnapShot("", missionId, (error, snapshot) => {
}); console.info("getMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
// 4. Obtain the mission snapshot. })
missionManager.getMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getMissionSnapShot is called, error.code = " + error.code); // 5. Obtain the low-resolution mission snapshot.
console.info("bundleName = " + snapshot.ability.bundleName); missionManager.getLowResolutionMissionSnapShot("", missionId, (error, snapshot) => {
}) console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
// 5. Obtain the low-resolution mission snapshot. })
missionManager.getLowResolutionMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code); // 6. Lock or unlock the mission.
console.info("bundleName = " + snapshot.ability.bundleName); missionManager.lockMission(missionId).then(() => {
}) console.info("lockMission is called ");
});
// 6. Lock or unlock the mission.
missionManager.lockMission(missionId).then(() => { missionManager.unlockMission(missionId).then(() => {
console.info("lockMission is called "); console.info("unlockMission is called ");
}); });
missionManager.unlockMission(missionId).then(() => { // 7. Switch the mission to the foreground.
console.info("unlockMission is called "); missionManager.moveMissionToFront(missionId).then(() => {
}); console.info("moveMissionToFront is called ");
});
// 7. Switch the mission to the foreground.
missionManager.moveMissionToFront(missionId).then(() => { // 8. Clear a single mission.
console.info("moveMissionToFront is called "); missionManager.clearMission(missionId).then(() => {
}); console.info("clearMission is called ");
});
// 8. Clear a single mission.
missionManager.clearMission(missionId).then(() => { // 9. Clear all missions.
console.info("clearMission is called "); missionManager.clearAllMissions().catch(function (err) {
}); console.info(err);
});
// 9. Clear all missions.
missionManager.clearAllMissions().catch(function (err) { // 10. Deregister the mission change listener.
console.info(err); missionManager.off('mission', listenerId, (error) => {
}); console.info("unregisterMissionListener");
})
// 10. Deregister the mission change listener. ```
missionManager.off('mission', listenerId, (error) => {
console.info("unregisterMissionListener");
})
```
...@@ -9,37 +9,7 @@ During application development, you must declare the required permission in the ...@@ -9,37 +9,7 @@ During application development, you must declare the required permission in the
To declare a permission in **config.json**, add **reqPermissions** under **module** and list the permission. To declare a permission in **config.json**, add **reqPermissions** under **module** and list the permission.
For example, to request the permission to access the calendar, perform the following steps:
For example, to declare the permission to access the calendar, request the **ohos.permission.READ_CALENDAR** permission. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). 1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
The sample code in the **config.json** file is as follows:
```json
{
"module": {
// ...
"reqPermissions": [
{
"name": "ohos.permission.READ_CALENDAR"
// ...
}
]
}
}
```
Request the permission from uses in the form of a dialog box:
```ts
import featureAbility from '@ohos.ability.featureAbility';
let context = featureAbility.getContext();
let permissions: Array<string> = ['ohos.permission.READ_CALENDAR']
context.requestPermissionsFromUser(permissions, 1).then((data) => {
console.info("Succeed to request permission from user with data: " + JSON.stringify(data))
}).catch((error) => {
console.info("Failed to request permission from user with error: " + JSON.stringify(error))
})
```
...@@ -80,7 +80,7 @@ Before using the APIs provided by **EventHub**, you must obtain an **EventHub** ...@@ -80,7 +80,7 @@ Before using the APIs provided by **EventHub**, you must obtain an **EventHub**
4. After **event1** is used, you can call [eventHub.off()](../reference/apis/js-apis-inner-application-eventHub.md#eventhuboff) to unsubscribe from the event. 4. After **event1** is used, you can call [eventHub.off()](../reference/apis/js-apis-inner-application-eventHub.md#eventhuboff) to unsubscribe from the event.
```ts ```ts
// context is the ability-level context of the UIAbility instance. // context is the AbilityContext of the UIAbility instance.
this.context.eventHub.off('event1'); this.context.eventHub.off('event1');
``` ```
...@@ -240,10 +240,6 @@ The following provides an example to describe the object overwritten problem in ...@@ -240,10 +240,6 @@ The following provides an example to describe the object overwritten problem in
struct Index { struct Index {
onPageShow() { onPageShow() {
let ctx = globalThis.context; // Obtain the context from globalThis and use it. let ctx = globalThis.context; // Obtain the context from globalThis and use it.
let permissions = ['com.example.permission']
ctx.requestPermissionsFromUser(permissions,(result) => {
// ...
});
} }
// Page display. // Page display.
build() { build() {
...@@ -251,7 +247,7 @@ The following provides an example to describe the object overwritten problem in ...@@ -251,7 +247,7 @@ The following provides an example to describe the object overwritten problem in
} }
} }
``` ```
3. In the UIAbilityB file, [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) is stored in **globalThis** and has the same name as that in the UIAbilityA file. 3. In the UIAbilityB file, [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) is stored in **globalThis** and has the same name as that in the UIAbilityA file.
```ts ```ts
...@@ -274,10 +270,6 @@ The following provides an example to describe the object overwritten problem in ...@@ -274,10 +270,6 @@ The following provides an example to describe the object overwritten problem in
struct Index { struct Index {
onPageShow() { onPageShow() {
let ctx = globalThis.context; // Obtain the context from globalThis and use it. let ctx = globalThis.context; // Obtain the context from globalThis and use it.
let permissions = ['com.example.permission']
ctx.requestPermissionsFromUser(permissions,(result) => {
console.info('requestPermissionsFromUser result:' + JSON.stringify(result));
});
} }
// Page display. // Page display.
build() { build() {
...@@ -285,7 +277,7 @@ The following provides an example to describe the object overwritten problem in ...@@ -285,7 +277,7 @@ The following provides an example to describe the object overwritten problem in
} }
} }
``` ```
5. Switch the UIAbilityB instance to the background and switch the UIAbilityA instance to the foreground. In this case, UIAbilityA will not enter the **onCreate()** lifecycle again. 5. Switch the UIAbilityB instance to the background and switch the UIAbilityA instance to the foreground. In this case, UIAbilityA will not enter the **onCreate()** lifecycle again.
```ts ```ts
...@@ -307,10 +299,6 @@ The following provides an example to describe the object overwritten problem in ...@@ -307,10 +299,6 @@ The following provides an example to describe the object overwritten problem in
struct Index { struct Index {
onPageShow() { onPageShow() {
let ctx = globalThis.context; // The context in globalThis is the context of UIAbilityB. let ctx = globalThis.context; // The context in globalThis is the context of UIAbilityB.
let permissions=['com.example.permission'];
ctx.requestPermissionsFromUser(permissions,(result) => { // Using this object causes a process breakdown.
console.info('requestPermissionsFromUser result:' + JSON.stringify(result));
});
} }
// Page display. // Page display.
build() { build() {
......
...@@ -19,7 +19,7 @@ This topic describes the UIAbility interaction modes in the following scenarios. ...@@ -19,7 +19,7 @@ This topic describes the UIAbility interaction modes in the following scenarios.
- [Starting a Specified Page of UIAbility](#starting-a-specified-page-of-uiability) - [Starting a Specified Page of UIAbility](#starting-a-specified-page-of-uiability)
- [Using Ability Call to Implement UIAbility Interaction (for System Applications Only)](#using-ability-call-to-implement-uiability-interaction-for-system-applications-only) - [Using Call to Implement UIAbility Interaction (for System Applications Only)](#using-call-to-implement-uiability-interaction-for-system-applications-only)
## Starting UIAbility in the Same Application ## Starting UIAbility in the Same Application
...@@ -31,45 +31,52 @@ Assume that your application has two UIAbility components: EntryAbility and Func ...@@ -31,45 +31,52 @@ Assume that your application has two UIAbility components: EntryAbility and Func
1. In EntryAbility, call [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to start UIAbility. The [want](../reference/apis/js-apis-app-ability-want.md) parameter is the entry parameter for starting the UIAbility instance. In the **want** parameter, **bundleName** indicates the bundle name of the application to start; **abilityName** indicates the name of the UIAbility to start; **moduleName** is required only when the target UIAbility belongs to a different module; **parameters** is used to carry custom information. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). 1. In EntryAbility, call [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to start UIAbility. The [want](../reference/apis/js-apis-app-ability-want.md) parameter is the entry parameter for starting the UIAbility instance. In the **want** parameter, **bundleName** indicates the bundle name of the application to start; **abilityName** indicates the name of the UIAbility to start; **moduleName** is required only when the target UIAbility belongs to a different module; **parameters** is used to carry custom information. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability).
```ts ```ts
let context = ...; // UIAbilityContext
let wantInfo = { let wantInfo = {
deviceId: '', // An empty deviceId indicates the local device. deviceId: '', // An empty deviceId indicates the local device.
bundleName: 'com.example.myapplication', bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility', abilityName: 'FuncAbility',
moduleName: 'module1', // moduleName is optional. moduleName: 'module1', // moduleName is optional.
parameters: {// Custom information. parameters: {// Custom information.
info: 'From the Index page of EntryAbility', info: 'From the Index page of EntryAbility',
}, },
} }
// context is the ability-level context of the initiator UIAbility. // context is the UIAbilityContext of the initiator UIAbility.
this.context.startAbility(wantInfo).then(() => { context.startAbility(wantInfo).then(() => {
// ... // ...
}).catch((err) => { }).catch((err) => {
// ... // ...
}) })
``` ```
2. Use the FuncAbility lifecycle callback to receive the parameters passed from EntryAbility. 2. In FuncAbility, use [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) or [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonnewwant) to receive the parameters passed in by EntryAbility.
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window'; import window from '@ohos.window';
export default class FuncAbility extends UIAbility { export default class FuncAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
// Receive the parameters passed by the caller UIAbility. // Receive the parameters passed by the initiator UIAbility.
let funcAbilityWant = want; let funcAbilityWant = want;
let info = funcAbilityWant?.parameters?.info; let info = funcAbilityWant?.parameters?.info;
// ... // ...
} }
} }
``` ```
> **NOTE**<br>
>
> In FuncAbility started, you can obtain the PID and bundle name of the UIAbility through **parameters** in the passed **want** parameter.
3. To stop the **UIAbility** instance after the FuncAbility service is complete, call [terminateSelf()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateself) in FuncAbility. 3. To stop the **UIAbility** instance after the FuncAbility service is complete, call [terminateSelf()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateself) in FuncAbility.
```ts ```ts
// context is the ability-level context of the UIAbility instance to stop. let context = ...; // UIAbilityContext
this.context.terminateSelf((err) => {
// ... // context is the UIAbilityContext of the UIAbility instance to stop.
context.terminateSelf((err) => {
// ...
}); });
``` ```
...@@ -87,67 +94,70 @@ When starting FuncAbility from EntryAbility, you want the result to be returned ...@@ -87,67 +94,70 @@ When starting FuncAbility from EntryAbility, you want the result to be returned
1. In EntryAbility, call [startAbilityForResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to start FuncAbility. Use **data** in the asynchronous callback to receive information returned after FuncAbility stops itself. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). 1. In EntryAbility, call [startAbilityForResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to start FuncAbility. Use **data** in the asynchronous callback to receive information returned after FuncAbility stops itself. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability).
```ts ```ts
let context = ...; // UIAbilityContext
let wantInfo = { let wantInfo = {
deviceId: '', // An empty deviceId indicates the local device. deviceId: '', // An empty deviceId indicates the local device.
bundleName: 'com.example.myapplication', bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility', abilityName: 'FuncAbility',
moduleName: 'module1', // moduleName is optional. moduleName: 'module1', // moduleName is optional.
parameters: {// Custom information. parameters: {// Custom information.
info: 'From the Index page of EntryAbility', info: 'From the Index page of EntryAbility',
}, },
} }
// context is the ability-level context of the initiator UIAbility. // context is the UIAbilityContext of the initiator UIAbility.
this.context.startAbilityForResult(wantInfo).then((data) => { context.startAbilityForResult(wantInfo).then((data) => {
// ... // ...
}).catch((err) => { }).catch((err) => {
// ... // ...
}) })
``` ```
2. Call [terminateSelfWithResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to stop FuncAbility. Use the input parameter **abilityResult** to carry the information that FuncAbility needs to return to EntryAbility. 2. Call [terminateSelfWithResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to stop FuncAbility. Use the input parameter **abilityResult** to carry the information that FuncAbility needs to return to EntryAbility.
```ts ```ts
let context = ...; // UIAbilityContext
const RESULT_CODE: number = 1001; const RESULT_CODE: number = 1001;
let abilityResult = { let abilityResult = {
resultCode: RESULT_CODE, resultCode: RESULT_CODE,
want: { want: {
bundleName: 'com.example.myapplication', bundleName: 'com.example.myapplication',
abilityName: 'FuncAbility', abilityName: 'FuncAbility',
moduleName: 'module1', moduleName: 'module1',
parameters: { parameters: {
info: 'From the Index page of FuncAbility', info: 'From the Index page of FuncAbility',
},
}, },
},
} }
// context is the ability-level context of the callee UIAbility. // context is the AbilityContext of the target UIAbility.
this.context.terminateSelfWithResult(abilityResult, (err) => { context.terminateSelfWithResult(abilityResult, (err) => {
// ... // ...
}); });
``` ```
3. After FuncAbility stops itself, EntryAbility uses [startAbilityForResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to receive the information returned by FuncAbility. The value of **RESULT_CODE** must be the same as the preceding value. 3. After FuncAbility stops itself, EntryAbility uses [startAbilityForResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to receive the information returned by FuncAbility. The value of **RESULT_CODE** must be the same as the preceding value.
```ts ```ts
let context = ...; // UIAbilityContext
const RESULT_CODE: number = 1001; const RESULT_CODE: number = 1001;
// ... // ...
// context is the ability-level context of the initiator UIAbility. // context is the UIAbilityContext of the initiator UIAbility.
this.context.startAbilityForResult(want).then((data) => { context.startAbilityForResult(wantInfo).then((data) => {
if (data?.resultCode === RESULT_CODE) { if (data?.resultCode === RESULT_CODE) {
// Parse the information returned by the callee UIAbility. // Parse the information returned by the target UIAbility.
let info = data.want?.parameters?.info; let info = data.want?.parameters?.info;
// ...
}
}).catch((err) => {
// ... // ...
}
}).catch((err) => {
// ...
}) })
``` ```
## Starting UIAbility of Another Application ## Starting UIAbility of Another Application
Generally, the user only needs to do a common operation (for example, selecting a document application to view the document content) to start the UIAbility of another application. The [implicit Want launch mode](want-overview.md#types-of-want) is recommended. The system identifies a matched UIAbility and starts it based on the **want** parameter of the caller. Generally, the user only needs to do a common operation (for example, selecting a document application to view the document content) to start the UIAbility of another application. The [implicit Want launch mode](want-overview.md#types-of-want) is recommended. The system identifies a matched UIAbility and starts it based on the **want** parameter of the initiator UIAbility.
There are two ways to start **UIAbility**: [explicit and implicit](want-overview.md). There are two ways to start **UIAbility**: [explicit and implicit](want-overview.md).
...@@ -183,35 +193,38 @@ This section describes how to start the UIAbility of another application through ...@@ -183,35 +193,38 @@ This section describes how to start the UIAbility of another application through
} }
``` ```
2. Include **entities** and **actions** of the caller's **want** parameter into **entities** and **actions** under **skills** of the target UIAbility. After the system matches the UIAbility that meets the **entities** and **actions** information, a dialog box is displayed, showing the list of matched UIAbility instances for users to select. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). 2. Include **entities** and **actions** of the initiator UIAbility's **want** parameter into **entities** and **actions** under **skills** of the target UIAbility. After the system matches the UIAbility that meets the **entities** and **actions** information, a dialog box is displayed, showing the list of matched UIAbility instances for users to select. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability).
```ts ```ts
let context = ...; // UIAbilityContext
let wantInfo = { let wantInfo = {
deviceId: '', // An empty deviceId indicates the local device. deviceId: '', // An empty deviceId indicates the local device.
// Uncomment the line below if you want to implicitly query data only in the specific bundle. // Uncomment the line below if you want to implicitly query data only in the specific bundle.
// bundleName: 'com.example.myapplication', // bundleName: 'com.example.myapplication',
action: 'ohos.want.action.viewData', action: 'ohos.want.action.viewData',
// entities can be omitted. // entities can be omitted.
entities: ['entity.system.default'], entities: ['entity.system.default'],
} }
// context is the ability-level context of the initiator UIAbility. // context is the UIAbilityContext of the initiator UIAbility.
this.context.startAbility(wantInfo).then(() => { context.startAbility(wantInfo).then(() => {
// ... // ...
}).catch((err) => { }).catch((err) => {
// ... // ...
}) })
``` ```
The following figure shows the effect. When you click **Open PDF**, a dialog box is displayed for you to select. The following figure shows the effect. When you click **Open PDF**, a dialog box is displayed for you to select.
![](figures/uiability-intra-device-interaction.png) ![](figures/uiability-intra-device-interaction.png)
3. To stop the **UIAbility** instance after the document application is used, call [terminateSelf()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateself). 3. To stop the **UIAbility** instance after the document application is used, call [terminateSelf()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateself).
```ts ```ts
// context is the ability-level context of the UIAbility instance to stop. let context = ...; // UIAbilityContext
this.context.terminateSelf((err) => {
// ... // context is the AbilityContext of the UIAbility instance to stop.
context.terminateSelf((err) => {
// ...
}); });
``` ```
...@@ -246,65 +259,68 @@ If you want to obtain the return result when using implicit Want to start the UI ...@@ -246,65 +259,68 @@ If you want to obtain the return result when using implicit Want to start the UI
} }
``` ```
2. Call [startAbilityForResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to start the UIAbility of the payment application. Include **entities** and **actions** of the caller's **want** parameter into **entities** and **actions** under **skills** of the target UIAbility. Use **data** in the asynchronous callback to receive the information returned to the caller after the payment UIAbility stops itself. After the system matches the UIAbility that meets the **entities** and **actions** information, a dialog box is displayed, showing the list of matched UIAbility instances for users to select. 2. Call [startAbilityForResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to start the UIAbility of the payment application. Include **entities** and **actions** of the initiator UIAbility's **want** parameter into **entities** and **actions** under **skills** of the target UIAbility. Use **data** in the asynchronous callback to receive the information returned to the initiator UIAbility after the payment UIAbility stops itself. After the system matches the UIAbility that meets the **entities** and **actions** information, a dialog box is displayed, showing the list of matched UIAbility instances for users to select.
```ts ```ts
let context = ...; // UIAbilityContext
let wantInfo = { let wantInfo = {
deviceId: '', // An empty deviceId indicates the local device. deviceId: '', // An empty deviceId indicates the local device.
// Uncomment the line below if you want to implicitly query data only in the specific bundle. // Uncomment the line below if you want to implicitly query data only in the specific bundle.
// bundleName: 'com.example.myapplication', // bundleName: 'com.example.myapplication',
action: 'ohos.want.action.editData', action: 'ohos.want.action.editData',
// entities can be omitted. // entities can be omitted.
entities: ['entity.system.default'], entities: ['entity.system.default'],
} }
// context is the ability-level context of the initiator UIAbility. // context is the UIAbilityContext of the initiator UIAbility.
this.context.startAbilityForResult(wantInfo).then((data) => { context.startAbilityForResult(wantInfo).then((data) => {
// ... // ...
}).catch((err) => { }).catch((err) => {
// ... // ...
}) })
``` ```
3. After the payment is finished, call [terminateSelfWithResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to stop the payment UIAbility and return the **abilityResult** parameter. 3. After the payment is finished, call [terminateSelfWithResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) to stop the payment UIAbility and return the **abilityResult** parameter.
```ts ```ts
let context = ...; // UIAbilityContext
const RESULT_CODE: number = 1001; const RESULT_CODE: number = 1001;
let abilityResult = { let abilityResult = {
resultCode: RESULT_CODE, resultCode: RESULT_CODE,
want: { want: {
bundleName: 'com.example.myapplication', bundleName: 'com.example.myapplication',
abilityName: 'EntryAbility', abilityName: 'EntryAbility',
moduleName: 'entry', moduleName: 'entry',
parameters: { parameters: {
payResult: 'OKay', payResult: 'OKay',
},
}, },
},
} }
// context is the ability-level context of the callee UIAbility. // context is the AbilityContext of the target UIAbility.
this.context.terminateSelfWithResult(abilityResult, (err) => { context.terminateSelfWithResult(abilityResult, (err) => {
// ... // ...
}); });
``` ```
4. Receive the information returned by the payment application in the callback of the [startAbilityForResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) method. The value of **RESULT_CODE** must be the same as that returned by [terminateSelfWithResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult). 4. Receive the information returned by the payment application in the callback of the [startAbilityForResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult) method. The value of **RESULT_CODE** must be the same as that returned by [terminateSelfWithResult()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextterminateselfwithresult).
```ts ```ts
let context = ...; // UIAbilityContext
const RESULT_CODE: number = 1001; const RESULT_CODE: number = 1001;
let want = { let want = {
// Want parameter information. // Want parameter information.
}; };
// context is the ability-level context of the initiator UIAbility. // context is the UIAbilityContext of the initiator UIAbility.
this.context.startAbilityForResult(want).then((data) => { context.startAbilityForResult(want).then((data) => {
if (data?.resultCode === RESULT_CODE) { if (data?.resultCode === RESULT_CODE) {
// Parse the information returned by the callee UIAbility. // Parse the information returned by the target UIAbility.
let payResult = data.want?.parameters?.payResult; let payResult = data.want?.parameters?.payResult;
// ...
}
}).catch((err) => {
// ... // ...
}
}).catch((err) => {
// ...
}) })
``` ```
...@@ -323,7 +339,7 @@ The window mode is specified by the **windowMode** field in the [StartOptions](. ...@@ -323,7 +339,7 @@ The window mode is specified by the **windowMode** field in the [StartOptions](.
> **NOTE** > **NOTE**
> >
> 1. If the **windowMode** field is not specified, the UIAbility is started in the default window mode. > 1. If the **windowMode** field is not specified, the UIAbility is started in the default window mode.
> 2. To ensure that the application can be displayed in the required window mode, check the **supportWindowMode** field in the [abilities tag](../quick-start/module-configuration-file.md#abilities) in the [module.json5 file](../quick-start/module-configuration-file.md) of the UIAbility and make sure the specified window mode is supported. > 2. To ensure that the application can be displayed in the required window mode, check the **supportWindowMode** field in the [abilities](../quick-start/module-configuration-file.md#abilities) tag in the [module.json5 file](../quick-start/module-configuration-file.md) of the UIAbility and make sure the specified window mode is supported.
The following uses the floating window mode as an example to describe how to start the FuncAbility from the EntryAbility page. The following uses the floating window mode as an example to describe how to start the FuncAbility from the EntryAbility page.
...@@ -335,6 +351,7 @@ For details about how to obtain the context, see [Obtaining the Context of UIAbi ...@@ -335,6 +351,7 @@ For details about how to obtain the context, see [Obtaining the Context of UIAbi
```ts ```ts
import AbilityConstant from '@ohos.app.ability.AbilityConstant'; import AbilityConstant from '@ohos.app.ability.AbilityConstant';
let context = ...; // UIAbilityContext
let wantInfo = { let wantInfo = {
deviceId: '', // An empty deviceId indicates the local device. deviceId: '', // An empty deviceId indicates the local device.
bundleName: 'com.example.myapplication', bundleName: 'com.example.myapplication',
...@@ -347,8 +364,8 @@ let wantInfo = { ...@@ -347,8 +364,8 @@ let wantInfo = {
let options = { let options = {
windowMode: AbilityConstant.WindowMode.WINDOW_MODE_FLOATING windowMode: AbilityConstant.WindowMode.WINDOW_MODE_FLOATING
} }
// context is the ability-level context of the initiator UIAbility. // context is the UIAbilityContext of the initiator UIAbility.
this.context.startAbility(wantInfo, options).then(() => { context.startAbility(wantInfo, options).then(() => {
// ... // ...
}).catch((err) => { }).catch((err) => {
// ... // ...
...@@ -365,10 +382,11 @@ A UIAbility component can have multiple pages. When it is started in different s ...@@ -365,10 +382,11 @@ A UIAbility component can have multiple pages. When it is started in different s
### Specifying a Startup Page ### Specifying a Startup Page
When the caller UIAbility starts another UIAbility, it usually needs to redirect to a specified page. For example, FuncAbility contains two pages: Index (corresponding to the home page) and Second (corresponding to function A page). You can configure the specified page URL in the **want** parameter by adding a custom parameter to **parameters** in **want**. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). When the initiator UIAbility starts another UIAbility, it usually needs to redirect to a specified page. For example, FuncAbility contains two pages: Index (corresponding to the home page) and Second (corresponding to function A page). You can configure the specified page URL in the **want** parameter by adding a custom parameter to **parameters** in **want**. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability).
```ts ```ts
let context = ...; // UIAbilityContext
let wantInfo = { let wantInfo = {
deviceId: '', // An empty deviceId indicates the local device. deviceId: '', // An empty deviceId indicates the local device.
bundleName: 'com.example.myapplication', bundleName: 'com.example.myapplication',
...@@ -378,8 +396,8 @@ let wantInfo = { ...@@ -378,8 +396,8 @@ let wantInfo = {
router: 'funcA', router: 'funcA',
}, },
} }
// context is the ability-level context of the initiator UIAbility. // context is the UIAbilityContext of the initiator UIAbility.
this.context.startAbility(wantInfo).then(() => { context.startAbility(wantInfo).then(() => {
// ... // ...
}).catch((err) => { }).catch((err) => {
// ... // ...
...@@ -397,25 +415,25 @@ import UIAbility from '@ohos.app.ability.UIAbility' ...@@ -397,25 +415,25 @@ import UIAbility from '@ohos.app.ability.UIAbility'
import Window from '@ohos.window' import Window from '@ohos.window'
export default class FuncAbility extends UIAbility { export default class FuncAbility extends UIAbility {
funcAbilityWant; funcAbilityWant;
onCreate(want, launchParam) { onCreate(want, launchParam) {
// Receive the parameters passed by the caller UIAbility. // Receive the parameters passed by the initiator UIAbility.
this.funcAbilityWant = want; this.funcAbilityWant = want;
} }
onWindowStageCreate(windowStage: Window.WindowStage) { onWindowStageCreate(windowStage: Window.WindowStage) {
// Main window is created. Set a main page for this ability. // Main window is created. Set a main page for this UIAbility.
let url = 'pages/Index'; let url = 'pages/Index';
if (this.funcAbilityWant?.parameters?.router) { if (this.funcAbilityWant?.parameters?.router) {
if (this.funcAbilityWant.parameters.router === 'funA') { if (this.funcAbilityWant.parameters.router === 'funA') {
url = 'pages/Second'; url = 'pages/Second';
} }
}
windowStage.loadContent(url, (err, data) => {
// ...
});
} }
windowStage.loadContent(url, (err, data) => {
// ...
});
}
} }
``` ```
...@@ -434,11 +452,11 @@ In summary, when a UIAbility instance of application A has been created and the ...@@ -434,11 +452,11 @@ In summary, when a UIAbility instance of application A has been created and the
import UIAbility from '@ohos.app.ability.UIAbility' import UIAbility from '@ohos.app.ability.UIAbility'
export default class FuncAbility extends UIAbility { export default class FuncAbility extends UIAbility {
onNewWant(want, launchParam) { onNewWant(want, launchParam) {
// Receive the parameters passed by the caller UIAbility. // Receive the parameters passed by the initiator UIAbility.
globalThis.funcAbilityWant = want; globalThis.funcAbilityWant = want;
// ... // ...
} }
} }
``` ```
...@@ -469,215 +487,200 @@ In summary, when a UIAbility instance of application A has been created and the ...@@ -469,215 +487,200 @@ In summary, when a UIAbility instance of application A has been created and the
> **NOTE** > **NOTE**
> >
> When the [launch type of the callee UIAbility](uiability-launch-type.md) is set to **standard**, a new instance is created each time the callee UIAbility is started. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback will not be invoked. > When the [launch type of the target UIAbility](uiability-launch-type.md) is set to **standard**, a new instance is created each time the target UIAbility is started. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback will not be invoked.
## Using Ability Call to Implement UIAbility Interaction (for System Applications Only) ## Using Call to Implement UIAbility Interaction (for System Applications Only)
Ability call is an extension of the UIAbility capability. It enables the UIAbility to be invoked by and communicate with external systems. The UIAbility invoked can be either started in the foreground or created and run in the background. You can use the ability call to implement data sharing between two UIAbility instances (caller ability and callee ability) through IPC. Call is an extension of the UIAbility capability. It enables the UIAbility to be invoked by and communicate with external systems. The UIAbility invoked can be either started in the foreground or created and run in the background. You can use the call to implement data sharing between two UIAbility instances (CallerAbility and CalleeAbility) through IPC.
The core API used for the ability call is **startAbilityByCall**, which differs from **startAbility** in the following ways: The core API used for the call is **startAbilityByCall**, which differs from **startAbility** in the following ways:
- **startAbilityByCall** supports ability launch in the foreground and background, whereas **startAbility** supports ability launch in the foreground only. - **startAbilityByCall** supports UIAbility launch in the foreground and background, whereas **startAbility** supports UIAbility launch in the foreground only.
- The caller ability can use the caller object returned by **startAbilityByCall** to communicate with the callee ability, but **startAbility** does not provide the communication capability. - The CallerAbility can use the caller object returned by **startAbilityByCall** to communicate with the CalleeAbility, but **startAbility** does not provide the communication capability.
Ability call is usually used in the following scenarios: Call is usually used in the following scenarios:
- Communicating with the callee ability - Communicating with the CalleeAbility
- Starting the callee ability in the background - Starting the CalleeAbility in the background
**Table 1** Terms used in the ability call **Table 1** Terms used in the call
| **Term**| Description| | **Term**| Description|
| -------- | -------- | | -------- | -------- |
| CallerAbility | UIAbility that triggers the ability call.| | CallerAbility| UIAbility that triggers the call.|
| CalleeAbility | UIAbility invoked by the ability call.| | CalleeAbility | UIAbility invoked by the call.|
| Caller | Object returned by **startAbilityByCall** and used by the caller ability to communicate with the callee ability.| | Caller | Object returned by **startAbilityByCall** and used by the CallerAbility to communicate with the CalleeAbility.|
| Callee | Object held by the callee ability to communicate with the caller ability.| | Callee | Object held by the CalleeAbility to communicate with the CallerAbility.|
The following figure shows the ability call process. The following figure shows the call process.
Figure 1 Ability call process Figure 1 Call process
![call](figures/call.png) ![call](figures/call.png)
- The caller ability uses **startAbilityByCall** to obtain a caller object and uses **call()** of the caller object to send data to the callee ability. - The CallerAbility uses **startAbilityByCall** to obtain a caller object and uses **call()** of the caller object to send data to the CalleeAbility.
- The callee ability, which holds a **Callee** object, uses **on()** of the **Callee** object to register a callback. This callback is invoked when the callee ability receives data from the caller ability. - The CalleeAbility, which holds a **Callee** object, uses **on()** of the **Callee** object to register a callback. This callback is invoked when the CalleeAbility receives data from the CallerAbility.
> **NOTE** > **NOTE**
> 1. Currently, only system applications can use the ability call. > 1. Currently, only system applications can use the call.
> >
> 2. The launch type of the callee ability must be **singleton**. > 2. The launch type of the CalleeAbility must be **singleton**.
> >
> 3. Both local (intra-device) and cross-device ability calls are supported. The following describes how to initiate a local call. For details about how to initiate a cross-device ability call, see [Using Cross-Device Ability Call](hop-multi-device-collaboration.md#using-cross-device-ability-call). > 3. Both local (intra-device) and cross-device calls are supported. The following describes how to initiate a local call. For details about how to initiate a cross-device call, see [Using Cross-Device Call](hop-multi-device-collaboration.md#using-cross-device-call).
### Available APIs ### Available APIs
The following table describes the main APIs used for the ability call. For details, see [AbilityContext](../reference/apis/js-apis-app-ability-uiAbility.md#caller). The following table describes the main APIs used for the call. For details, see [AbilityContext](../reference/apis/js-apis-app-ability-uiAbility.md#caller).
**Table 2** Ability call APIs **Table 2** Call APIs
| API| Description| | API| Description|
| -------- | -------- | | -------- | -------- |
| startAbilityByCall(want: Want): Promise&lt;Caller&gt; | Starts a UIAbility in the foreground (through the **want** configuration) or background (default) and obtains the caller object for communication with the UIAbility. For details, see [AbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilitybycall) or [ServiceExtensionContext](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartabilitybycall).| | startAbilityByCall(want: Want): Promise&lt;Caller&gt; | Starts a UIAbility in the foreground (through the **want** configuration) or background (default) and obtains the caller object for communication with the UIAbility. For details, see [AbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilitybycall) or [ServiceExtensionContext](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartabilitybycall).|
| on(method: string, callback: CalleeCallBack): void | Callback invoked when the callee ability registers a method.| | on(method: string, callback: CalleeCallBack): void | Callback invoked when the CalleeAbility registers a method.|
| off(method: string): void | Callback invoked when the callee ability deregisters a method.| | off(method: string): void | Callback invoked when the CalleeAbility deregisters a method.|
| call(method: string, data: rpc.Parcelable): Promise&lt;void&gt; | Sends agreed parcelable data to the callee ability.| | call(method: string, data: rpc.Parcelable): Promise&lt;void&gt; | Sends agreed parcelable data to the CalleeAbility.|
| callWithResult(method: string, data: rpc.Parcelable): Promise&lt;rpc.MessageSequence&gt; | Sends agreed parcelable data to the callee ability and obtains the agreed parcelable data returned by the callee ability.| | callWithResult(method: string, data: rpc.Parcelable): Promise&lt;rpc.MessageSequence&gt; | Sends agreed parcelable data to the CalleeAbility and obtains the agreed parcelable data returned by the CalleeAbility.|
| release(): void | Releases the caller object.| | release(): void | Releases the caller object.|
| on(type: "release", callback: OnReleaseCallback): void | Callback invoked when the caller object is released.| | on(type: "release", callback: OnReleaseCallback): void | Callback invoked when the caller object is released.|
The implementation of using the ability call for UIAbility interaction involves two parts. The implementation of using the call for UIAbility interaction involves two parts.
- [Creating a Callee Ability](#creating-a-callee-ability) - [Creating a CalleeAbility](#creating-a-calleeability)
- [Accessing the Callee Ability](#accessing-the-callee-ability) - [Accessing the CalleeAbility](#accessing-the-calleeability)
### Creating a Callee Ability ### Creating a CalleeAbility
For the callee ability, implement the callback to receive data and the methods to marshal and unmarshal data. When data needs to be received, use **on()** to register a listener. When data does not need to be received, use **off()** to deregister the listener. For the CalleeAbility, implement the callback to receive data and the methods to marshal and unmarshal data. When data needs to be received, use **on()** to register a listener. When data does not need to be received, use **off()** to deregister the listener.
1. Configure the ability launch type. 1. Configure the launch type of the UIAbility.
Set **launchType** of the callee ability to **singleton** in the **module.json5** file.
| JSON Field| Description| For example, set the launch type of the CalleeAbility to **singleton**. For details, see [UIAbility Component Launch Type](uiability-launch-type.md).
| -------- | -------- |
| "launchType" | Ability launch type. Set this parameter to **singleton**.|
An example of the ability configuration is as follows:
```json
"abilities":[{
"name": ".CalleeAbility",
"srcEntrance": "./ets/CalleeAbility/CalleeAbility.ts",
"launchType": "singleton",
"description": "$string:CalleeAbility_desc",
"icon": "$media:icon",
"label": "$string:CalleeAbility_label",
"visible": true
}]
```
2. Import the **UIAbility** module. 2. Import the **UIAbility** module.
```ts ```ts
import Ability from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
``` ```
3. Define the agreed parcelable data. 3. Define the agreed parcelable data.
The data formats sent and received by the caller and callee abilities must be consistent. In the following example, the data formats are number and string. The data formats sent and received by the CallerAbility and CalleeAbility must be consistent. In the following example, the data formats are number and string.
```ts ```ts
export default class MyParcelable { export default class MyParcelable {
num: number = 0 num: number = 0;
str: string = "" str: string = '';
constructor(num, string) { constructor(num, string) {
this.num = num this.num = num;
this.str = string this.str = string;
} }
marshalling(messageSequence) { marshalling(messageSequence) {
messageSequence.writeInt(this.num) messageSequence.writeInt(this.num);
messageSequence.writeString(this.str) messageSequence.writeString(this.str);
return true return true
} }
unmarshalling(messageSequence) { unmarshalling(messageSequence) {
this.num = messageSequence.readInt() this.num = messageSequence.readInt();
this.str = messageSequence.readString() this.str = messageSequence.readString();
return true return true;
} }
} }
``` ```
4. Implement **Callee.on** and **Callee.off**. 4. Implement **Callee.on** and **Callee.off**.
The time to register a listener for the callee ability depends on your application. The data sent and received before the listener is registered and that after the listener is deregistered are not processed. In the following example, the **MSG_SEND_METHOD** listener is registered in **onCreate** of the ability and deregistered in **onDestroy**. After receiving parcelable data, the application processes the data and returns the data result. You need to implement processing based on service requirements. The sample code is as follows: The time to register a listener for the CalleeAbility depends on your application. The data sent and received before the listener is registered and that after the listener is deregistered are not processed. In the following example, the **MSG_SEND_METHOD** listener is registered in **onCreate** of the UIAbility and deregistered in **onDestroy**. After receiving parcelable data, the application processes the data and returns the data result. You need to implement processing based on service requirements. The sample code is as follows:
```ts ```ts
const TAG: string = '[CalleeAbility]'; const TAG: string = '[CalleeAbility]';
const MSG_SEND_METHOD: string = 'CallSendMsg'; const MSG_SEND_METHOD: string = 'CallSendMsg';
function sendMsgCallback(data) { function sendMsgCallback(data) {
console.info('CalleeSortFunc called'); console.info('CalleeSortFunc called');
// Obtain the parcelable data sent by the caller ability. // Obtain the parcelable data sent by the CallerAbility.
let receivedData = new MyParcelable(0, ''); let receivedData = new MyParcelable(0, '');
data.readParcelable(receivedData); data.readParcelable(receivedData);
console.info(`receiveData[${receivedData.num}, ${receivedData.str}]`); console.info(`receiveData[${receivedData.num}, ${receivedData.str}]`);
// Process the data. // Process the data.
// Return the parcelable data result to the caller ability. // Return the parcelable data result to the CallerAbility.
return new MyParcelable(receivedData.num + 1, `send ${receivedData.str} succeed`); return new MyParcelable(receivedData.num + 1, `send ${receivedData.str} succeed`);
} }
export default class CalleeAbility extends Ability { export default class CalleeAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
try { try {
this.callee.on(MSG_SEND_METHOD, sendMsgCallback); this.callee.on(MSG_SEND_METHOD, sendMsgCallback);
} catch (error) { } catch (error) {
console.info(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`); console.info(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`);
}
} }
}
onDestroy() { onDestroy() {
try { try {
this.callee.off(MSG_SEND_METHOD); this.callee.off(MSG_SEND_METHOD);
} catch (error) { } catch (error) {
console.error(TAG, `${MSG_SEND_METHOD} unregister failed with error ${JSON.stringify(error)}`); console.error(TAG, `${MSG_SEND_METHOD} unregister failed with error ${JSON.stringify(error)}`);
}
} }
}
} }
``` ```
### Accessing the Callee Ability
### Accessing the CalleeAbility
1. Import the **UIAbility** module. 1. Import the **UIAbility** module.
```ts ```ts
import Ability from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
``` ```
2. Obtain the caller interface. 2. Obtain the caller interface.
The **context** attribute of the ability implements **startAbilityByCall** to obtain the caller object for communication. The following example uses **this.context** to obtain the **context** attribute of the ability, uses **startAbilityByCall** to start the callee ability, obtain the caller object, and register the **onRelease** listener of the caller ability. You need to implement processing based on service requirements. The **UIAbilityContext** attribute implements **startAbilityByCall** to obtain the caller object for communication. The following example uses **this.context** to obtain the **UIAbilityContext**, uses **startAbilityByCall** to start the CalleeAbility, obtain the caller object, and register the **onRelease** listener of the CallerAbility. You need to implement processing based on service requirements.
```ts ```ts
// Register the onRelease() listener of the caller ability. // Register the onRelease() listener of the CallerAbility.
private regOnRelease(caller) { private regOnRelease(caller) {
try { try {
caller.on("release", (msg) => { caller.on('release', (msg) => {
console.info(`caller onRelease is called ${msg}`); console.info(`caller onRelease is called ${msg}`);
}) })
console.info('caller register OnRelease succeed'); console.info('caller register OnRelease succeed');
} catch (error) { } catch (error) {
console.info(`caller register OnRelease failed with ${error}`); console.info(`caller register OnRelease failed with ${error}`);
} }
} }
async onButtonGetCaller() { async onButtonGetCaller() {
try { try {
this.caller = await context.startAbilityByCall({ this.caller = await context.startAbilityByCall({
bundleName: 'com.samples.CallApplication', bundleName: 'com.samples.CallApplication',
abilityName: 'CalleeAbility' abilityName: 'CalleeAbility'
}) })
if (this.caller === undefined) { if (this.caller === undefined) {
console.info('get caller failed') console.info('get caller failed')
return return
}
console.info('get caller success')
this.regOnRelease(this.caller)
} catch (error) {
console.info(`get caller failed with ${error}`)
} }
console.info('get caller success')
this.regOnRelease(this.caller)
} catch (error) {
console.info(`get caller failed with ${error}`)
}
} }
``` ```
...@@ -17,10 +17,13 @@ The launch type of the UIAbility component refers to the state of the UIAbility ...@@ -17,10 +17,13 @@ The launch type of the UIAbility component refers to the state of the UIAbility
Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, if a UIAbility instance of this type already exists in the application process, the instance is reused. Therefore, only one UIAbility instance of this type exists in the system, that is, displayed in **Recents**. Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, if a UIAbility instance of this type already exists in the application process, the instance is reused. Therefore, only one UIAbility instance of this type exists in the system, that is, displayed in **Recents**.
**Figure 1** Demonstration effect in singleton mode **Figure 1** Demonstration effect in singleton mode
![uiability-launch-type1](figures/uiability-launch-type1.png) ![uiability-launch-type1](figures/uiability-launch-type1.png)
> **NOTE**<br>Assume that the application already has a UIAbility instance created, and the launch type of the UIAbility instance is set to **singleton**. If [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called again to start the UIAbility instance, the original UIAbility instance is started, and no new UIAbility instance is created. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback is invoked, but the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks are not. > **NOTE**
>
> Assume that the application already has a UIAbility instance created, and the launch type of the UIAbility instance is set to **singleton**. If [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called again to start the UIAbility instance, the original UIAbility instance is started, and no new UIAbility instance is created. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback is invoked, but the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks are not.
To use the singleton mode, set **launchType** in the [module.json5 configuration file](../quick-start/module-configuration-file.md) to **singleton**. To use the singleton mode, set **launchType** in the [module.json5 configuration file](../quick-start/module-configuration-file.md) to **singleton**.
...@@ -44,7 +47,8 @@ To use the singleton mode, set **launchType** in the [module.json5 configuration ...@@ -44,7 +47,8 @@ To use the singleton mode, set **launchType** in the [module.json5 configuration
In standard mode, each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, a new UIAbility instance of this type is created in the application process. Multiple UIAbility instances of this type are displayed in **Recents**. In standard mode, each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, a new UIAbility instance of this type is created in the application process. Multiple UIAbility instances of this type are displayed in **Recents**.
**Figure 2** Demonstration effect in standard mode **Figure 2** Demonstration effect in standard mode
![standard-mode](figures/standard-mode.png) ![standard-mode](figures/standard-mode.png)
To use the standard mode, set **launchType** in the [module.json5 configuration file](../quick-start/module-configuration-file.md) to **standard**. To use the standard mode, set **launchType** in the [module.json5 configuration file](../quick-start/module-configuration-file.md) to **standard**.
...@@ -69,7 +73,8 @@ To use the standard mode, set **launchType** in the [module.json5 configuration ...@@ -69,7 +73,8 @@ To use the standard mode, set **launchType** in the [module.json5 configuration
The **specified** mode is used in some special scenarios. For example, in a document application, you want a document instance to be created each time you create a document, but you want to use the same document instance when you repeatedly open an existing document. The **specified** mode is used in some special scenarios. For example, in a document application, you want a document instance to be created each time you create a document, but you want to use the same document instance when you repeatedly open an existing document.
**Figure 3** Demonstration effect in specified mode **Figure 3** Demonstration effect in specified mode
![uiability-launch-type2](figures/uiability-launch-type2.png) ![uiability-launch-type2](figures/uiability-launch-type2.png)
For example, there are two UIAbility components: EntryAbility and SpecifiedAbility (with the launch type **specified**). You are required to start SpecifiedAbility from EntryAbility. For example, there are two UIAbility components: EntryAbility and SpecifiedAbility (with the launch type **specified**). You are required to start SpecifiedAbility from EntryAbility.
...@@ -108,7 +113,7 @@ For example, there are two UIAbility components: EntryAbility and SpecifiedAbili ...@@ -108,7 +113,7 @@ For example, there are two UIAbility components: EntryAbility and SpecifiedAbili
instanceKey: getInstance(), instanceKey: getInstance(),
}, },
} }
// context is the ability-level context of the initiator UIAbility. // context is the UIAbilityContext of the initiator UIAbility.
this.context.startAbility(want).then(() => { this.context.startAbility(want).then(() => {
// ... // ...
}).catch((err) => { }).catch((err) => {
...@@ -137,7 +142,7 @@ For example, there are two UIAbility components: EntryAbility and SpecifiedAbili ...@@ -137,7 +142,7 @@ For example, there are two UIAbility components: EntryAbility and SpecifiedAbili
} }
``` ```
> **NOTE**<br> > **NOTE**
> >
> 1. Assume that the application already has a UIAbility instance created, and the launch type of the UIAbility instance is set to **specified**. If [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called again to start the UIAbility instance, and the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback of [AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md) matches a created UIAbility instance, the original UIAbility instance is started, and no new UIAbility instance is created. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback is invoked, but the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks are not. > 1. Assume that the application already has a UIAbility instance created, and the launch type of the UIAbility instance is set to **specified**. If [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called again to start the UIAbility instance, and the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback of [AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md) matches a created UIAbility instance, the original UIAbility instance is started, and no new UIAbility instance is created. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback is invoked, but the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks are not.
> 2. AbilityStage is not automatically generated in the default project of DevEco Studio. For details about how to create an AbilityStage file, see [AbilityStage Component Container](abilitystage.md). > 2. AbilityStage is not automatically generated in the default project of DevEco Studio. For details about how to create an AbilityStage file, see [AbilityStage Component Container](abilitystage.md).
......
...@@ -5,21 +5,21 @@ ...@@ -5,21 +5,21 @@
The agent-powered reminder feature provides APIs for publishing background reminders. You can call these APIs to create scheduled reminders for countdown timers, calendar events, and alarm clocks. The APIs are encapsulated in the [reminderAgentManager](../reference/apis/js-apis-reminderAgentManager.md) class. The agent-powered reminder feature provides APIs for publishing background reminders. You can call these APIs to create scheduled reminders for countdown timers, calendar events, and alarm clocks. The APIs are encapsulated in the [reminderAgentManager](../reference/apis/js-apis-reminderAgentManager.md) class.
**Table 1** Major APIs in reminderAgentManager **Table 1** Major APIs in reminderAgentManager
| API | Description | | API | Description |
| ---------------------------------------- | ---------------------------------------- | | ------------------------------------------------------------ | ------------------------------------------------------------ |
| publishReminder(reminderReq: ReminderRequest, callback: AsyncCallback&lt;number&gt;): void<br>publishReminder(reminderReq: ReminderRequest): Promise&lt;number&gt; | Publishes a scheduled reminder.<br>The maximum number of valid notifications (excluding expired ones that will not pop up again) is 30 for one application<br>and 2000 for the entire system.| | publishReminder(reminderReq: ReminderRequest, callback: AsyncCallback&lt;number&gt;): void<br>publishReminder(reminderReq: ReminderRequest): Promise&lt;number&gt; | Publishes a scheduled reminder.<br>The maximum number of valid notifications (excluding expired ones that will not pop up again) is 30 for one application and 2000 for the entire system. |
| cancelReminder(reminderId: number, callback: AsyncCallback&lt;void&gt;): void<br>cancelReminder(reminderId: number): Promise&lt;void&gt; | Cancels a specified reminder. (The value of **reminderId** is obtained from the return value of **publishReminder**.)| | cancelReminder(reminderId: number, callback: AsyncCallback&lt;void&gt;): void<br>cancelReminder(reminderId: number): Promise&lt;void&gt; | Cancels a specified reminder. (The value of **reminderId** is obtained from the return value of **publishReminder**.) |
| getValidReminders(callback: AsyncCallback&lt;Array&lt;ReminderRequest&gt;&gt;): void<br>getValidReminders(): Promise&lt;Array&lt;ReminderRequest&gt;&gt; | Obtains all valid reminders set by the current application. | | getValidReminders(callback: AsyncCallback&lt;Array&lt;ReminderRequest&gt;&gt;): void<br>getValidReminders(): Promise&lt;Array&lt;ReminderRequest&gt;&gt; | Obtains all valid reminders set by the current application. |
| cancelAllReminders(callback: AsyncCallback&lt;void&gt;): void<br>cancelAllReminders(): Promise&lt;void&gt; | Cancels all reminders set by the current application. | | cancelAllReminders(callback: AsyncCallback&lt;void&gt;): void<br>cancelAllReminders(): Promise&lt;void&gt; | Cancels all reminders set by the current application. |
| addNotificationSlot(slot: NotificationSlot, callback: AsyncCallback&lt;void&gt;): void<br>addNotificationSlot(slot: NotificationSlot): Promise&lt;void&gt; | Registers a **NotificationSlot** instance to be used by the reminder. | | addNotificationSlot(slot: NotificationSlot, callback: AsyncCallback&lt;void&gt;): void<br>addNotificationSlot(slot: NotificationSlot): Promise&lt;void&gt; | Registers a **NotificationSlot** instance to be used by the reminder. |
| removeNotificationSlot(slotType: notification.SlotType, callback: AsyncCallback&lt;void&gt;): void<br>removeNotificationSlot(slotType: notification.SlotType): Promise&lt;void&gt; | Removes a **NotificationSlot** instance of a specified type. | | removeNotificationSlot(slotType: notification.SlotType, callback: AsyncCallback&lt;void&gt;): void<br>removeNotificationSlot(slotType: notification.SlotType): Promise&lt;void&gt; | Removes a **NotificationSlot** instance of a specified type. |
## How to Develop ## How to Develop
1. Request the **ohos.permission.PUBLISH_AGENT_REMINDER** permission. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). 1. Request the **ohos.permission.PUBLISH_AGENT_REMINDER** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
2. [Enable the notification feature](../notification/notification-enable.md). 2. [Enable the notification feature](../notification/notification-enable.md).
...@@ -95,7 +95,7 @@ The agent-powered reminder feature provides APIs for publishing background remin ...@@ -95,7 +95,7 @@ The agent-powered reminder feature provides APIs for publishing background remin
snoozeTimes: 2, // Number of reminder snooze times. snoozeTimes: 2, // Number of reminder snooze times.
timeInterval: 5, // Reminder snooze interval, in seconds. timeInterval: 5, // Reminder snooze interval, in seconds.
title: 'this is title', // Reminder title. title: 'this is title', // Reminder title.
content:'this is content', // Reminder content. content: 'this is content', // Reminder content.
expiredContent: 'this reminder has expired', // Content to be displayed after the reminder expires. expiredContent: 'this reminder has expired', // Content to be displayed after the reminder expires.
snoozeContent: 'remind later', // Content to be displayed when the reminder is snoozed. snoozeContent: 'remind later', // Content to be displayed when the reminder is snoozed.
notificationId: 100, // Notification ID used by the reminder. If there are reminders with the same notification ID, the later one will overwrite the earlier one. notificationId: 100, // Notification ID used by the reminder. If there are reminders with the same notification ID, the later one will overwrite the earlier one.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册