提交 87f8eb13 编写于 作者: G gongyuechen

Merge branch 'master' of https://gitee.com/gongyuechen/docs

Signed-off-by: Ngongyuechen <gongyuechen@huawei.com>

要显示的变更太多。

To preserve performance only 1000 of 1000+ files are displayed.
此差异已折叠。
...@@ -18,7 +18,7 @@ This repository stores device and application development documents provided by ...@@ -18,7 +18,7 @@ This repository stores device and application development documents provided by
- master: the latest version. - master: the latest version.
- OpenHarmony 3.2 Beta3. [Learn more](en/release-notes/OpenHarmony-v3.2-beta3.md) - OpenHarmony 3.2 Beta5. [Learn more](en/release-notes/OpenHarmony-v3.2-beta5.md)
- OpenHarmony 3.1 Release. [Learn more](en/release-notes/OpenHarmony-v3.1-release.md) - OpenHarmony 3.1 Release. [Learn more](en/release-notes/OpenHarmony-v3.1-release.md)
...@@ -34,7 +34,7 @@ This repository stores device and application development documents provided by ...@@ -34,7 +34,7 @@ This repository stores device and application development documents provided by
### Historical Stable Versions ### Historical Stable Versions
OpenHarmony_v1.x_release: OpenHarmony v1.1.5 LTS. [Learn more](en/release-notes/OpenHarmony-v1.1.5-LTS.md) OpenHarmony_v1.x_release: OpenHarmony 1.1.5 LTS. [Learn more](en/release-notes/OpenHarmony-v1.1.5-LTS.md)
[More versions](en/release-notes/) [More versions](en/release-notes/)
...@@ -51,6 +51,6 @@ You can evaluate available documents, make simple modifications, provide feedbac ...@@ -51,6 +51,6 @@ You can evaluate available documents, make simple modifications, provide feedbac
Excellent contributors will be awarded and the contributions will be publicized in the developer community. Excellent contributors will be awarded and the contributions will be publicized in the developer community.
- Mail list: docs@openharmony.io - Mailing list: docs@openharmony.io
- Zulip group: documentation_sig - Zulip group: documentation_sig
\ No newline at end of file
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
- master:最新开发版本。 - master:最新开发版本。
- OpenHarmony 3.2 Beta3版本:点击[此处](zh-cn/release-notes/OpenHarmony-v3.2-beta3.md)了解版本详情。 - OpenHarmony 3.2 Beta5版本:点击[此处](zh-cn/release-notes/OpenHarmony-v3.2-beta5.md)了解版本详情。
- OpenHarmony 3.1 Release版本:点击[此处](zh-cn/release-notes/OpenHarmony-v3.1-release.md)了解版本详情。 - OpenHarmony 3.1 Release版本:点击[此处](zh-cn/release-notes/OpenHarmony-v3.1-release.md)了解版本详情。
......
...@@ -127,7 +127,7 @@ The following table describes the subsystems of OpenHarmony. For details about t ...@@ -127,7 +127,7 @@ The following table describes the subsystems of OpenHarmony. For details about t
| Build | Provides a compilation and building framework based on Generate Ninja (GN) and Ninja. | All systems | | Build | Provides a compilation and building framework based on Generate Ninja (GN) and Ninja. | All systems |
| Test | The test-driven development mode is used during the development process. You can develop new cases or modify existing cases to test new or enhanced system features. The test helps you develop high-quality code in the development phase.| All systems | | Test | The test-driven development mode is used during the development process. You can develop new cases or modify existing cases to test new or enhanced system features. The test helps you develop high-quality code in the development phase.| All systems |
| Data Management | Provides local data management and distributed data management:<br>- Local application data management for lightweight preference databases and relational databases<br>- Distributed data service to provide applications with the capability to store data in the databases of different devices| Standard system | | Data Management | Provides local data management and distributed data management:<br>- Local application data management for lightweight preference databases and relational databases<br>- Distributed data service to provide applications with the capability to store data in the databases of different devices| Standard system |
| Programming Language Runtime| Provides the compilation and execution environment for programs developed with JavaScript or C/C++, basic libraries that support the runtime, and the runtime-associated APIs, compilers, and auxiliary tools.| All systems | | Compiler and Runtime | Provides the compilation and execution environment for programs developed with JavaScript or C/C++, basic libraries that support the runtime, and the runtime-associated APIs, compilers, and auxiliary tools.| All systems |
| Distributed Scheduler| Starts, registers, queries, and manages system services. | All systems | | Distributed Scheduler| Starts, registers, queries, and manages system services. | All systems |
| JS UI Framework | OpenHarmony JS UI framework supports web-development-like paradigm. | All systems | | JS UI Framework | OpenHarmony JS UI framework supports web-development-like paradigm. | All systems |
| Multimedia | Provides easy-to-use APIs for developing multimedia components such as audio, video, and camera, and enables applications to use multimedia resources of the system.| All systems | | Multimedia | Provides easy-to-use APIs for developing multimedia components such as audio, video, and camera, and enables applications to use multimedia resources of the system.| All systems |
...@@ -183,7 +183,7 @@ For details about how to obtain the source code of OpenHarmony, see [Source Code ...@@ -183,7 +183,7 @@ For details about how to obtain the source code of OpenHarmony, see [Source Code
## Hands-On Tutorials ## Hands-On Tutorials
[Samples](https://gitee.com/openharmony/app_samples) [Samples](https://gitee.com/openharmony/applications_app_samples)
[Codelabs](https://gitee.com/openharmony/codelabs) [Codelabs](https://gitee.com/openharmony/codelabs)
......
...@@ -2,52 +2,87 @@ ...@@ -2,52 +2,87 @@
- [Application Development Overview](application-dev-guide.md) - [Application Development Overview](application-dev-guide.md)
- About OpenHarmony - About OpenHarmony
- [OpenHarmony Project](../OpenHarmony-Overview.md) - [OpenHarmony Project](../OpenHarmony-Overview.md)
- [Glossary](../glossary.md) - [Glossary](../glossary.md)
- [OpenHarmony Release Notes](../release-notes/Readme.md) - [OpenHarmony Release Notes](../release-notes/Readme.md)
- Quick Start - Quick Start
- Getting Started - Getting Started
- [Preparations](quick-start/start-overview.md) - [Before You Start](quick-start/start-overview.md)
- [Getting Started with ArkTS in Stage Model](quick-start/start-with-ets-stage.md) - [Getting Started with ArkTS in Stage Model](quick-start/start-with-ets-stage.md)
- [Getting Started with ArkTS in FA Model](quick-start/start-with-ets-fa.md) - [Getting Started with ArkTS in FA Model](quick-start/start-with-ets-fa.md)
- [Getting Started with JavaScript in FA Model](quick-start/start-with-js-fa.md) - [Getting Started with JavaScript in FA Model](quick-start/start-with-js-fa.md)
- Development Fundamentals - Development Fundamentals
- [Application Package Structure Configuration File (FA Model)](quick-start/package-structure.md) - Application Package Fundamentals
- [Application Package Structure Configuration File (Stage Model)](quick-start/stage-structure.md) - [Application Package Overview](quick-start/application-package-overview.md)
- [SysCap](quick-start/syscap.md) - Application Package Structure
- [Application Package Structure in Stage Model)](quick-start/application-package-structure-stage.md)
- [Application Package Structure in FA Model](quick-start/application-package-structure-fa.md)
- Multi-HAP Mechanism
- [Multi-HAP Design Objectives](quick-start/multi-hap-objective.md)
- [Multi-HAP Build View](quick-start/multi-hap-build-view.md)
- [Multi-HAP Development, Debugging, Release, and Deployment Process](quick-start/multi-hap-release-deployment.md)
- [Multi-HAP Usage Rules](quick-start/multi-hap-rules.md)
- [Multi-HAP Operation Mechanism and Data Communication Modes](quick-start/multi-hap-principles.md)
- [Application Installation and Uninstallation Process](quick-start/application-package-install-uninstall.md)
- Application Configuration Files in Stage Model
- [Application Configuration File Overview (Stage Model)](quick-start/application-configuration-file-overview-stage.md)
- [app.json5 Configuration File](quick-start/app-configuration-file.md)
- [module.json5 Configuration File](quick-start/module-configuration-file.md)
- Application Configuration Files in FA Model
- [Application Configuration File Overview (FA Model)](quick-start/application-configuration-file-overview-fa.md)
- [Internal Structure of the app Tag](quick-start/app-structure.md)
- [Internal structure of deviceConfig Tag](quick-start/deviceconfig-structure.md)
- [Internal Structure of the module Tag](quick-start/module-structure.md)
- [Resource Categories and Access](quick-start/resource-categories-and-access.md)
- Learning ArkTS
- [Getting Started with ArkTS](quick-start/arkts-get-started.md)
- ArkTS Syntax (Declarative UI)
- [Basic UI Description](quick-start/arkts-basic-ui-description.md)
- State Management
- [Basic Concepts](quick-start/arkts-state-mgmt-concepts.md)
- [State Management with Page-level Variables](quick-start/arkts-state-mgmt-page-level.md)
- [State Management with Application-level Variables](quick-start/arkts-state-mgmt-application-level.md)
- [Dynamic UI Element Building](quick-start/arkts-dynamic-ui-elememt-building.md)
- [Rendering Control](quick-start/arkts-rendering-control.md)
- [Restrictions and Extensions](quick-start/arkts-restrictions-and-extensions.md)
- Development - Development
- [Ability Development](ability/Readme-EN.md) - [Application Models](application-models/Readme-EN.md)
- [UI Development](ui/Readme-EN.md) - [UI Development](ui/Readme-EN.md)
- [Common Event and Notification](notification/Readme-EN.md) - [Notification](notification/Readme-EN.md)
- [Window Manager](windowmanager/Readme-EN.md) - [Window Manager](windowmanager/Readme-EN.md)
- [WebGL](webgl/Readme-EN.md) - [WebGL](webgl/Readme-EN.md)
- [Media](media/Readme-EN.md) - [Media](media/Readme-EN.md)
- [Security](security/Readme-EN.md) - [Security](security/Readme-EN.md)
- [Connectivity](connectivity/Readme-EN.md) - [Connectivity](connectivity/Readme-EN.md)
- [Data Management](database/Readme-EN.md) - [Data Management](database/Readme-EN.md)
- [File Management](file-management/Readme-EN.md) - [File Management](file-management/Readme-EN.md)
- [Telephony](telephony/Readme-EN.md) - [Telephony Service](telephony/Readme-EN.md)
- [Task Management](task-management/Readme-EN.md) - [Task Management](task-management/Readme-EN.md)
- [Device Management](device/Readme-EN.md) - [Device Management](device/Readme-EN.md)
- [Device Usage Statistics](device-usage-statistics/Readme-EN.md) - [Device Usage Statistics](device-usage-statistics/Readme-EN.md)
- [DFX](dfx/Readme-EN.md) - [DFX](dfx/Readme-EN.md)
- [Internationalization](internationalization/Readme-EN.md) - [Internationalization](internationalization/Readme-EN.md)
- [OpenHarmony IDL Specifications and User Guide](IDL/idl-guidelines.md) - [Application Test](application-test/Readme-EN.md)
- [Using Native APIs in Application Projects](napi/Readme-EN.md) - [OpenHarmony IDL Specifications and User Guide](IDL/idl-guidelines.md)
- [Native APIs](napi/Readme-EN.md)
- Tools - Tools
- [DevEco Studio (OpenHarmony) User Guide](quick-start/deveco-studio-user-guide-for-openharmony.md) - [DevEco Studio (OpenHarmony) User Guide](quick-start/deveco-studio-user-guide-for-openharmony.md)
- [Debugging Tools](tools/Readme-EN.md)
- Hands-On Tutorials - Hands-On Tutorials
- [Samples](https://gitee.com/openharmony/applications_app_samples/blob/master/README.md) - [Samples](https://gitee.com/openharmony/applications_app_samples/blob/master/README.md)
- [Codelabs](https://gitee.com/openharmony/codelabs) - [Codelabs](https://gitee.com/openharmony/codelabs)
- API References - API References
- [Component Reference (JavaScript-based Web-like Development Paradigm)](reference/arkui-js/Readme-EN.md) - [SystemCapability](reference/syscap.md)
- [Component Reference (TypeScript-based Declarative Development Paradigm)](reference/arkui-ts/Readme-EN.md) - [SystemCapability List](reference/syscap-list.md)
- APIs - [Component Reference (TypeScript-based Declarative Development Paradigm)](reference/arkui-ts/Readme-EN.md)
- [JS and TS APIs](reference/apis/Readme-EN.md) - [Component Reference (JavaScript-based Web-like Development Paradigm)](reference/arkui-js/Readme-EN.md)
- Native APIs - [JS Service Widget UI Components](reference/js-service-widget-ui/Readme-EN.md)
- [Standard Libraries](reference/native-lib/third_party_libc/musl.md) - APIs
- [Node_API](reference/native-lib/third_party_napi/napi.md) - [ArkTS and JS APIs](reference/apis/Readme-EN.md)
- [Error Codes](reference/errorcodes/Readme-EN.md)
- Native APIs
- [Standard Libraries](reference/native-lib/third_party_libc/musl.md)
- [Node_API](reference/native-lib/third_party_napi/napi.md)
- [FAQs](faqs/Readme-EN.md) - [FAQs](faqs/Readme-EN.md)
- Contribution - Contribution
- [How to Contribute](../contribute/documentation-contribution.md) - [How to Contribute](../contribute/documentation-contribution.md)
...@@ -63,7 +63,7 @@ For details about how to use DevEco Studio to start the test framework, see [Ope ...@@ -63,7 +63,7 @@ For details about how to use DevEco Studio to start the test framework, see [Ope
**Example** **Example**
```javascript ```javascript
import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
function onAbilityCreateCallback(data) { function onAbilityCreateCallback(data) {
console.info("onAbilityCreateCallback"); console.info("onAbilityCreateCallback");
...@@ -87,11 +87,11 @@ abilityDelegator.addAbilityMonitor(monitor).then(() => { ...@@ -87,11 +87,11 @@ abilityDelegator.addAbilityMonitor(monitor).then(() => {
**Modules to Import** **Modules to Import**
```javascript ```javascript
import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
``` ```
```javascript ```javascript
var abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() var abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
``` ```
### Starting an Ability and Listening for the Ability State ### Starting an Ability and Listening for the Ability State
......
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
**Context** provides the capability of obtaining contextual information of an application. **Context** provides the capability of obtaining contextual information of an application.
The OpenHarmony application framework has two models: Feature Ability (FA) model and stage model. Correspondingly, there are two sets of context mechanisms. **application/BaseContext** is a common context base class. It uses the **stageMode** attribute to specify whether the context is used for the stage model. The OpenHarmony application framework has two models: Feature Ability (FA) model and stage model. Correspondingly, there are two sets of context mechanisms. **application/BaseContext** is a common context base class. It uses the **stageMode** attribute to specify whether the context is used for the stage model.
- FA model - FA model
Only the methods in **app/Context** can be used for the context in the FA model. Both the application-level context and ability-level context are instances of this type. If an ability-level method is invoked in the application-level context, an error occurs. Therefore, you must pay attention to the actual meaning of the **Context** instance. Only the methods in **app/Context** can be used for the context in the FA model. Both the application-level context and ability-level context are instances of this type. If an ability-level method is invoked in the application-level context, an error occurs. Therefore, you must pay attention to the actual meaning of the **Context** instance.
- Stage model - Stage model
...@@ -54,6 +54,7 @@ setDisplayOrientation(orientation: bundle.DisplayOrientation): Promise<void>; ...@@ -54,6 +54,7 @@ setDisplayOrientation(orientation: bundle.DisplayOrientation): Promise<void>;
The methods are used to set the display orientation of the current ability. The methods are used to set the display orientation of the current ability.
**Example** **Example**
```javascript ```javascript
import featureAbility from '@ohos.ability.featureAbility' import featureAbility from '@ohos.ability.featureAbility'
import bundle from '@ohos.bundle'; import bundle from '@ohos.bundle';
...@@ -96,13 +97,13 @@ Obtain the context by calling **context.getApplicationContext()** in **Ability** ...@@ -96,13 +97,13 @@ Obtain the context by calling **context.getApplicationContext()** in **Ability**
**Example** **Example**
```javascript ```javascript
import Ability from "@ohos.application.Ability"; import UIAbility from '@ohos.app.ability.UIAbility';
var lifecycleid; var lifecycleid;
export default class MainAbility extends Ability { export default class EntryAbility extends UIAbility {
onCreate() { onCreate() {
console.log("MainAbility onCreate") console.log("EntryAbility onCreate")
let AbilityLifecycleCallback = { let AbilityLifecycleCallback = {
onAbilityCreate(ability){ onAbilityCreate(ability){
console.log("AbilityLifecycleCallback onAbilityCreate ability:" + JSON.stringify(ability)); console.log("AbilityLifecycleCallback onAbilityCreate ability:" + JSON.stringify(ability));
...@@ -191,25 +192,25 @@ Obtain the context from the **context** attribute in **Ability**. ...@@ -191,25 +192,25 @@ Obtain the context from the **context** attribute in **Ability**.
**Example** **Example**
```javascript ```javascript
import Ability from '@ohos.application.Ability' import UIAbility from '@ohos.app.ability.UIAbility';
export default class MainAbility extends Ability { export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
console.log("[Demo] MainAbility onCreate") console.log("[Demo] EntryAbility onCreate")
globalThis.abilityWant = want; globalThis.abilityWant = want;
} }
onDestroy() { onDestroy() {
console.log("[Demo] MainAbility onDestroy") console.log("[Demo] EntryAbility onDestroy")
} }
onWindowStageCreate(windowStage) { onWindowStageCreate(windowStage) {
// Set the main page for this ability when the main window is created. // Set the main page for this ability when the main window is created.
console.log("[Demo] MainAbility onWindowStageCreate") console.log("[Demo] EntryAbility onWindowStageCreate")
// Obtain AbilityContext and print the ability information. // Obtain AbilityContext and print the ability information.
let context = this.context; let context = this.context;
console.log("[Demo] MainAbility bundleName " + context.abilityInfo.bundleName) console.log("[Demo] EntryAbility bundleName " + context.abilityInfo.bundleName)
windowStage.loadContent("pages/index", (err, data) => { windowStage.loadContent("pages/index", (err, data) => {
if (err.code) { if (err.code) {
...@@ -222,17 +223,17 @@ export default class MainAbility extends Ability { ...@@ -222,17 +223,17 @@ export default class MainAbility extends Ability {
onWindowStageDestroy() { onWindowStageDestroy() {
// Release the UI related resources when the main window is destroyed. // Release the UI related resources when the main window is destroyed.
console.log("[Demo] MainAbility onWindowStageDestroy") console.log("[Demo] EntryAbility onWindowStageDestroy")
} }
onForeground() { onForeground() {
// The ability is switched to run in the foreground. // The ability is switched to run in the foreground.
console.log("[Demo] MainAbility onForeground") console.log("[Demo] EntryAbility onForeground")
} }
onBackground() { onBackground() {
// The ability is switched to run in the background. // The ability is switched to run in the background.
console.log("[Demo] MainAbility onBackground") console.log("[Demo] EntryAbility onBackground")
} }
}; };
``` ```
...@@ -249,23 +250,23 @@ In the stage model, in the onWindowStageCreate lifecycle of an ability, you can ...@@ -249,23 +250,23 @@ In the stage model, in the onWindowStageCreate lifecycle of an ability, you can
Use the API described in the table below to obtain the context associated with an ArkTS page. Use the API described in the table below to obtain the context associated with an ArkTS page.
| API | Description | | API | Description |
| :------------------------------------ | :--------------------------- | | :------------------------------------ | :----------------------------------------------------------- |
| getContext(component: Object): Object | Obtains the **Context** object associated with a component on the page.| | getContext(component: Object): Object | Obtains the **Context** object associated with a component on the page.<br>Since API version 9, this API is supported in ArkTS widgets.|
**Example** **Example**
```ts ```ts
// MainAbility.ts // EntryAbility.ts
import Ability from '@ohos.application.Ability' import UIAbility from '@ohos.app.ability.UIAbility';
export default class MainAbility extends Ability { export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
console.log("[Demo] MainAbility onCreate") console.log("[Demo] EntryAbility onCreate")
} }
onDestroy() { onDestroy() {
console.log("[Demo] MainAbility onDestroy") console.log("[Demo] EntryAbility onDestroy")
} }
onWindowStageCreate(windowStage) { onWindowStageCreate(windowStage) {
...@@ -283,7 +284,7 @@ export default class MainAbility extends Ability { ...@@ -283,7 +284,7 @@ export default class MainAbility extends Ability {
```ts ```ts
// pages/index.ets // pages/index.ets
import context from '@ohos.application.context' import context from '@ohos.app.ability.context'
type Context = context.Context type Context = context.Context
......
...@@ -126,7 +126,7 @@ As the entry of the ability continuation capability, **continuationManager** is ...@@ -126,7 +126,7 @@ As the entry of the ability continuation capability, **continuationManager** is
if (needGrantPermission) { if (needGrantPermission) {
try { try {
// globalThis.context is Ability.context, which must be assigned a value in the MainAbility.ts file in advance. // globalThis.context is Ability.context, which must be assigned a value in the MainAbility.ts file in advance.
await globalThis.context.requestPermissionsFromUser(permissions); await atManger.requestPermissionsFromUser(globalThis.context, permissions);
} catch (err) { } catch (err) {
console.error('app permission request permissions error' + JSON.stringify(err)); console.error('app permission request permissions error' + JSON.stringify(err));
} }
...@@ -175,7 +175,7 @@ As the entry of the ability continuation capability, **continuationManager** is ...@@ -175,7 +175,7 @@ As the entry of the ability continuation capability, **continuationManager** is
let want = { let want = {
deviceId: remoteDeviceId, deviceId: remoteDeviceId,
bundleName: 'ohos.samples.continuationmanager', bundleName: 'ohos.samples.continuationmanager',
abilityName: 'MainAbility' abilityName: 'EntryAbility'
}; };
globalThis.abilityContext.startAbility(want).then((data) => { globalThis.abilityContext.startAbility(want).then((data) => {
console.info('StartRemoteAbility finished, ' + JSON.stringify(data)); console.info('StartRemoteAbility finished, ' + JSON.stringify(data));
......
...@@ -40,4 +40,4 @@ For details about the project directory structure of the FA model, see [OpenHarm ...@@ -40,4 +40,4 @@ For details about the project directory structure of the FA model, see [OpenHarm
For details about how to configure the application package structure of the FA model, see [Application Package Structure Configuration File](../quick-start/application-configuration-file-overview-fa.md). For details about how to configure the application package structure of the FA model, see [Application Package Structure Configuration File](../quick-start/application-configuration-file-overview-fa.md).
<!--no_check-->
\ No newline at end of file
...@@ -63,9 +63,9 @@ To create an FA widget, you need to implement lifecycle callbacks using the **Li ...@@ -63,9 +63,9 @@ To create an FA widget, you need to implement lifecycle callbacks using the **Li
1. Import the required modules. 1. Import the required modules.
```javascript ```javascript
import formBindingData from '@ohos.application.formBindingData' import formBindingData from '@ohos.app.form.formBindingData';
import formInfo from '@ohos.application.formInfo' import formInfo from '@ohos.app.form.formInfo';
import formProvider from '@ohos.application.formProvider' import formProvider from '@ohos.app.form.formProvider';
``` ```
2. Implement lifecycle callbacks for the widget. 2. Implement lifecycle callbacks for the widget.
...@@ -158,7 +158,7 @@ The widget configuration file is named **config.json**. Find the **config.json** ...@@ -158,7 +158,7 @@ The widget configuration file is named **config.json**. Find the **config.json**
| defaultDimension | Default grid style of the widget. The value must be available in the **supportDimensions** array of the widget.| String | No | | defaultDimension | Default grid style of the widget. The value must be available in the **supportDimensions** array of the widget.| String | No |
| updateEnabled | Whether the widget can be updated periodically.<br>**true**: The widget can be updated at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** takes precedence over **scheduledUpdateTime**.<br>**false**: The widget cannot be updated periodically.| Boolean | No | | updateEnabled | Whether the widget can be updated periodically.<br>**true**: The widget can be updated at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** takes precedence over **scheduledUpdateTime**.<br>**false**: The widget cannot be updated periodically.| Boolean | No |
| scheduledUpdateTime | Scheduled time to update the widget. The value is in 24-hour format and accurate to minute.<br>**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| String | Yes (initial value: **0:0**) | | scheduledUpdateTime | Scheduled time to update the widget. The value is in 24-hour format and accurate to minute.<br>**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| String | Yes (initial value: **0:0**) |
| updateDuration | Interval to update the widget. The value is a natural number, in the unit of 30 minutes.<br>If the value is **0**, this field does not take effect.<br>If the value is a positive integer ***N***, the interval is calculated by multiplying ***N*** and 30 minutes.<br>**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| Number | Yes (initial value: **0**) | | updateDuration | Interval to update the widget. The value is a natural number, in the unit of 30 minutes.<br>If the value is **0**, this field does not take effect.<br>If the value is a positive integer *N*, the interval is calculated by multiplying *N* and 30 minutes.<br>**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| Number | Yes (initial value: **0**) |
| formConfigAbility | Link to a specific page of the application. The value is a URI. | String | Yes (initial value: left empty) | | formConfigAbility | Link to a specific page of the application. The value is a URI. | String | Yes (initial value: left empty) |
| formVisibleNotify | Whether the widget is allowed to use the widget visibility notification. | String | Yes (initial value: left empty) | | formVisibleNotify | Whether the widget is allowed to use the widget visibility notification. | String | Yes (initial value: left empty) |
| jsComponentName | Component name of the widget. The value is a string with a maximum of 127 bytes. | String | No | | jsComponentName | Component name of the widget. The value is a string with a maximum of 127 bytes. | String | No |
...@@ -206,7 +206,7 @@ A widget provider is usually started when it is needed to provide information ab ...@@ -206,7 +206,7 @@ A widget provider is usually started when it is needed to provide information ab
let formId = want.parameters["ohos.extra.param.key.form_identity"]; let formId = want.parameters["ohos.extra.param.key.form_identity"];
let formName = want.parameters["ohos.extra.param.key.form_name"]; let formName = want.parameters["ohos.extra.param.key.form_name"];
let tempFlag = want.parameters["ohos.extra.param.key.form_temporary"]; let tempFlag = want.parameters["ohos.extra.param.key.form_temporary"];
// Persistently store widget information for subsequent use, such as widget instance retrieval or update. // Persistently store widget data for subsequent use, such as widget instance retrieval or update.
// The storeFormInfo API is not implemented here. // The storeFormInfo API is not implemented here.
storeFormInfo(formId, formName, tempFlag, want); storeFormInfo(formId, formName, tempFlag, want);
...@@ -231,9 +231,9 @@ You should override **onDestroy** to implement widget data deletion. ...@@ -231,9 +231,9 @@ You should override **onDestroy** to implement widget data deletion.
} }
``` ```
For details about how to implement persistence data storage, see [Lightweight Data Store Development](../database/database-preference-guidelines.md). For details about how to implement persistent data storage, see [Lightweight Data Store Development](../database/database-preference-guidelines.md).
The **Want** passed by the widget host to the widget provider contains a flag that specifies whether the requested widget is normal or temporary. The **Want** object passed in by the widget host to the widget provider contains a flag that specifies whether the requested widget is normal or temporary.
- Normal widget: a widget persistently used by the widget host - Normal widget: a widget persistently used by the widget host
...@@ -254,14 +254,14 @@ onUpdate(formId) { ...@@ -254,14 +254,14 @@ onUpdate(formId) {
"detail": "detailOnUpdate" "detail": "detailOnUpdate"
}; };
let formData = formBindingData.createFormBindingData(obj); let formData = formBindingData.createFormBindingData(obj);
// Call the updateForm method to update the widget. Only the data passed through the input parameter is updated. Other information remains unchanged. // Call the updateForm() method to update the widget. Only the data passed through the input parameter is updated. Other information remains unchanged.
formProvider.updateForm(formId, formData).catch((error) => { formProvider.updateForm(formId, formData).catch((error) => {
console.log('FormAbility updateForm, error:' + JSON.stringify(error)); console.log('FormAbility updateForm, error:' + JSON.stringify(error));
}); });
} }
``` ```
### Developing Widget UI Pages ### Developing the Widget UI Page
You can use HML, CSS, and JSON to develop the UI page for a JavaScript-programmed widget. You can use HML, CSS, and JSON to develop the UI page for a JavaScript-programmed widget.
...@@ -335,7 +335,7 @@ You can use HML, CSS, and JSON to develop the UI page for a JavaScript-programme ...@@ -335,7 +335,7 @@ You can use HML, CSS, and JSON to develop the UI page for a JavaScript-programme
"actions": { "actions": {
"routerEvent": { "routerEvent": {
"action": "router", "action": "router",
"abilityName": "com.example.entry.MainAbility", "abilityName": "com.example.entry.EntryAbility",
"params": { "params": {
"message": "add detail" "message": "add detail"
} }
...@@ -353,12 +353,12 @@ Now you've got a widget shown below. ...@@ -353,12 +353,12 @@ Now you've got a widget shown below.
You can set router and message events for components on a widget. The router event applies to ability redirection, and the message event applies to custom click events. The key steps are as follows: You can set router and message events for components on a widget. The router event applies to ability redirection, and the message event applies to custom click events. The key steps are as follows:
1. Set the **onclick** field in the HML file to **routerEvent** or **messageEvent**, depending on the **actions** settings in the JSON file. 1. Set the **onclick** field in the HML file to **routerEvent** or **messageEvent**, depending on the **actions** settings in the JSON file.
2. For the router event, set the following attributes: 2. Set the router event.
- **action**: **router**, which indicates a router event. - **action**: **"router"**, which indicates a router event.
- **abilityName**: target ability name, for example, **com.example.entry.MainAbility**, which is the default main ability name in DevEco Studio for the FA model. - **abilityName**: target ability name, for example, **com.example.entry.EntryAbility**, which is the default UIAbility name in DevEco Studio for the FA model.
- **params**: custom parameters of the target ability. Set them as required. The value can be obtained from **parameters** in **want** used for starting the target ability. For example, in the lifecycle function **onCreate** of the main ability in the FA model, **featureAbility.getWant()** can be used to obtain **want** and its **parameters** field. - **params**: custom parameters of the target ability. Set them as required. The value can be obtained from **parameters** in **want** used for starting the target ability. For example, in the lifecycle function **onCreate** of the EntryAbility in the FA model, **featureAbility.getWant()** can be used to obtain **want** and its **parameters** field.
3. For the message event, set the following attributes: 3. Set the message event.
- **action**: **message**, which indicates a message event. - **action**: **"message"**, which indicates a message event.
- **params**: custom parameters of the message event. Set them as required. The value can be obtained from **message** in the widget lifecycle function **onEvent**. - **params**: custom parameters of the message event. Set them as required. The value can be obtained from **message** in the widget lifecycle function **onEvent**.
The code snippet is as follows: The code snippet is as follows:
...@@ -388,7 +388,7 @@ The code snippet is as follows: ...@@ -388,7 +388,7 @@ The code snippet is as follows:
"actions": { "actions": {
"routerEvent": { "routerEvent": {
"action": "router", "action": "router",
"abilityName": "com.example.entry.MainAbility", "abilityName": "com.example.entry.EntryAbility",
"params": { "params": {
"message": "add detail" "message": "add detail"
} }
...@@ -401,4 +401,4 @@ The code snippet is as follows: ...@@ -401,4 +401,4 @@ The code snippet is as follows:
} }
} }
} }
``` ```
\ No newline at end of file
...@@ -135,13 +135,13 @@ Obtain **deviceId** from **DeviceManager**. The sample code is as follows: ...@@ -135,13 +135,13 @@ Obtain **deviceId** from **DeviceManager**. The sample code is as follows:
if (typeof dmClass === 'object' && dmClass != null) { if (typeof dmClass === 'object' && dmClass != null) {
let list = dmClass.getTrustedDeviceListSync(); let list = dmClass.getTrustedDeviceListSync();
if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') { if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null"); console.log("EntryAbility onButtonClick getRemoteDeviceId err: list is null");
return; return;
} }
console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId); console.log("EntryAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId);
return list[0].deviceId; return list[0].deviceId;
} else { } else {
console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null"); console.log("EntryAbility onButtonClick getRemoteDeviceId err: dmClass is null");
} }
} }
``` ```
......
...@@ -24,8 +24,6 @@ The differences between **onCommand()** and **onConnect()** are as follows: ...@@ -24,8 +24,6 @@ The differences between **onCommand()** and **onConnect()** are as follows:
1. Override the Service ability-related lifecycle callbacks to implement your own logic for processing interaction requests. 1. Override the Service ability-related lifecycle callbacks to implement your own logic for processing interaction requests.
```ts ```ts
export default { export default {
onStart() { onStart() {
...@@ -47,7 +45,7 @@ The differences between **onCommand()** and **onConnect()** are as follows: ...@@ -47,7 +45,7 @@ The differences between **onCommand()** and **onConnect()** are as follows:
} }
} }
``` ```
2. Register a Service ability. 2. Register a Service ability.
Declare the Service ability in the **config.json** file by setting its **type** attribute to **service**. Declare the Service ability in the **config.json** file by setting its **type** attribute to **service**.
...@@ -155,7 +153,7 @@ You can use either of the following methods to connect to a Service ability: ...@@ -155,7 +153,7 @@ You can use either of the following methods to connect to a Service ability:
```ts ```ts
import prompt from '@system.prompt' import prompt from '@system.prompt'
var option = { var option = {
onConnect: function onConnectCallback(element, proxy) { onConnect: function onConnectCallback(element, proxy) {
console.log(`onConnectLocalService onConnectDone`); console.log(`onConnectLocalService onConnectDone`);
...@@ -194,7 +192,7 @@ You can use either of the following methods to connect to a Service ability: ...@@ -194,7 +192,7 @@ You can use either of the following methods to connect to a Service ability:
```ts ```ts
import featureAbility from '@ohos.ability.featureAbility' import featureAbility from '@ohos.ability.featureAbility'
let want = { let want = {
bundleName: "com.jstest.service", bundleName: "com.jstest.service",
abilityName: "com.jstest.service.ServiceAbility" abilityName: "com.jstest.service.ServiceAbility"
...@@ -208,7 +206,7 @@ You can use either of the following methods to connect to a Service ability: ...@@ -208,7 +206,7 @@ You can use either of the following methods to connect to a Service ability:
```ts ```ts
import rpc from "@ohos.rpc" import rpc from "@ohos.rpc"
class ServiceAbilityStub extends rpc.RemoteObject { class ServiceAbilityStub extends rpc.RemoteObject {
constructor(des: any) { constructor(des: any) {
if (typeof des === 'string') { if (typeof des === 'string') {
...@@ -218,7 +216,7 @@ You can use either of the following methods to connect to a Service ability: ...@@ -218,7 +216,7 @@ You can use either of the following methods to connect to a Service ability:
return; return;
} }
} }
onRemoteRequest(code: number, data: any, reply: any, option: any) { onRemoteRequest(code: number, data: any, reply: any, option: any) {
console.log("onRemoteRequest called"); console.log("onRemoteRequest called");
// Execute the service logic. // Execute the service logic.
...@@ -235,7 +233,7 @@ You can use either of the following methods to connect to a Service ability: ...@@ -235,7 +233,7 @@ You can use either of the following methods to connect to a Service ability:
return true; return true;
} }
} }
export default { export default {
onStart() { onStart() {
console.log('ServiceAbility onStart'); console.log('ServiceAbility onStart');
......
...@@ -127,7 +127,7 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar ...@@ -127,7 +127,7 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar
if (needGrantPermission) { if (needGrantPermission) {
Logger.info("app permission needGrantPermission") Logger.info("app permission needGrantPermission")
try { try {
await this.context.requestPermissionsFromUser(permissions) await accessManger.requestPermissionsFromUser(this.context, permissions)
} catch (err) { } catch (err) {
Logger.error(`app permission ${JSON.stringify(err)}`) Logger.error(`app permission ${JSON.stringify(err)}`)
} }
...@@ -147,8 +147,8 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar ...@@ -147,8 +147,8 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar
Modules to import: Modules to import:
```javascript ```javascript
import Ability from '@ohos.application.Ability'; import UIAbility from '@ohos.app.ability.UIAbility';
import AbilityConstant from '@ohos.application.AbilityConstant'; import AbilityConstant from '@ohos.app.ability.AbilityConstant';
``` ```
To implement ability continuation, you must implement this API and have the value **AGREE** returned. To implement ability continuation, you must implement this API and have the value **AGREE** returned.
...@@ -185,14 +185,14 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar ...@@ -185,14 +185,14 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar
Example Example
```javascript ```javascript
import Ability from '@ohos.application.Ability'; import UIAbility from '@ohos.app.ability.UIAbility';
import distributedObject from '@ohos.data.distributedDataObject'; import distributedObject from '@ohos.data.distributedDataObject';
export default class MainAbility extends Ability { export default class EntryAbility extends UIAbility {
storage : LocalStorag; storage : LocalStorag;
onCreate(want, launchParam) { onCreate(want, launchParam) {
Logger.info(`MainAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`) Logger.info(`EntryAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`)
if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) { if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) {
// Obtain the user data from the want parameter. // Obtain the user data from the want parameter.
let workInput = want.parameters.work let workInput = want.parameters.work
...@@ -207,8 +207,6 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar ...@@ -207,8 +207,6 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar
``` ```
For a singleton ability, use **onNewWant()** to achieve the same implementation. For a singleton ability, use **onNewWant()** to achieve the same implementation.
### Data Continuation ### Data Continuation
Use distributed objects. Use distributed objects.
...@@ -220,12 +218,12 @@ In the ability continuation scenario, the distributed data object is used to syn ...@@ -220,12 +218,12 @@ In the ability continuation scenario, the distributed data object is used to syn
- In **onContinue()**, the initiator saves the data to be migrated to the distributed object, calls the **save()** API to save the data and synchronize the data to the target device, sets the session ID, and sends the session ID to the target device through **wantParam**. - In **onContinue()**, the initiator saves the data to be migrated to the distributed object, calls the **save()** API to save the data and synchronize the data to the target device, sets the session ID, and sends the session ID to the target device through **wantParam**.
```javascript ```javascript
import Ability from '@ohos.application.Ability'; import UIAbility from '@ohos.app.ability.UIAbility';
import distributedObject from '@ohos.data.distributedDataObject'; import distributedObject from '@ohos.data.distributedDataObject';
var g_object = distributedObject.createDistributedObject({data:undefined}); var g_object = distributedObject.createDistributedObject({data:undefined});
export default class MainAbility extends Ability { export default class EntryAbility extends UIAbility {
sessionId : string; sessionId : string;
onContinue(wantParam : {[key: string]: any}) { onContinue(wantParam : {[key: string]: any}) {
...@@ -256,34 +254,33 @@ In the ability continuation scenario, the distributed data object is used to syn ...@@ -256,34 +254,33 @@ In the ability continuation scenario, the distributed data object is used to syn
- The target device obtains the session ID from **onCreate()**, creates a distributed object, and associates the distributed object with the session ID. In this way, the distributed object can be synchronized. Before calling **restoreWindowStage**, ensure that all distributed objects required for continuation have been associated. - The target device obtains the session ID from **onCreate()**, creates a distributed object, and associates the distributed object with the session ID. In this way, the distributed object can be synchronized. Before calling **restoreWindowStage**, ensure that all distributed objects required for continuation have been associated.
```javascript ```javascript
import Ability from '@ohos.application.Ability'; import UIAbility from '@ohos.app.ability.UIAbility';
import distributedObject from '@ohos.data.distributedDataObject'; import distributedObject from '@ohos.data.distributedDataObject';
var g_object = distributedObject.createDistributedObject({data:undefined}); var g_object = distributedObject.createDistributedObject({data:undefined});
export default class MainAbility extends Ability { export default class EntryAbility extends UIAbility {
storage : LocalStorag; storage : LocalStorag;
onCreate(want, launchParam) {
Logger.info(`EntryAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`)
if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) {
// Obtain the session ID of the distributed data object from the want parameter.
this.sessionId = want.parameters.session
Logger.info(`onCreate for continuation sessionId: ${this.sessionId}`)
onCreate(want, launchParam) { // Before fetching data from the remote device, reset g_object.data to undefined.
Logger.info(`MainAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`) g_object.data = undefined;
if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) { // Set the session ID, so the target will fetch data from the remote device.
// Obtain the session ID of the distributed data object from the want parameter. g_object.setSessionId(this.sessionId);
this.sessionId = want.parameters.session
Logger.info(`onCreate for continuation sessionId: ${this.sessionId}`)
// Before fetching data from the remote device, reset g_object.data to undefined. AppStorage.SetOrCreate<string>('ContinueStudy', g_object.data)
g_object.data = undefined; this.storage = new LocalStorage();
// Set the session ID, so the target will fetch data from the remote device. this.context.restoreWindowStage(this.storage);
g_object.setSessionId(this.sessionId); }
AppStorage.SetOrCreate<string>('ContinueStudy', g_object.data) }
this.storage = new LocalStorage(); }
this.context.restoreWindowStage(this.storage);
}
}
}
``` ```
...@@ -309,5 +306,3 @@ In the ability continuation scenario, the distributed data object is used to syn ...@@ -309,5 +306,3 @@ In the ability continuation scenario, the distributed data object is used to syn
### Best Practice ### Best Practice
For better user experience, you are advised to use the **wantParam** parameter to transmit data smaller than 100 KB and use distributed objects to transmit data larger than 100 KB. For better user experience, you are advised to use the **wantParam** parameter to transmit data smaller than 100 KB and use distributed objects to transmit data larger than 100 KB.
<!--no_check-->
\ No newline at end of file
...@@ -56,8 +56,8 @@ The table below describes the APIs provided by the **Ability** class. For detail ...@@ -56,8 +56,8 @@ The table below describes the APIs provided by the **Ability** class. For detail
### Implementing AbilityStage and Ability Lifecycle Callbacks ### Implementing AbilityStage and Ability Lifecycle Callbacks
To create Page abilities for an application in the stage model, you must implement the **AbilityStage** class and ability lifecycle callbacks, and use the **Window** class to set the pages. The sample code is as follows: To create Page abilities for an application in the stage model, you must implement the **AbilityStage** class and ability lifecycle callbacks, and use the **Window** class to set the pages. The sample code is as follows:
1. Import the **AbilityStage** module. 1. Import the **AbilityStage** module.
``` ```ts
import AbilityStage from "@ohos.application.AbilityStage" import AbilityStage from "@ohos.app.ability.AbilityStage";
``` ```
2. Implement the **AbilityStage** class. The default relative path generated by the APIs is **entry\src\main\ets\Application\AbilityStage.ts**. 2. Implement the **AbilityStage** class. The default relative path generated by the APIs is **entry\src\main\ets\Application\AbilityStage.ts**.
```ts ```ts
...@@ -69,41 +69,41 @@ To create Page abilities for an application in the stage model, you must impleme ...@@ -69,41 +69,41 @@ To create Page abilities for an application in the stage model, you must impleme
``` ```
3. Import the **Ability** module. 3. Import the **Ability** module.
```js ```js
import Ability from '@ohos.application.Ability' import UIAbility from '@ohos.app.ability.UIAbility';
``` ```
4. Implement the lifecycle callbacks of the **Ability** class. The default relative path generated by the APIs is **entry\src\main\ets\MainAbility\MainAbility.ts**. 4. Implement the lifecycle callbacks of the **UIAbility** class. The default relative path generated by the APIs is **entry\src\main\ets\entryability\EntryAbility.ts**.
In the **onWindowStageCreate(windowStage)** API, use **loadContent** to set the application page to be loaded. For details about how to use the **Window** APIs, see [Window Development](../windowmanager/application-window-stage.md). In the **onWindowStageCreate(windowStage)** API, use **loadContent** to set the application page to be loaded. For details about how to use the **Window** APIs, see [Window Development](../windowmanager/application-window-stage.md).
```ts ```ts
export default class MainAbility extends Ability { export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
console.log("MainAbility onCreate") console.log("EntryAbility onCreate")
} }
onDestroy() { onDestroy() {
console.log("MainAbility onDestroy") console.log("EntryAbility onDestroy")
} }
onWindowStageCreate(windowStage) { onWindowStageCreate(windowStage) {
console.log("MainAbility onWindowStageCreate") console.log("EntryAbility onWindowStageCreate")
windowStage.loadContent("pages/index").then(() => { windowStage.loadContent("pages/index").then(() => {
console.log("MainAbility load content succeed") console.log("EntryAbility load content succeed")
}).catch((error) => { }).catch((error) => {
console.error("MainAbility load content failed with error: " + JSON.stringify(error)) console.error("EntryAbility load content failed with error: " + JSON.stringify(error))
}) })
} }
onWindowStageDestroy() { onWindowStageDestroy() {
console.log("MainAbility onWindowStageDestroy") console.log("EntryAbility onWindowStageDestroy")
} }
onForeground() { onForeground() {
console.log("MainAbility onForeground") console.log("EntryAbility onForeground")
} }
onBackground() { onBackground() {
console.log("MainAbility onBackground") console.log("EntryAbility onBackground")
} }
} }
``` ```
...@@ -113,7 +113,8 @@ Both the **AbilityStage** and **Ability** classes have the **context** attribute ...@@ -113,7 +113,8 @@ Both the **AbilityStage** and **Ability** classes have the **context** attribute
The following example shows how an application obtains the bundle code directory, HAP file name, ability name, and system language through the **context** attribute in the **AbilityStage** class. The sample code is as follows: The following example shows how an application obtains the bundle code directory, HAP file name, ability name, and system language through the **context** attribute in the **AbilityStage** class. The sample code is as follows:
```ts ```ts
import AbilityStage from "@ohos.application.AbilityStage" import AbilityStage from "@ohos.app.ability.AbilityStage";
export default class MyAbilityStage extends AbilityStage { export default class MyAbilityStage extends AbilityStage {
onCreate() { onCreate() {
console.log("MyAbilityStage onCreate") console.log("MyAbilityStage onCreate")
...@@ -132,52 +133,32 @@ export default class MyAbilityStage extends AbilityStage { ...@@ -132,52 +133,32 @@ export default class MyAbilityStage extends AbilityStage {
The following example shows how an application obtains the bundle code directory, HAP file name, ability name, and system language through the **context** attribute in the **Ability** class. The sample code is as follows: The following example shows how an application obtains the bundle code directory, HAP file name, ability name, and system language through the **context** attribute in the **Ability** class. The sample code is as follows:
```ts ```ts
import Ability from '@ohos.application.Ability' import UIAbility from '@ohos.app.ability.UIAbility';
export default class MainAbility extends Ability {
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
console.log("MainAbility onCreate") console.log("EntryAbility onCreate")
let context = this.context let context = this.context
console.log("MainAbility bundleCodeDir" + context.bundleCodeDir) console.log("EntryAbility bundleCodeDir" + context.bundleCodeDir)
let abilityInfo = this.context.abilityInfo; let abilityInfo = this.context.abilityInfo;
console.log("MainAbility ability bundleName" + abilityInfo.bundleName) console.log("EntryAbility ability bundleName" + abilityInfo.bundleName)
console.log("MainAbility ability name" + abilityInfo.name) console.log("EntryAbility ability name" + abilityInfo.name)
let config = this.context.config let config = this.context.config
console.log("MainAbility config language" + config.language) console.log("EntryAbility config language" + config.language)
} }
} }
``` ```
### Requesting Permissions
If an application needs to obtain user privacy information or use system capabilities, for example, obtaining location information or using the camera to take photos or record videos, it must request the respective permission from consumers. During application development, you need to specify the involved sensitive permissions, declare the required permissions in **module.json5**, and use the **requestPermissionsFromUser** API to request the permission from consumers in the form of a dialog box. The following uses the permission for calendar access as an example.
Declare the required permission in the **module.json5** file.
```json
"requestPermissions": [
{
"name": "ohos.permission.READ_CALENDAR"
}
]
```
Request the permission from consumers in the form of a dialog box:
```ts
let context = this.context
let permissions: Array<string> = ['ohos.permission.READ_CALENDAR']
context.requestPermissionsFromUser(permissions).then((data) => {
console.log("Succeed to request permission from user with data: " + JSON.stringify(data))
}).catch((error) => {
console.log("Failed to request permission from user with error: " + JSON.stringify(error))
})
```
### Notifying of Environment Changes ### Notifying of Environment Changes
Environment changes include changes of global configurations and ability configurations. Currently, the global configurations include the system language and color mode. The change of global configurations is generally triggered by configuration items in **Settings** or icons in **Control Panel**. The ability configuration is specific to a single **Ability** instance, including the display ID, screen resolution, and screen orientation. The configuration is related to the display where the ability is located, and the change is generally triggered by the window. For details on the configuration, see [Configuration](../reference/apis/js-apis-configuration.md). Environment changes include changes of global configurations and ability configurations. Currently, the global configurations include the system language and color mode. The change of global configurations is generally triggered by configuration items in **Settings** or icons in **Control Panel**. The ability configuration is specific to a single **Ability** instance, including the display ID, screen resolution, and screen orientation. The configuration is related to the display where the ability is located, and the change is generally triggered by the window. Before configuring a project, define the project in the [Configuration](../reference/apis/js-apis-application-configuration.md) class.
For an application in the stage model, when the configuration changes, its abilities are not restarted, but the **onConfigurationUpdated(config: Configuration)** callback is triggered. If the application needs to perform processing based on the change, you can overwrite **onConfigurationUpdated**. Note that the **Configuration** object in the callback contains all the configurations of the current ability, not only the changed configurations. For an application in the stage model, when the configuration changes, its abilities are not restarted, but the **onConfigurationUpdated(config: Configuration)** callback is triggered. If the application needs to perform processing based on the change, you can override **onConfigurationUpdated**. Note that the **Configuration** object in the callback contains all the configurations of the current ability, not only the changed configurations.
The following example shows the implementation of the **onConfigurationUpdated** callback in the **AbilityStage** class. The callback is triggered when the system language and color mode are changed. The following example shows the implementation of the **onConfigurationUpdated** callback in the **AbilityStage** class. The callback is triggered when the system language and color mode are changed.
```ts ```ts
import AbilityStage from '@ohos.application.AbilityStage' import AbilityStage from '@ohos.app.ability.AbilityStage';
import ConfigurationConstant from '@ohos.application.ConfigurationConstant' import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant';
export default class MyAbilityStage extends AbilityStage { export default class MyAbilityStage extends AbilityStage {
onConfigurationUpdated(config) { onConfigurationUpdated(config) {
...@@ -190,10 +171,10 @@ export default class MyAbilityStage extends AbilityStage { ...@@ -190,10 +171,10 @@ export default class MyAbilityStage extends AbilityStage {
The following example shows the implementation of the **onConfigurationUpdated** callback in the **Ability** class. The callback is triggered when the system language, color mode, or display parameters (such as the direction and density) change. The following example shows the implementation of the **onConfigurationUpdated** callback in the **Ability** class. The callback is triggered when the system language, color mode, or display parameters (such as the direction and density) change.
```ts ```ts
import Ability from '@ohos.application.Ability' import UIAbility from '@ohos.app.ability.UIAbility';
import ConfigurationConstant from '@ohos.application.ConfigurationConstant' import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant';
export default class MainAbility extends Ability { export default class EntryAbility extends UIAbility {
direction : number; direction : number;
onCreate(want, launchParam) { onCreate(want, launchParam) {
...@@ -229,7 +210,7 @@ let context = this.context ...@@ -229,7 +210,7 @@ let context = this.context
var want = { var want = {
"deviceId": "", "deviceId": "",
"bundleName": "com.example.MyApplication", "bundleName": "com.example.MyApplication",
"abilityName": "MainAbility" "abilityName": "EntryAbility"
}; };
context.startAbility(want).then(() => { context.startAbility(want).then(() => {
console.log("Succeed to start ability") console.log("Succeed to start ability")
...@@ -246,7 +227,7 @@ let context = this.context ...@@ -246,7 +227,7 @@ let context = this.context
var want = { var want = {
"deviceId": getRemoteDeviceId(), "deviceId": getRemoteDeviceId(),
"bundleName": "com.example.MyApplication", "bundleName": "com.example.MyApplication",
"abilityName": "MainAbility" "abilityName": "EntryAbility"
}; };
context.startAbility(want).then(() => { context.startAbility(want).then(() => {
console.log("Succeed to start remote ability") console.log("Succeed to start remote ability")
...@@ -261,17 +242,17 @@ function getRemoteDeviceId() { ...@@ -261,17 +242,17 @@ function getRemoteDeviceId() {
if (typeof dmClass === 'object' && dmClass != null) { if (typeof dmClass === 'object' && dmClass != null) {
var list = dmClass.getTrustedDeviceListSync(); var list = dmClass.getTrustedDeviceListSync();
if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') { if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null"); console.log("EntryAbility onButtonClick getRemoteDeviceId err: list is null");
return; return;
} }
console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId); console.log("EntryAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId);
return list[0].deviceId; return list[0].deviceId;
} else { } else {
console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null"); console.log("EntryAbility onButtonClick getRemoteDeviceId err: dmClass is null");
} }
} }
``` ```
Request the permission **ohos.permission.DISTRIBUTED_DATASYNC** from consumers. This permission is used for data synchronization. For details about the sample code for requesting the permission, see [Requesting Permissions](#requesting-permissions). Request the permission **ohos.permission.DISTRIBUTED_DATASYNC** from consumers. This permission is used for data synchronization. For details about the sample code for requesting permissions, see [abilityAccessCtrl.requestPermissionsFromUse](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9).
### Starting an Ability with the Specified Page ### Starting an Ability with the Specified Page
If the launch type of an ability is set to **singleton** and the ability has been started, the **onNewWant** callback is triggered when the ability is started again. You can pass start options through the **want**. For example, to start an ability with the specified page, use the **uri** or **parameters** parameter in the **want** to pass the page information. Currently, the ability in the stage model cannot directly use the **router** capability. You must pass the start options to the custom component and invoke the **router** method to display the specified page during the custom component lifecycle management. The sample code is as follows: If the launch type of an ability is set to **singleton** and the ability has been started, the **onNewWant** callback is triggered when the ability is started again. You can pass start options through the **want**. For example, to start an ability with the specified page, use the **uri** or **parameters** parameter in the **want** to pass the page information. Currently, the ability in the stage model cannot directly use the **router** capability. You must pass the start options to the custom component and invoke the **router** method to display the specified page during the custom component lifecycle management. The sample code is as follows:
...@@ -281,7 +262,7 @@ async function reStartAbility() { ...@@ -281,7 +262,7 @@ async function reStartAbility() {
try { try {
await this.context.startAbility({ await this.context.startAbility({
bundleName: "com.sample.MyApplication", bundleName: "com.sample.MyApplication",
abilityName: "MainAbility", abilityName: "EntryAbility",
uri: "pages/second" uri: "pages/second"
}) })
console.log('start ability succeed') console.log('start ability succeed')
...@@ -293,9 +274,9 @@ async function reStartAbility() { ...@@ -293,9 +274,9 @@ async function reStartAbility() {
Obtain the **want** parameter that contains the page information from the **onNewWant** callback of the ability. Obtain the **want** parameter that contains the page information from the **onNewWant** callback of the ability.
```ts ```ts
import Ability from '@ohos.application.Ability' import UIAbility from '@ohos.app.ability.UIAbility';
export default class MainAbility extends Ability { export default class EntryAbility extends UIAbility {
onNewWant(want, launchParams) { onNewWant(want, launchParams) {
globalThis.newWant = want globalThis.newWant = want
} }
...@@ -321,5 +302,3 @@ struct Index { ...@@ -321,5 +302,3 @@ struct Index {
} }
} }
``` ```
<!--no_check-->
\ No newline at end of file
...@@ -111,4 +111,4 @@ For details about the project directory structure of the stage model, see [OpenH ...@@ -111,4 +111,4 @@ For details about the project directory structure of the stage model, see [OpenH
For details about how to configure the application package structure of the stage model, see [Application Package Structure Configuration File](../quick-start/application-configuration-file-overview-stage.md). For details about how to configure the application package structure of the stage model, see [Application Package Structure Configuration File](../quick-start/application-configuration-file-overview-stage.md).
<!--no_check-->
\ No newline at end of file
...@@ -24,8 +24,10 @@ The ability call process is as follows: ...@@ -24,8 +24,10 @@ The ability call process is as follows:
- 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 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.
![stage-call](figures/stage-call.png) ![stage-call](figures/stage-call.png)
> **NOTE**<br/> > **NOTE**
>
> The launch type of the callee ability must be **singleton**. > The launch type of the callee ability must be **singleton**.
>
> Currently, only system applications can use the ability call. > Currently, only system applications can use the ability call.
## Available APIs ## Available APIs
...@@ -34,7 +36,7 @@ The table below describes the ability call APIs. For details, see [Ability](../r ...@@ -34,7 +36,7 @@ The table below describes the ability call APIs. For details, see [Ability](../r
**Table 2** Ability call APIs **Table 2** Ability call APIs
|API|Description| |API|Description|
|:------|:------| |:------|:------|
|startAbilityByCall(want: Want): Promise\<Caller>|Starts an ability in the foreground (through the **want** configuration) or background (default) and obtains the **Caller** object for communication with the ability. For details, see [AbilityContext](../reference/apis/js-apis-ability-context.md#abilitycontextstartabilitybycall) or [ServiceExtensionContext](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartabilitybycall).| |startAbilityByCall(want: Want): Promise\<Caller>|Starts an ability in the foreground (through the **want** configuration) or background (default) and obtains the **Caller** object for communication with the ability. For details, see [AbilityContext](../reference/apis/js-apis-ability-context.md#abilitycontextstartabilitybycall) or **ServiceExtensionContext**.|
|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 callee ability registers a method.|
|off(method: string): void|Callback invoked when the callee ability deregisters a method.| |off(method: string): void|Callback invoked when the callee ability deregisters a method.|
|call(method: string, data: rpc.Sequenceable): Promise\<void>|Sends agreed sequenceable data to the callee ability.| |call(method: string, data: rpc.Sequenceable): Promise\<void>|Sends agreed sequenceable data to the callee ability.|
...@@ -210,22 +212,25 @@ function getRemoteDeviceId() { ...@@ -210,22 +212,25 @@ function getRemoteDeviceId() {
if (typeof dmClass === 'object' && dmClass != null) { if (typeof dmClass === 'object' && dmClass != null) {
var list = dmClass.getTrustedDeviceListSync() var list = dmClass.getTrustedDeviceListSync()
if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') { if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') {
console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null") console.log("EntryAbility onButtonClick getRemoteDeviceId err: list is null")
return return
} }
console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId) console.log("EntryAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId)
return list[0].deviceId return list[0].deviceId
} else { } else {
console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null") console.log("EntryAbility onButtonClick getRemoteDeviceId err: dmClass is null")
} }
} }
``` ```
In the cross-device scenario, your application must also apply for the data synchronization permission from end users. The code snippet is as follows: In the cross-device scenario, your application must also apply for the data synchronization permission from end users. The code snippet is as follows:
```ts ```ts
import abilityAccessCtrl from '@ohos.abilityAccessCtrl.d.ts';
requestPermission() { requestPermission() {
let context = this.context let context = this.context
let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC'] let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC']
context.requestPermissionsFromUser(permissions).then((data) => { let atManager = abilityAccessCtrl.createAtManager();
atManager.requestPermissionsFromUser(context, permissions).then((data) => {
console.log("Succeed to request permission from user with data: "+ JSON.stringify(data)) console.log("Succeed to request permission from user with data: "+ JSON.stringify(data))
}).catch((error) => { }).catch((error) => {
console.log("Failed to request permission from user with error: "+ JSON.stringify(error)) console.log("Failed to request permission from user with error: "+ JSON.stringify(error))
......
...@@ -42,9 +42,9 @@ OpenHarmony does not support creation of a Service Extension ability for third-p ...@@ -42,9 +42,9 @@ OpenHarmony does not support creation of a Service Extension ability for third-p
2. Customize a class that inherits from `ServiceExtensionAbility` in the .ts file in the directory where the Service Extension ability is defined (`entry\src\main\ets\ServiceExtAbility\ServiceExtAbility.ts` by default) and override the lifecycle callbacks of the base class. The code sample is as follows: 2. Customize a class that inherits from `ServiceExtensionAbility` in the .ts file in the directory where the Service Extension ability is defined (`entry\src\main\ets\ServiceExtAbility\ServiceExtAbility.ts` by default) and override the lifecycle callbacks of the base class. The code sample is as follows:
```js ```js
import ServiceExtensionAbility from '@ohos.application.ServiceExtensionAbility' import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility';
import rpc from '@ohos.rpc' import rpc from '@ohos.rpc';
class StubTest extends rpc.RemoteObject { class StubTest extends rpc.RemoteObject {
constructor(des) { constructor(des) {
super(des); super(des);
...@@ -52,7 +52,7 @@ OpenHarmony does not support creation of a Service Extension ability for third-p ...@@ -52,7 +52,7 @@ OpenHarmony does not support creation of a Service Extension ability for third-p
onRemoteRequest(code, data, reply, option) { onRemoteRequest(code, data, reply, option) {
} }
} }
class ServiceExtAbility extends ServiceExtensionAbility { class ServiceExtAbility extends ServiceExtensionAbility {
onCreate(want) { onCreate(want) {
console.log('onCreate, want:' + want.abilityName); console.log('onCreate, want:' + want.abilityName);
......
# WantAgent Development # WantAgent Development
## When to Use ## When to Use
The **WantAgent** class encapsulates want information that specifies a particular action, which can be starting an ability or publishing a common event. You can either call **wantAgent.trigger** to trigger a **WantAgent** directly or add a **WantAgent** to a notification so that it will be triggered when users tap the notification. The **WantAgent** class encapsulates want information that specifies a particular action, which can be starting an ability or publishing a common event. You can either call **wantAgent.trigger** to trigger a **WantAgent** directly or add a **WantAgent** to a notification so that it will be triggered when users tap the notification.
## Available APIs ## Available APIs
| API | Description| | API | Description|
...@@ -12,13 +12,13 @@ The **WantAgent** class encapsulates want information that specifies a particula ...@@ -12,13 +12,13 @@ The **WantAgent** class encapsulates want information that specifies a particula
## How to Develop ## How to Develop
1. Import the **WantAgent** module. 1. Import the **WantAgent** module.
``` ```ts
import wantAgent from '@ohos.wantAgent'; import wantAgent from '@ohos.app.ability.wantAgent';
``` ```
2. Create a **WantAgentInfo** object that will be used for starting an ability. For details about the data types and parameters of **WantAgentInfo**, see [WantAgent](../reference/apis/js-apis-wantAgent.md#wantagentinfo). 2. Create a **WantAgentInfo** object that will be used for starting an ability. For details about the data types and parameters of **WantAgentInfo**, see [WantAgent](../reference/apis/js-apis-wantAgent.md#wantagentinfo).
``` ```ts
private wantAgentObj = null // Save the WantAgent object created. It will be used to complete the trigger operations. private wantAgentObj = null // Save the WantAgent object created. It will be used to complete the trigger operations.
// wantAgentInfo // wantAgentInfo
...@@ -27,7 +27,7 @@ The **WantAgent** class encapsulates want information that specifies a particula ...@@ -27,7 +27,7 @@ The **WantAgent** class encapsulates want information that specifies a particula
{ {
deviceId: "", deviceId: "",
bundleName: "com.example.test", bundleName: "com.example.test",
abilityName: "com.example.test.MainAbility", abilityName: "com.example.test.EntryAbility",
action: "", action: "",
entities: [], entities: [],
uri: "", uri: "",
...@@ -42,7 +42,7 @@ The **WantAgent** class encapsulates want information that specifies a particula ...@@ -42,7 +42,7 @@ The **WantAgent** class encapsulates want information that specifies a particula
3. Create a **WantAgentInfo** object for publishing a common event. 3. Create a **WantAgentInfo** object for publishing a common event.
``` ```ts
private wantAgentObj = null // Save the WantAgent object created. It will be used to complete the trigger operations. private wantAgentObj = null // Save the WantAgent object created. It will be used to complete the trigger operations.
// wantAgentInfo // wantAgentInfo
...@@ -61,7 +61,7 @@ The **WantAgent** class encapsulates want information that specifies a particula ...@@ -61,7 +61,7 @@ The **WantAgent** class encapsulates want information that specifies a particula
4. Create a **WantAgent** object and save the returned **wantAgentObj** for subsequent trigger operations. 4. Create a **WantAgent** object and save the returned **wantAgentObj** for subsequent trigger operations.
``` ```ts
// Create a WantAgent object. // Create a WantAgent object.
wantAgent.getWantAgent(wantAgentInfo, (err, wantAgentObj) => { wantAgent.getWantAgent(wantAgentInfo, (err, wantAgentObj) => {
if (err.code) { if (err.code) {
...@@ -75,7 +75,7 @@ The **WantAgent** class encapsulates want information that specifies a particula ...@@ -75,7 +75,7 @@ The **WantAgent** class encapsulates want information that specifies a particula
5. Trigger the **WantAgent** object. 5. Trigger the **WantAgent** object.
``` ```ts
// Trigger the WantAgent object. // Trigger the WantAgent object.
var triggerInfo = { var triggerInfo = {
code:0 code:0
......
...@@ -18,27 +18,29 @@ To facilitate your application development, we provide development guidelines fo ...@@ -18,27 +18,29 @@ To facilitate your application development, we provide development guidelines fo
First thing first, familiarize yourself with the two cornerstone frameworks in OpenHarmony applications: First thing first, familiarize yourself with the two cornerstone frameworks in OpenHarmony applications:
- Application framework: [Ability Development](ability/Readme-EN.md) - Application framework: [Application Models](application-models/Readme-EN.md)
- UI framework: [UI Development](ui/Readme-EN.md) - UI framework: [UI Development](ui/Readme-EN.md)
All applications should be developed on top of these frameworks. All applications should be developed on top of these frameworks.
Then, equip yourself for developing the key features, with the following guidelines: Then, equip yourself for developing the key features, with the following guidelines:
- [Common Event and Notification](notification/Readme-EN.md) - [Notification](notification/Readme-EN.md)
- [Window Manager](windowmanager/Readme-EN.md) - [Window Manager](windowmanager/Readme-EN.md)
- [WebGL](webgl/Readme-EN.md) - [WebGL](webgl/Readme-EN.md)
- [Media](media/Readme-EN.md) - [Media](media/Readme-EN.md)
- [Security](security/Readme-EN.md) - [Security](security/Readme-EN.md)
- [Connectivity](connectivity/Readme-EN.md) - [Connectivity](connectivity/Readme-EN.md)
- [Telephony](telephony/Readme-EN.md) - [Telephony Service](telephony/Readme-EN.md)
- [Data Management](database/Readme-EN.md) - [Data Management](database/Readme-EN.md)
- [Task Management](task-management/Readme-EN.md) - [Task Management](task-management/Readme-EN.md)
- [Device Management](device/Readme-EN.md) - [Device Management](device/Readme-EN.md)
- [Device Usage Statistics](device-usage-statistics/Readme-EN.md) - [Device Usage Statistics](device-usage-statistics/Readme-EN.md)
- [DFX](dfx/Readme-EN.md) - [DFX](dfx/Readme-EN.md)
- [Internationalization](internationalization/Readme-EN.md) - [Internationalization](internationalization/Readme-EN.md)
- [Application Test](application-test/Readme-EN.md)
- [IDL Specifications and User Guide](IDL/idl-guidelines.md) - [IDL Specifications and User Guide](IDL/idl-guidelines.md)
- [Using Native APIs in Application Projects](napi/Readme-EN.md) - [Using Native APIs in Application Projects](napi/Readme-EN.md)
- [File Management](file-management/medialibrary-overview.md)
### Tools ### Tools
...@@ -56,11 +58,11 @@ API references encompass all components and APIs available in OpenHarmony, helpi ...@@ -56,11 +58,11 @@ API references encompass all components and APIs available in OpenHarmony, helpi
They are organized as follows: They are organized as follows:
- [Component Reference (TypeScript-based Declarative Development Paradigm)](reference/arkui-ts/Readme-EN.md) - [Component Reference (TypeScript-based Declarative Development Paradigm)](reference/arkui-ts/Readme-EN.md)
- [Component Reference (JavaScript-based Web-like Development Paradigm)](reference/arkui-js/Readme-EN.md)
- [Component Reference (JavaScript-based Web-like Development Paradigm)](reference/arkui-js/Readme-EN.md) - [JS Service Widget UI Components](reference/js-service-widget-ui/Readme-EN.md)
- APIs - APIs
- [JS and TS APIs](reference/apis/Readme-EN.md) - [JS and TS APIs](reference/apis/Readme-EN.md)
- Native APIs - Native APIs
- [Standard Library](reference/native-lib/third_party_libc/musl.md) - [Standard Library](reference/native-lib/third_party_libc/musl.md)
- [Node_API](reference/native-lib/third_party_napi/napi.md) - [Node_API](reference/native-lib/third_party_napi/napi.md)
......
...@@ -18,27 +18,29 @@ To facilitate your application development, we provide development guidelines fo ...@@ -18,27 +18,29 @@ To facilitate your application development, we provide development guidelines fo
First thing first, familiarize yourself with the two cornerstone frameworks in OpenHarmony applications: First thing first, familiarize yourself with the two cornerstone frameworks in OpenHarmony applications:
- Application framework: [Ability Development](ability/fa-brief.md) - Application framework: [Application Models](application-models/application-model-composition.md)
- UI framework: [UI Development](ui/arkui-overview.md) - UI framework: [UI Development](ui/arkui-overview.md)
All applications should be developed on top of these frameworks. All applications should be developed on top of these frameworks.
Then, equip yourself for developing the key features, with the following guidelines: Then, equip yourself for developing the key features, with the following guidelines:
- [Common Event and Notification](notification/notification-brief.md) - [Notification](notification/notification-overview.md)
- [Window Manager](windowmanager/window-overview.md) - [Window Manager](windowmanager/window-overview.md)
- [WebGL](webgl/webgl-overview.md) - [WebGL](webgl/webgl-overview.md)
- [Media](media/audio-overview.md) - [Media](media/audio-overview.md)
- [Security](security/userauth-overview.md) - [Security](security/userauth-overview.md)
- [Connectivity](connectivity/ipc-rpc-overview.md) - [Connectivity](connectivity/ipc-rpc-overview.md)
- [Telephony](telephony/telephony-overview.md) - [Telephony Service](telephony/telephony-overview.md)
- [Data Management](database/database-mdds-overview.md) - [Data Management](database/database-mdds-overview.md)
- [Task Management](task-management/background-task-overview.md) - [Task Management](task-management/background-task-overview.md)
- [Device](device/usb-overview.md) - [Device](device/usb-overview.md)
- [Device Usage Statistics](device-usage-statistics/device-usage-statistics-overview.md) - [Device Usage Statistics](device-usage-statistics/device-usage-statistics-overview.md)
- [DFX](dfx/hiappevent-overview.md) - [DFX](dfx/hiappevent-guidelines.md)
- [Internationalization](internationalization/international-overview.md) - [Internationalization](internationalization/international-overview.md)
- [Application Test](application-test/arkxtest-guidelines.md)
- [OpenHarmony IDL Specifications and User Guide](IDL/idl-guidelines.md) - [OpenHarmony IDL Specifications and User Guide](IDL/idl-guidelines.md)
- [Using Native APIs in Application Projects](napi/napi-guidelines.md) - [Using Native APIs in Application Projects](napi/napi-guidelines.md)
- [File Management](file-management/medialibrary-overview.md)
### Tools ### Tools
...@@ -59,7 +61,9 @@ They are organized as follows: ...@@ -59,7 +61,9 @@ They are organized as follows:
- [Component Reference (JavaScript-based Web-like Development Paradigm)](reference/arkui-js/Readme-EN.md) - [Component Reference (JavaScript-based Web-like Development Paradigm)](reference/arkui-js/Readme-EN.md)
- [JS and TS APIs](reference/apis/js-apis-DataUriUtils.md) - [JS Service Widget UI Components](reference/js-service-widget-ui/Readme-EN.md)
- [JS and TS APIs](reference/apis/js-apis-ability-dataUriUtils.md)
- Native APIs - Native APIs
- [Standard Library](reference/native-lib/third_party_libc/musl.md) - [Standard Library](reference/native-lib/third_party_libc/musl.md)
......
# Application Models # Application Models
- Application Model Overview
- [Elements of the Application Model](application-model-composition.md)
- [Interpretation of the Application Model](application-model-description.md)
- Stage Model Development
- [Stage Model Development Overview](stage-model-development-overview.md)
- Stage Mode Application Components
- [Application- or Component-Level Configuration](application-component-configuration-stage.md)
- UIAbility Component
- [UIAbility Component Overview](uiability-overview.md)
- [UIAbility Component Lifecycle](uiability-lifecycle.md)
- [UIAbility Component Launch Type](uiability-launch-type.md)
- [UIAbility Component Usage](uiability-usage.md)
- [Data Synchronization Between UIAbility and UI](uiability-data-sync-with-ui.md)
- [Interaction Between Intra-Device UIAbility Components](uiability-intra-device-interaction.md)
- ExtensionAbility Component
- [ExtensionAbility Component Overview](extensionability-overview.md)
- [ServiceExtensionAbility](serviceextensionability.md)
- [DataShareExtensionAbility (for System Applications Only)](datashareextensionability.md)
- [FormExtensionAbility (Widget)](widget-development-stage.md)
- [AccessibilityExtensionAbility](accessibilityextensionability.md)
- [EnterpriseAdminExtensionAbility](enterprise-extensionAbility.md)
- [InputMethodExtensionAbility](inputmethodextentionability.md)
- [WindowExtensionAbility](windowextensionability.md)
- [AbilityStage Component Container](abilitystage.md)
- [Context](application-context-stage.md)
- Want
- [Want Overview](want-overview.md)
- [Matching Rules of Explicit Want and Implicit Want](explicit-implicit-want-mappings.md)
- [Common action and entities Values](actions-entities.md)
- [Using Explicit Want to Start an Ability](ability-startup-with-explicit-want.md)
- [Using Implicit Want to Open a Website](ability-startup-with-implicit-want.md)
- [Using Want to Share Data Between Applications](data-share-via-want.md)
- [Component Startup Rules](component-startup-rules.md)
- Inter-Device Application Component Interaction (Continuation)
- [Continuation Overview](inter-device-interaction-hop-overview.md)
- [Cross-Device Migration (for System Applications Only)](hop-cross-device-migration.md)
- [Multi-device Collaboration (for System Applications Only)](hop-multi-device-collaboration.md)
- [Subscribing to System Environment Variable Changes](subscribe-system-environment-variable-changes.md)
- IPC
- [Process Model](process-model-stage.md)
- Common Events
- [Introduction to Common Events](common-event-overview.md)
- Common Event Subscription
- [Common Event Subscription Overview](common-event-subscription-overview.md)
- [Subscribing to Common Events in Dynamic Mode](common-event-subscription.md)
- [Subscribing to Common Events in Static Mode (for System Applications Only)](common-event-static-subscription.md)
- [Unsubscribing from Common Events](common-event-unsubscription.md)
- [Publishing Common Events](common-event-publish.md)
- [Background Services](background-services.md)
- Inter-Thread Communication
- [Thread Model](thread-model-stage.md)
- [Using Emitter for Inter-Thread Communication](itc-with-emitter.md)
- [Using Worker for Inter-Thread Communication](itc-with-worker.md)
- Mission Management
- [Mission Management Scenarios](mission-management-overview.md)
- [Mission Management and Launch Type](mission-management-launch-type.md)
- [Page Stack and MissionList](page-mission-stack.md)
- [Setting the Icon and Name of a Mission Snapshot](mission-set-icon-name-for-task-snapshot.md)
- [Application Configuration File](config-file-stage.md)
- FA Model Development
- [FA Model Development Overview](fa-model-development-overview.md)
- FA Mode Application Components
- [Application- or Component-Level Configuration](application-component-configuration-fa.md)
- PageAbility Component Development
- [PageAbility Component Overview](pageability-overview.md)
- [PageAbility Component Configuration](pageability-configuration.md)
- [PageAbility Lifecycle](pageability-lifecycle.md)
- [PageAbility Launch Type](pageability-launch-type.md)
- [Creating a PageAbility](create-pageability.md)
- [Starting a Local PageAbility](start-local-pageability.md)
- [Stopping a PageAbility](stop-pageability.md)
- [Starting a Remote PageAbility (for System Applications Only)](start-remote-pageability.md)
- [Starting a Specified Page](start-page.md)
- [Window Properties](window-properties.md)
- [Requesting Permissions](request-permissions.md)
- [Redirection Rules](redirection-rules.md)
- ServiceAbility Component Development
- [ServiceAbility Component Overview](serviceability-overview.md)
- [ServiceAbility Component Configuration](serviceability-configuration.md)
- [ServiceAbility Lifecycle](serviceability-lifecycle.md)
- [Creating a ServiceAbility](create-serviceability.md)
- [Starting a ServiceAbility](start-serviceability.md)
- [Connecting to a ServiceAbility](connect-serviceability.md)
- DataAbility Component Development
- [DataAbility Component Overview](dataability-overview.md)
- [DataAbility Component Configuration](dataability-configuration.md)
- [DataAbility Lifecycle](dataability-lifecycle.md)
- [Creating a DataAbility](create-dataability.md)
- [Starting a DataAbility](start-dataability.md)
- [Accessing a DataAbility](access-dataability.md)
- [DataAbility Permission Control](dataability-permission-control.md)
- [Widget Development](widget-development-fa.md)
- [Context](application-context-fa.md)
- [Want](want-fa.md)
- [Component Startup Rules](component-startup-rules-fa.md)
- IPC
- [Process Model](process-model-fa.md)
- [Common Events](common-event-fa.md)
- [Background Services](rpc.md)
- Inter-Thread Communication
- [Thread Model](thread-model-fa.md)
- [Inter-Thread Communication](itc-fa-overview.md)
- [Mission Management](mission-management-fa.md)
- [Application Configuration File](config-file-fa.md)
- Development of Component Interaction Between the FA Model and Stage Model
- [Component Interaction Between the FA Model and Stage Model](fa-stage-interaction-overview.md)
- [Starting a UIAbility from the FA Model](start-uiability-from-fa.md)
- [Connecting to a ServiceExtensionAbility from the FA Model](bind-serviceextensionability-from-fa.md)
- [Accessing a DataShareExtensionAbility from the FA Model](access-datashareextensionability-from-fa.md)
- [Starting a PageAbility from the Stage Model](start-pageability-from-stage.md)
- [Connecting to a ServiceAbility from the Stage Model](bind-serviceability-from-stage.md)
- Switching from the FA Model to the Stage Model
- [Model Switching Overview](model-switch-overview.md)
- Configuration File Switching
- [Differences in Configuration Files](configuration-file-diff.md)
- [Switching of app and deviceConfig](app-deviceconfig-switch.md)
- [Switching of module](module-switch.md)
- Component Switching
- [PageAbility Switching](pageability-switch.md)
- [ServiceAbility Switching](serviceability-switch.md)
- [DataAbility Switching](dataability-switch.md)
- [Widget Switching](widget-switch.md)
- API Switching
- [API Switching Overview](api-switch-overview.md)
- [Context Switching](context-switch.md)
- [featureAbility Switching](featureability-switch.md)
- [particleAbility Switching](particleability-switch.md)
- [LifecycleForm Switching](lifecycleform-switch.md)
- [LifecycleApp Switching](lifecycleapp-switch.md)
- [LifecycleService Switching](lifecycleservice-switch.md)
- [LifecycleData Switching](lifecycledata-switch.md)
- [DataAbilityHelper Switching](dataabilityhelper-switch.md)
- [mediaLibrary Switching](medialibrary-switch.md)
- [request Switching](request-switch.md)
- [resourceManager Switching](resourcemanager-switch.md)
- [window Switching](window-switch.md)
- [Storage Switching](storage-switch.md)
# Using Explicit Want to Start an Ability
When a user touches a button in an application, the application often needs to start a UIAbility component to complete a specific task. If the **abilityName** and **bundleName** parameters are specified when starting a UIAbility, then the explicit Want is used.
## Using Explicit Want
The user touches a button in the application to start the UIAbility component to complete a specific task. To start the UIAbility component in explicit Want mode, the **abilityName** and **bundleName** parameters must be specified. For details, see [Starting UIAbility in the Same Application](uiability-intra-device-interaction.md#starting-uiability-in-the-same-application).
# Using Implicit Want to Open a Website
This section uses the operation of using a browser to open a website as an example. It is assumed that one or more browser applications are installed on the device. To ensure that the browser application can work properly, configure the [module.json5 file](../quick-start/module-configuration-file.md) as follows:
```json
{
"module": {
// ...
"abilities": [
{
// ...
"skills": [
{
"entities": [
"entity.system.home",
"entity.system.browsable"
// ...
],
"actions": [
"action.system.home",
"ohos.want.action.viewData"
// ...
],
"uris": [
{
"scheme": "https",
"host": "www.test.com",
"port": "8080",
// Prefix matching is used.
"pathStartWith": "query",
"type": "text/*"
},
{
"scheme": "http",
// ...
}
// ...
]
}
]
}
]
}
}
```
In the initiator UIAbility, use implicit Want to start the browser application.
```ts
import common from '@ohos.app.ability.common';
function implicitStartAbility() {
let context = getContext(this) as common.UIAbilityContext;
let wantInfo = {
// Uncomment the line below if you want to implicitly query data only in the specific bundle.
// bundleName: "com.example.myapplication",
"action": "ohos.want.action.viewData",
// entities can be omitted.
"entities": ["entity.system.browsable"],
"uri": "https://www.test.com:8080/query/student",
"type": "text/plain"
}
context.startAbility(wantInfo).then(() => {
// ...
}).catch((err) => {
// ...
})
}
```
The matching process is as follows:
1. If **action** in the passed **want** parameter is specified and is included in **actions** under **skills** of the ability to match, the matching is successful.
2. If **entities** in the passed **want** parameter is specified and is included in **entities** under **skills** of the ability to match, 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.
When there are multiple matching applications, a dialog box is displayed for you to select one of them. The following figure shows an example.
![](figures/ability-startup-with-implicit-want1.png)
\ No newline at end of file
# AbilityStage Component Container
AbilityStage is a component container at the [module](../quick-start/application-package-structure-stage.md) level. When the HAP of an application is loaded for the first time, an AbilityStage instance is created. You can perform operations such as initialization on the instance.
An AbilityStage instance corresponds to a module.
AbilityStage is not automatically generated in the default project of DevEco Studio. To use AbilityStage, you can manually create an AbilityStage file. The procedure is as follows:
1. In the **ets** directory of the **Module** project, right-click and choose **New > Directory** to create a directory named **myabilitystage**.
2. In the **myabilitystage** directory, right-click and choose **New > ts File** to create a file named **MyAbilityStage.ts**.
3. Open the **MyAbilityStage.ts** file, and import the dependency package of AbilityStage. Customize a class that inherits from AbilityStage, and add the required lifecycle callbacks. The following code snippet adds the **onCreate()** lifecycle callback.
```ts
import AbilityStage from '@ohos.app.ability.AbilityStage';
export default class MyAbilityStage extends AbilityStage {
onCreate() {
// When the HAP of the application is loaded for the first time, initialize the module.
}
onAcceptWant(want) {
// Triggered only for the ability with the specified launch type.
return "MyAbilityStage";
}
}
```
4. Set **srcEntry** in the [module.json5 file](../quick-start/module-configuration-file.md) to the code path of the module.
```json
{
"module": {
"name": "entry",
"type": "entry",
"srcEntry": "./ets/myabilitystage/MyAbilityStage.ts",
// ...
}
}
```
[AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md) has the lifecycle callback [onCreate()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageoncreate) and the event callbacks [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant), [onConfigurationUpdated()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonconfigurationupdate), and [onMemoryLevel()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonmemorylevel).
- **onCreate()** lifecycle callback: Before the first UIAbility instance of a module is loaded, an AbilityStage instance is created. This callback is invoked when the AbilityStage instance is created. The AbilityStage module notifies you of when you can perform module initialization such as resource pre-loading and thread creation during module loading.
- **onAcceptWant()** event callback: triggered when the UIAbility is started in [specified mode](uiability-launch-type.md#specified). For details, see [UIAbility Component Launch Type](uiability-launch-type.md).
- **onConfigurationUpdated()** event callback: triggered when the global system configuration changes. The global system configuration, such as the system language and theme, are defined in the [Configuration](../reference/apis/js-apis-app-ability-configuration.md) class before project configuration.
- **onMemoryLevel()** event callback: triggered when the system adjusts the memory.
When an application is switched to the background, it is cached in the background. This adversely affects the overall system performance. When system resources are insufficient, the system reclaims memory from applications in multiple ways. For example, the system may stop applications to release memory for executing key tasks. To further maintain the balance of the system memory and prevent the system from stopping application processes, you can subscribe to the system memory changes in the **onMemoryLevel()** lifecycle callback of AbilityStage to release unnecessary resources.
```ts
import AbilityStage from '@ohos.app.ability.AbilityStage';
export default class MyAbilityStage extends AbilityStage {
onMemoryLevel(level) {
// Release unnecessary memory based on the change of available system memory.
}
}
```
# Accessing a DataAbility
To access a DataAbility, import the basic dependency packages and obtain the URI string for communicating with the DataAbility.
The basic dependency packages include:
- @ohos.ability.featureAbility
- @ohos.data.dataAbility
- @ohos.data.rdb
The sample code for accessing a DataAbility is as follows:
1. Create a **DataAbilityHelper** instance.
```ts
// Different from the URI defined in the config.json file, the URI passed in the parameter has an extra slash (/), three slashes in total.
import featureAbility from '@ohos.ability.featureAbility'
import ohos_data_ability from '@ohos.data.dataAbility'
import ohos_data_rdb from '@ohos.data.rdb'
let urivar = "dataability:///com.ix.DataAbility"
let DAHelper = featureAbility.acquireDataAbilityHelper(urivar);
```
2. Construct RDB data.
```ts
let valuesBucket = {"name": "gaolu"}
let da = new ohos_data_ability.DataAbilityPredicates()
let valArray =new Array("value1");
let cars = new Array({"batchInsert1" : "value1",});
```
For details about DataAbilityPredicates, see [DataAbility Predicates](../reference/apis/js-apis-data-ability.md).
3. Use **insert** to insert data to the DataAbility.
```ts
// Callback mode:
DAHelper.insert(
urivar,
valuesBucket,
(error, data) => {
console.info("DAHelper insert result: " + data)
}
);
```
```ts
// Promise mode (await needs to be used in the asynchronous method):
let datainsert = await DAHelper.insert(urivar, valuesBucket).then((data) => {
console.info("insert success.");
}).catch((error) => {
console.error("insert failed.");
});
```
4. Use **delete** to delete data from the DataAbility.
```ts
// Callback mode:
DAHelper.delete(
urivar,
da,
(error, data) => {
console.info("DAHelper delete result: " + data)
}
);
```
```ts
// Promise mode (await needs to be used in the asynchronous method):
let datadelete = await DAHelper.delete(
urivar,
da,
);
```
5. Use **update** to update data in the DataAbility.
```ts
// Callback mode:
DAHelper.update(
urivar,
valuesBucket,
da,
(error, data) => {
console.info("DAHelper update result: " + data)
}
);
```
```ts
// Promise mode (await needs to be used in the asynchronous method):
let dataupdate = await DAHelper.update(
urivar,
valuesBucket,
da,
);
```
6. Use **query** to query data in the DataAbility.
```ts
// Callback mode:
DAHelper.query(
urivar,
valArray,
da,
(error, data) => {
console.info("DAHelper query result: " + data)
}
);
```
```ts
// Promise mode (await needs to be used in the asynchronous method):
let dataquery = await DAHelper.query(
urivar,
valArray,
da
);
```
7. Use **batchInsert** to insert data in batches to the DataAbility.
```ts
// Callback mode:
DAHelper.batchInsert(
urivar,
cars,
(error, data) => {
console.info("DAHelper batchInsert result: " + data)
}
);
```
```ts
// Promise mode (await needs to be used in the asynchronous method):
let databatchInsert = await DAHelper.batchInsert(
urivar,
cars
);
```
8. Use **executeBatch** to process data in batches in the DataAbility.
```ts
// Callback mode:
DAHelper.executeBatch(
urivar,
[
{
uri: urivar,
type: featureAbility.DataAbilityOperationType.TYPE_INSERT,
valuesBucket: {"executeBatch" : "value1",},
predicates: da,
expectedCount:0,
predicatesBackReferences: null,
interrupted:true,
}
],
(error, data) => {
console.info("DAHelper executeBatch result: " + data)
}
);
```
```ts
// Promise mode (await needs to be used in the asynchronous method):
let dataexecuteBatch = await DAHelper.executeBatch(
urivar,
[
{
uri: urivar,
type: featureAbility.DataAbilityOperationType.TYPE_INSERT,
valuesBucket:
{
"executeBatch" : "value1",
},
predicates: da,
expectedCount:0,
predicatesBackReferences: null,
interrupted:true,
}
]
);
```
The APIs for operating a DataAbility are provided by **DataAbilityHelper**. For details about the APIs, see [DataAbilityHelper](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md).
# Accessing a DataShareExtensionAbility from the FA Model
## Overview
Regardless of the FA model or stage model, the data read/write function consists of the client and server.
- In the FA model, the client uses the **DataAbilityHelper** class to provide external APIs, and the server uses the **DataAbility** class to provide database read and write services.
- In the stage model, the client uses the **DataShareHelper** class to provide external APIs, and the server uses the **DataShareExtensionAbility** class to provide database read and write services.
If the client uses the FA model whereas the server is upgraded to the stage model, the client cannot access the server.
To resolve this issue, OpenHarmony provides a solution on the framework side for smooth evolution.
## Basic Principles
A compatible method is that **DataAbilityHelper** determines whether to call the **DataShareHelper** APIs based on the URI prefix (either **DataAbility** or **DataShare**). However, this method requires modification to the URI in the original client code.
Instead of manual modification, OpenHarmony adopts the following processing:
1. The system attempts to start the DataAbility based on the URI passed in. If the startup fails, the system converts the URI prefix to **DataShare** and attempts to start the DataShareExtensionAbility.
2. If the URI does not map to any DataAbility or DataShareExtensionAbility, the startup fails. Otherwise, either the DataAbility or DataShareExtensionAbility is started.
## Constraints
1. When you switch a DataAbility to a DataShareExtensionAbility, only the URI prefix can be modified.![FAvsStage-uri](figures/FAvsStage-uri.png)
2. The **DataShareHelper** class implements only certain APIs of **DataAbilityHelper**. For details about the APIs, see the table below.
**Table 1** APIs invoked when the FA model accesses a DataShareExtensionAbility of the stage model
| API| Provided by DataAbilityHelper| Provided by DataShareHelper| Compatible|
| -------- | -------- | -------- | -------- |
| on | Yes| Yes| Yes|
| off | Yes| Yes| Yes|
| notifyChange | Yes| Yes| Yes|
| insert | Yes| Yes| Yes|
| delete | Yes| Yes| Yes|
| query | Yes| Yes| Yes|
| update | Yes| Yes| Yes|
| batchInsert | Yes| Yes| Yes|
| getType | Yes| No| No|
| getFileTypes | Yes| No| No|
| normalizeUri | Yes| Yes| Yes|
| denormalizeUri | Yes| Yes| Yes|
| openFile | Yes| No| No|
| call | Yes| No| No|
| executeBatch | Yes| No| No|
# AccessibilityExtensionAbility Development
The **AccessibilityExtensionAbility** module provides accessibility extension capabilities based on the **ExtensionAbility** framework. You can develop your accessibility applications by applying the **AccessibilityExtensionAbility** template to enhance usability.
> **Environment Requirements**
>
> IDE: DevEco Studio 3.0 Beta3 (3.0.0.900) or later
>
> SDK: API version 9 or later
>
> Model: stage
This document is organized as follows:
- [Creating an AccessibilityExtAbility File](#creating-an-accessibility-extension-service)
- [Processing an Accessibility Event](#processing-an-accessibility-event)
- [Declaring Capabilities of Accessibility Extension Services](#declaring-capabilities-of-accessibility-extension-services)
- [Enabling a Custom Accessibility Extension Service](#enabling-a-custom-accessibility-extension-service)
## Creating an Accessibility Extension Service
You can create an accessibility extension service by creating a project from scratch or adding the service to an existing project.
### Creating a Project
Perform the following steps in DevEco Studio:
1. From the upper left corner of DevEco Studio, choose **File** > **New** > **Create Project**.
2. By following the project creation wizard, click the **OpenHarmony** tab, select the **Empty Ability** template, and then click **Next**.
3. Set **Project type** to **Application**, **Compile API** (or **Compile SDK**, depending on the version used) to **9**, and **Model** to **Stage**, and then click **Finish**.
### Creating an AccessibilityExtAbility File
To add an accessibility extension service to a project, create the **AccessibilityExtAbility** folder in the **ets** folder of the project, create the **AccessibilityExtAbility.ts** file in the new folder, and add the following code to the new file:
```typescript
import AccessibilityExtensionAbility from '@ohos.application.AccessibilityExtensionAbility';
class AccessibilityExtAbility extends AccessibilityExtensionAbility {
onConnect() {
console.log('AccessibilityExtAbility onConnect');
}
onDisconnect() {
console.log('AccessibilityExtAbility onDisconnect');
}
onAccessibilityEvent(accessibilityEvent) {
console.log('AccessibilityExtAbility onAccessibilityEvent: ' + JSON.stringify(accessibilityEvent));
}
}
export default AccessibilityExtAbility;
```
The APIs defined in the file are as follows.
| API| Description|
| ---- | ---- |
| onConnect(): void | Called when a connection with the extension service is set up.|
| onDisconnect(): void | Called when the connection with the extension service is severed.|
| onAccessibilityEvent(event: AccessibilityEvent): void | Called when an accessibility event occurs|
## Processing an Accessibility Event
You can process the service logic for accessibility events in the **onAccessibilityEvent()** API. For details about the events, see [AccessibilityEvent](../reference/apis/js-apis-application-accessibilityExtensionAbility.md#accessibilityevent). The following code snippet uses the **pageStateUpdate** event as an example.
```typescript
onAccessibilityEvent(accessibilityEvent) {
console.log('AccessibilityExtAbility onAccessibilityEvent: ' + JSON.stringify(accessibilityEvent));
if (accessibilityEvent.eventType === 'pageStateUpdate') {
console.log('AccessibilityExtAbility onAccessibilityEvent: pageStateUpdate');
// TODO: Develop custom logic.
}
}
```
For an accessibility event, you can use the APIs of the [AccessibilityExtensionContext](../reference/apis/js-apis-inner-application-accessibilityExtensionContext.md) module to configure the concerned information, obtain root information, and inject gestures.
You can also process physical key events in the accessibility extension service. For details, see [onKeyEvent](../reference/apis/js-apis-application-accessibilityExtensionAbility.md#accessibilityextensionabilityonkeyevent).
## Declaring Capabilities of Accessibility Extension Services
After developing the custom logic for an accessibility extension service, you must add the configuration information of the service to the corresponding module-level **module.json5** file in the project directory. In the file, the **srcEntrance** tag indicates the path to the accessibility extension service. Make sure the value of the **type** tag is fixed at **accessibility**. Otherwise, the connection to the service will fail.
```json
"extensionAbilities": [
{
"name": "AccessibilityExtAbility",
"srcEntrance": "./ets/AccessibilityExtAbility/AccessibilityExtAbility.ts",
"label": "$string:MainAbility_label",
"description": "$string:MainAbility_desc",
"type": "accessibility",
"metadata": [
{
"name": "ohos.accessibleability",
"resource": "$profile:accessibility_config"
}
]
}
]
```
**accessibility_config** is the specific configuration of the accessibility extension service. You need to create the **accessibility_config.json** file in **resources/base/profile/** and declare the [capabilities](../reference/apis/js-apis-accessibility.md#capability) of the service in the file.
```json
{
"accessibilityCapabilities": [
"retrieve",
"gesture"
]
}
```
## Enabling a Custom Accessibility Extension Service
To enable or disable an accessibility extension service, run the following command:
- To enable the service: **accessibility enable -a AccessibilityExtAbility -b com.example.demo -c rg**
- To disable the service: **accessibility disable -a AccessibilityExtAbility -b com.example.demo**
In the preceding commands, **AccessibilityExtAbility** indicates the name of the accessibility extension service, **com.example.demo** indicates the bundle name, and **rg** indicates the capabilities (**r** is short for retrieve).
If the service is enabled or disabled successfully, the message "enable ability successfully" or "disable ability successfully" is displayed.
# Common action and entities Values
**action**: Action to take, such as viewing, sharing, and application details, by the caller. In implicit Want, you can define this field and use it together with **uri** or **parameters** to specify the operation to be performed on the data, for example, viewing URI data. For example, if the URI is a website and the action is **ohos.want.action.viewData**, the ability that supports website viewing is matched. Declaring the **action** field in Want indicates that the invoked application should support the declared operation. The **actions** field under **skills** in the configuration file indicates the operations supported by the application.
**Common action Values**
- **ACTION_HOME**: action of starting the application entry component. It must be used together with **ENTITY_HOME**. The application icon on the home screen is an explicit entry component. Users can touch the icon to start the entry component. Multiple entry components can be configured for an application.
- **ACTION_CHOOSE**: action of selecting local resource data, such as Contacts and Gallery. Generally, the system has corresponding Picker applications for different types of data.
- **ACTION_VIEW_DATA**: action of viewing data. A website URI indicates the action for opening the website.
- **ACTION_VIEW_MULTIPLE_DATA**: action of launching the UI for sending multiple data records.
**entities**: Category information (such as browser and video player) of the target ability. It is a supplement to **action** in implicit Want. You can define this field to filter application categories, for example, browser. Declaring the **entities** field in Want indicates that the invoked application should belong to the declared category. The **entities** field under **skills** in the configuration file indicates the categories supported by the application.
**Common entities Values**
- **ENTITY_DEFAULT**: default category, which is meaningless.
- **ENTITY_HOME**: abilities with an icon displayed on the home screen.
- **ENTITY_BROWSABLE**: browser type.
# API Switching Overview
Due to the differences in the thread model and process model, certain APIs (marked with **FAModelOnly** in the SDK) can be used only in the FA model. When switching an application from the FA model to the stage model, replace the APIs marked with **FAModelOnly** in the application with the APIs supported in the stage model. This topic uses the switching of **startAbility()** as an example.
![api-switch-overview](figures/api-switch-overview.png)
- Sample code of **startAbility()** in the FA model:
```ts
import fa from '@ohos.ability.featureAbility';
let parameter = {
"want": {
bundleName: "com.example.myapplication",
abilityName: "com.example.myapplication.EntryAbility"
}
}
fa.startAbility(parameter).then((data) => {
console.info('startAbility success');
}).catch((error) => {
console.error('startAbility failed.');
})
```
- Sample code of **startAbility()** in the stage model:
```ts
// context is a member of the ability object and is required for invoking inside a non-ability object.
// Pass in the Context object.
let wantInfo = {
bundleName: "com.example.myapplication",
abilityName: "EntryAbility"
};
this.context.startAbility(wantInfo).then((data) => {
console.info('startAbility success.');
}).catch((error) => {
console.error('startAbility failed.');
})
```
# Switching of app and deviceConfig
To help you better maintain the configuration of application-level attributes, OpenHarmony has extracted the **app** and **deviceConfig** tags from the **config.json** file to the **app.json5** file and changed certain tag names in the stage model.
**Table 1** Comparison of the app tag in the configuration files
| Configuration Item| app in config.json| app in app.json5|
| -------- | -------- | -------- |
| Internal version number of an application| "version": {<br> "code": 1,<br>} | "versionCode":&nbsp;1&nbsp;, |
| Text description of the version number, which is displayed to users| "version": {<br> "name": "1.0.0",<br>} | "versionName"&nbsp;:&nbsp;"1.0.0"&nbsp;, |
| Earliest compatible version of the application| "version": {<br> "minCompatibleVersionCode": 1,<br>} | "minCompatibleVersionCode"&nbsp;:&nbsp;1&nbsp;, |
| Minimum API version required for application running| "apiVersion": {<br> "compatible": 7,<br>} | "minAPIVersion"&nbsp;:&nbsp;7&nbsp;, |
| Target API version required for application running| "apiVersion": {<br> "target": 8,<br>} | "targetApiVersion"&nbsp;:&nbsp;8&nbsp;, |
| Type of the target API version required for application running| "apiVersion": {<br> "releaseType": Release,<br>} | "apiReleaseType":&nbsp;"Release"&nbsp;, |
OpenHarmony has reconstructed the [deviceConfig](../quick-start/deviceconfig-structure.md) tag of the **config.json** file in the **app.json5** file. It has integrated the fields related to device information under **deviceConfig** into the **app** tag of the [app.json5](../quick-start/app-configuration-file.md) file.
**Table 2** Comparison of the deviceConfig tag in the configuration files
| deviceConfig in the FA Model| Description| Stage Model| Difference|
| -------- | -------- | -------- | -------- |
| deviceConfig| Device information.| / | This tag is no longer available in the stage model. In the stage model, device information is configured under the **app** tag.|
| process | Name of the process running the application or ability. If the **process** attribute is configured in the **deviceConfig** tag, all abilities of the application run in this process. You can set the **process** attribute for a specific ability in the **abilities** attribute, so that the ability can run in the particular process.| / | The stage model does not support the configuration of process names.|
| keepAlive | Whether the application is always running. This attribute applies only to system applications and does not take effect for third-party applications.| / | The stage model does not support changing of the model control mode for system applications.|
| supportBackup | Whether the application supports data backup and restore.| / | This configuration is not supported in the stage model.|
| compressNativeLibs | Whether the **libs** libraries are packaged in the HAP file after being compressed.| / | This configuration is not supported in the stage model.|
| network | Network security configuration.| / | This configuration is not supported in the stage model.|
# Application- or Component-Level Configuration (FA Model)
When developing an application, you may need to configure certain tags to identify the application, such as the bundle name and application icon. This topic describes key tags that need to be configured during application development.
- **Configuring the bundle name**
The bundle name is specified by the **bundleName** field under **app** in the **config.json** file. This field uniquely identifies an application. The bundle name can contain only letters, digits, underscores (_), and periods (.). It must start with a letter. The bundle name is a string with 7 to 127 bytes of a reverse domain name, for example, **com.example.myapplication**. It is recommended that the first part is the top-level domain **"com"**, and the second part is the vendor or individual name, which can be of multiple levels. For details about the configuration, see [app](../quick-start/app-structure.md).
- **Configuring the application icon and label**
The FA model does not support direct configuration of application icons and labels. Instead, the icon and label of a PageAbility component that meet the rules are used as the application icon and label. For details about the rules, see [PageAbility Component](pageability-configuration.md). The icon is specified by the **icon** field under **abilities** in the **config.json** file. The icon must be configured in the resource file on DevEco Studio, and the path of the icon must be **/resource/base/media**. An example value is **$media:ability_icon**. The label is the index of the resource file. It identifies the name of the ability presented to users. The label value can be an ability name or a resource index to the ability name in multiple languages. In the **skills** attribute of the ability, if the **actions** value contains **action.system.home** and the **entities** value contains **entity.system.home**, the icon and label of the ability is used as the application icon and label. If multiple abilities address this condition, the icon and label of the first candidate ability is used as the application icon and label. For details about the configuration, see [abilities](../quick-start/module-structure.md).
```json
"abilities": [
"icon": "$media:icon",
"label": "$string:MainAbility_label",
"skills": [
{
"entities": ["entity.system.home"],
"actions": ["action.system.home"]
}
]
// ...
}
```
- **Configuring application version declaration**
To declare the application version, set the **version** field under **app** in the **config.json** file to specify the version number, version name, and earliest compatible version number. For details about the configuration, see [version](../quick-start/module-structure.md).
- **Configuring device types supported by the module**
To configure the device types supported by the module, set the **deviceType** field in the **config.json** file. If a certain device type is added to **deviceTypes**, the module can run on that device. For details about the configuration, see [deviceType](../quick-start/module-structure.md).
- **Configuring the component permission**
To request component permissions, set the **reqPermission** field under **module** in the **config.json** file. This field declares the name of the permission to request, the reason for requesting the permission, and the scenario where the permission is used. For details about the configuration, see [reqPermission](../quick-start/module-structure.md).
# Application- or Component-Level Configuration (Stage Model)
When developing an application, you may need to configure certain tags to identify the application, such as the bundle name and application icon. This topic describes key tags that need to be configured during application development. Icons and labels are usually configured together. There is the application icon, application label, entry icon, and entry label, which correspond to the **icon** and **label** fields in the [app.json5 file](../quick-start/app-configuration-file.md) and [module.json5 file](../quick-start/module-configuration-file.md). The application icon and label are used in **Settings**. For example, they are displayed in the application list in **Settings**. The entry icon is displayed on the device's home screen after the application is installed. The entry icon maps to a [UIAbility](uiability-overview.md) component. Therefore, an application can have multiple entry icons and labels. When you touch one of them, the corresponding UIAbility page is displayed.
**Figure 1** Icons and labels
![application-component-configuration-stage](figures/application-component-configuration-stage.png)
- **Configuring the bundle name**
The bundle name is specified by the **bundleName** field in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory of the project. This field uniquely identifies an application. You are advised to use the reverse domain name notion, for example, *com.example.demo*, where the first part is the domain suffix **com**, the second part is the vendor/individual name, and the third part is the application name, which can be of multiple levels.
- **Configuring the application icon and label**
You must configure an icon and label for an application on the stage model.
The application icon is specified by the **icon** field in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory of the project. The **icon** field must be set to the index of an image so that the image is displayed as the application icon.
The application label is specified by the **label** field in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** module of the project. The **label** field specifies the application name displayed to users. It must be set to the index of a string resource.
```json
{
"app": {
"icon": "$media:app_icon",
"label": "$string:app_name"
// ...
}
}
```
- **Configuring the entry icon and label**
On the stage model, you can configure an entry icon and label for each application component. The entry icon and label are displayed on the home screen.
The entry icon is configured by specifying **icon** under **abilities** in the [module.json5 file](../quick-start/module-configuration-file.md). For example, if you want to display the icon of the UIAbility component on the home screen, add **entity.system.home** to **entities** and **ohos.want.action.home** to **actions** under **skills**. If this field is configured for multiple UIAbility components of an application, multiple icons are displayed on the home screen, corresponding to their respective UIAbility component.
```json
{
"module": {
// ...
"abilities": [
{
// The information starting with $ is the resource value.
"icon": "$media:icon",
"label": "$string:EntryAbility_label",
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"ohos.want.action.home"
]
}
],
}
]
}
}
```
- **Configuring application version declaration**
To declare the application version, configure the **versionCode** and **versionName** fields in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory of the project. **versionCode** specifies the version number of the application. The value is a 32-bit non-negative integer. It is used only to determine whether a version is later than another version. A larger value indicates a later version. **versionName** provides the text description of the version number.
- **Configuring device types supported by the module**
To configure the device types supported by the module, set the **deviceTypes** field in the [module.json5 file](../quick-start/module-configuration-file.md). If a certain device type is added to **deviceTypes**, the module can run on that device.
- **Configuring the module permission**
The **requestPermission** field in the [module.json5 file](../quick-start/module-configuration-file.md) is used to configure the permission information required by the module to access the protected part of the system or other applications. This field declares the name of the permission to request, the reason for requesting the permission, and the scenario where the permission is used.
# Context (FA Model)
There is only one context in the FA model. All capabilities in the context are provided through methods. The context uses these methods to extend the capabilities of the **featureAbility** class.
## Available APIs
To use the context in the FA model, first import the **featureAbility** module.
```ts
import featureAbility from "@ohos.ability.featureAbility";
```
Then, call **getContext()** to obtain the **Context** object:
```ts
let context = featureAbility.getContext()
```
For details about the APIs, see [API Reference](../reference/apis/js-apis-inner-app-context.md).
## How to Develop
1. Query bundle information.
```ts
import featureAbility from '@ohos.ability.featureAbility'
export default {
onCreate() {
// Obtain the context and call related APIs.
let context = featureAbility.getContext();
context.getBundleName((data, bundleName)=>{
console.info("ability bundleName:" + bundleName)
});
console.info('Application onCreate')
},
onDestroy() {
console.info('Application onDestroy')
},
}
```
2. Set the display orientation of the host featureAbility.
```ts
import featureAbility from '@ohos.ability.featureAbility'
import bundle from '@ohos.bundle';
export default {
onCreate() {
// Obtain the context and call related APIs.
let context = featureAbility.getContext();
context.setDisplayOrientation(bundle.DisplayOrientation.LANDSCAPE).then(() => {
console.info("Set display orientation.")
})
console.info('Application onCreate')
},
onDestroy() {
console.info('Application onDestroy')
},
}
```
# Context (Stage Model)
## Overview
[Context](../reference/apis/js-apis-inner-application-context.md) is the context of an object in an application. It provides basic information about the application, for example, **resourceManager**, **applicationInfo**, **dir** (application development path), and **area** (encrypted area). It also provides basic methods such as **createBundleContext()** and **getApplicationContext()**. The UIAbility component and ExtensionAbility derived class components have their own **Context** classes, for example, the base class **Context**, **ApplicationContext**, **AbilityStageContext**, **UIAbilityContext**, **ExtensionContext**, and **ServiceExtensionContext**.
- The figure below illustrates the inheritance relationship of contexts.
![context-inheritance](figures/context-inheritance.png)
- The figure below illustrates the holding relationship of contexts.
![context-holding](figures/context-holding.png)
- The following describes the information provided by different contexts.
- [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md): Each UIAbility has the **Context** attribute, which provides APIs to operate an application component, obtain the application component configuration, and more.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let uiAbilityContext = this.context;
// ...
}
}
```
> **NOTE**
>
> For details about how to obtain the context of a **UIAbility** instance on the page, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability).
- Scenario-specific [ExtensionContext](../reference/apis/js-apis-inner-application-extensionContext.md): For example, ServiceExtensionContext, inherited from ExtensionContext, provides APIs related to background services.
```ts
import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility';
export default class MyService extends ServiceExtensionAbility {
onCreate(want) {
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**.
```ts
import AbilityStage from "@ohos.app.ability.AbilityStage";
export default class MyAbilityStage extends AbilityStage {
onCreate() {
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.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let applicationContext = this.context.getApplicationContext();
// ...
}
}
```
## Typical Usage Scenarios of Context
This topic describes how to use the context in the following scenarios:
- [Obtaining the Application Development Path](#obtaining-the-application-development-path)
- [Obtaining and Modifying Encrypted Areas](#obtaining-and-modifying-encrypted-areas)
- [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)
### Obtaining the Application Development Path
The following table describes the application development paths obtained from context.
**Table 1** Application development paths
| 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**.|
| tempDir | string | Yes| No| Temporary file directory of the application.<br>Files in this directory are deleted after the application is uninstalled.|
| 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.|
| databaseDir | string | Yes| No| Storage directory of the local database.|
| bundleCodeDir | string | Yes| No| Installation directory of the application on the internal storage.|
| distributedFilesDir | string | Yes| No| Storage directory of distributed application data files.|
| preferencesDir | string | Yes| Yes| Preferences directory of the application.|
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.
**Figure 1** Application development paths obtained from context
![context-dir](figures/context-dir.png)
- Obtain the application-level path through **ApplicationContext**. It is recommended that global application information be stored in this path. Files stored in this path will be deleted only when the application is uninstalled.
| Name| Path|
| -------- | -------- |
| bundleCodeDir | {Path prefix}/el1/bundle/|
| cacheDir | {Path prefix}/{Encryption level}/base/cache/|
| filesDir | {Path prefix}/{Encryption level}/base/files/|
| preferencesDir | {Path prefix}/{Encryption level}/base/preferences/|
| tempDir | {Path prefix}/{Encryption level}/base/temp/|
| databaseDir | {Path prefix}/{Encryption level}/database/|
| distributedFilesDir | {Path prefix}/el2/distributedFiles/|
- Obtain the HAP level path through **AbilityStageContext**, **UIAbilityContext**, and **ExtensionContext**. It is recommended that the HAP information be stored in this path. The file content stored in this path will be deleted when the HAP is uninstalled. The file content in the application-level path will be deleted only after all the HAPs of the application are uninstalled.
| Name| Path|
| -------- | -------- |
| bundleCodeDir | {Path prefix}/el1/bundle/|
| cacheDir | {Path prefix}/{Encryption level}/base/**haps/{moduleName}**/cache/|
| filesDir | {Path prefix}/{Encryption level}/base/**haps/{moduleName}**/files/|
| preferencesDir | {Path prefix}/{Encryption level}/base/**haps/{moduleName}**/preferences/|
| tempDir | {Path prefix}/{Encryption level}/base/**haps/{moduleName}**/temp/|
| databaseDir | {Path prefix}/{Encryption level}/database/**{moduleName}**/|
| distributedFilesDir | {Path prefix}/el2/distributedFiles/**{moduleName}**/|
The sample code for obtaining the application development paths is as follows:
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let cacheDir = this.context.cacheDir;
let tempDir = this.context.tempDir;
let filesDir = this.context.filesDir;
let databaseDir = this.context.databaseDir;
let bundleCodeDir = this.context.bundleCodeDir;
let distributedFilesDir = this.context.distributedFilesDir;
let preferencesDir = this.context.preferencesDir;
// ...
}
}
```
> **NOTE**
>
> 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
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:
- 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).
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
// Before storing common information, switch the encryption level to EL1.
if (this.context.area === 1) {// Obtain 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.
}
}
```
### 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.
- Call **createBundleContext(bundleName:string)** to create the context of another application.
> **NOTE**
>
> 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).
> - 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.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let bundleName2 = "com.example.application";
let context2 = this.context.createBundleContext(bundleName2);
let label2 = context2.applicationInfo.label;
// ...
}
}
```
- Call **createModuleContext(bundleName:string, moduleName:string)** to obtain the context of a specified module of another application. After obtaining the context, you can obtain the resource information of that module.
> **NOTE**
>
> 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).
> - This is a system API and cannot be called by third-party applications.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let bundleName2 = "com.example.application";
let moduleName2 = "module1";
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.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let moduleName2 = "module1";
let context2 = this.context.createModuleContext(moduleName2);
// ...
}
}
```
### 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.
[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.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
const TAG: string = "[Example].[Entry].[EntryAbility]";
export default class EntryAbility extends UIAbility {
lifecycleId: number;
onCreate(want, launchParam) {
let abilityLifecycleCallback = {
onAbilityCreate(uiability) {
console.info(TAG, "onAbilityCreate uiability:" + JSON.stringify(uiability));
},
onWindowStageCreate(uiability, windowStage) {
console.info(TAG, "onWindowStageCreate uiability:" + JSON.stringify(uiability));
console.info(TAG, "onWindowStageCreate windowStage:" + JSON.stringify(windowStage));
},
onWindowStageActive(uiability, windowStage) {
console.info(TAG, "onWindowStageActive uiability:" + JSON.stringify(uiability));
console.info(TAG, "onWindowStageActive windowStage:" + JSON.stringify(windowStage));
},
onWindowStageInactive(uiability, windowStage) {
console.info(TAG, "onWindowStageInactive uiability:" + JSON.stringify(uiability));
console.info(TAG, "onWindowStageInactive windowStage:" + JSON.stringify(windowStage));
},
onWindowStageDestroy(uiability, windowStage) {
console.info(TAG, "onWindowStageDestroy uiability:" + JSON.stringify(uiability));
console.info(TAG, "onWindowStageDestroy windowStage:" + JSON.stringify(windowStage));
},
onAbilityDestroy(uiability) {
console.info(TAG, "onAbilityDestroy uiability:" + JSON.stringify(uiability));
},
onAbilityForeground(uiability) {
console.info(TAG, "onAbilityForeground uiability:" + JSON.stringify(uiability));
},
onAbilityBackground(uiability) {
console.info(TAG, "onAbilityBackground uiability:" + JSON.stringify(uiability));
},
onAbilityContinue(uiability) {
console.info(TAG, "onAbilityContinue uiability:" + JSON.stringify(uiability));
}
}
// 1. Obtain the application context through the context attribute.
let applicationContext = this.context.getApplicationContext();
// 2. Register a listener for the lifecycle changes through the application context.
this.lifecycleId = applicationContext.on("abilityLifecycle", abilityLifecycleCallback);
console.info(TAG, "register callback number: " + JSON.stringify(this.lifecycleId));
}
onDestroy() {
let applicationContext = this.context.getApplicationContext();
applicationContext.off("abilityLifecycle", this.lifecycleId, (error, data) => {
console.info(TAG, "unregister callback success, err: " + JSON.stringify(error));
});
}
}
```
# Elements of the Application Model
The application model is the abstraction of capabilities required by OpenHarmony applications. It provides necessary components and running mechanisms for applications. With application models, you can develop applications based on a unified set of models, making application development simpler and more efficient.
The OpenHarmony application model consists of the following elements:
- Application component
An application component is the basic unit and running entry of an application. When a user starts, uses, or exits an application, the application component transits in different states. This is called the application component lifecycle. The application component provides lifecycle callback functions, through which you can detect application [status changes](uiability-lifecycle.md). When compiling an application, you needs to compile application components and their lifecycle callback functions, and configure related information in the application configuration file. In this way, the operating system creates an application component instance based on the configuration file during running, and schedules the lifecycle callback functions, so as to execute your code.
- Application process model
The application process model defines how application processes are created, destroyed, and communicate with each other.
- Application thread model
The application thread model defines how a thread in an application process is created and destroyed, how the main thread and UI thread are created, and how the threads communicate with each other.
- Application mission management model
The application mission management model defines how a mission is created and destroyed, and the relationship between missions and components. A mission is a record about the use of an application component instance. Each time a user starts an application component instance, a mission is generated. For example, when a user starts a video application, the video application mission is displayed on the **Recents** page. When the user clicks the mission, the system switches the mission to the foreground. If the video editing functionality in the video application is compiled by using an application component, an application component instance for video editing is created when the user starts video editing. In this case, both the video application mission and video editing mission are displayed on the **Recents** page.
- Application configuration file
The application configuration file contains information about the application configuration, application components, and permissions, as well as custom information. The information will be provided for the compiler, application market, and operating system in the build, distribution, and running phases.
# Interpretation of the Application Model
## Application Model Overview
Along its evolution, OpenHarmony has provided two application models:
- Feature Ability (FA) model. This model is supported by OpenHarmony API version 7 and 8. It is no longer recommended.
- Stage model. This model is supported since OpenHarmony API version 9. It is recommended and will evolve for a long time. In this model, classes such as **AbilityStage** and **WindowStage** are provided as the stage of application components and windows. That's why it is named stage model.
The stage model is designed based on the following considerations, which make it become the recommended model:
1. **Designed for complex applications**
- In the stage model, multiple application components share an ArkTS engine (VM running the programming language ArkTS) instance, making it easy for application components to share objects and status while requiring less memory.
- The object-oriented development mode makes the code of complex applications easy to read, maintain, and scale.
2. **Native support for [cross-device migration](hop-cross-device-migration.md) and [multi-device collaboration](hop-multi-device-collaboration.md) at the application component level**
The stage model decouples application components from User Interfaces (UIs).
- In cross-device migration scenarios, after the system migrates application component data or status between devices, it can use the declarative feature of ArkUI to restore the UI based on the data or status saved in the application components.
- In multi-device collaboration scenarios, application components can initiate Remote Procedure Calls (RPCs) and support interaction with cross-device application components.
3. **Support for multiple device types and window forms**
Application component management and window management are decoupled at the architecture level. This decoupling makes it:
- Easy to tailor application components. For example, windows can be tailored for devices without screens.
- Easy to extend the window forms.
- Possible for application components to use the same lifecycle on multiple devices (such as desktop devices and mobile devices).
4. **Well balanced application capabilities and system management costs**
The stage model redefines the boundary of application capabilities to well balance application capabilities and system management costs.
- Diverse application components (such as widgets and input methods) for specific scenarios.
- Standardized background process management. To deliver a better user experience, the stage model manages background application processes in a more orderly manner. Applications cannot reside in the background randomly, and their background behavior is strictly managed to minimize malicious behavior.
## Differences Between the FA Model and Stage Model
In the stage model, multiple application components share the same ArkTS engine instance. In the FA model, each application component exclusively uses an ArkTS engine instance. This is their biggest difference. In the stage model, application components can easily share objects and status while requiring less memory. Therefore, you are advised to use the stage model when developing complex applications in distributed scenarios.
The table below describes their differences in detail.
**Table 1** Differences between the FA model and stage model
| Item| FA model| Stage model|
| -------- | -------- | -------- |
| **Application component**| 1. Component classification<br>![fa-model-component](figures/fa-model-component.png)<br/>- PageAbility: has the UI and supports user interaction For details, see [PageAbility Component Overview](pageability-overview.md).<br>- ServiceAbility: provides background services and has no UI. For details, see [ServiceAbility Component Overview](serviceability-overview.md).<br>- DataAbility: provides the data sharing capability and has no UI. For details, see [DataAbility Component Overview](dataability-overview.md).<br>2. Development mode<br>Application components are specified by exporting anonymous objects and fixed entry files. You cannot perform derivation. It is inconvenient for capability expansion. | 1. Component classification<br>![stage-model-component](figures/stage-model-component.png)<br/> - UIAbility: has the UI and supports user interaction. For details, see [UIAbility Component Overview](uiability-overview.md).<br>- ExtensionAbility: provides extension capabilities (such as widget and input methods) for specific scenarios. For details, see [ExtensionAbility Component Overview](extensionability-overview.md).<br>2. Development mode<br>The object-oriented mode is used to provide open application components as classes. You can derive application components for capability expansion. |
| **Process model**| There are two types of processes:<br>1. Main process<br>2. Rendering process<br>For details, see [Process Model (FA Model)](process-model-fa.md).| There are three types of processes:<br>1. Main process<br>2. ExtensionAbility process<br>3. Rendering process<br>For details, see [Process Model (Stage Model)](process-model-stage.md).|
| **Thread model**| 1. ArkTS engine instance creation<br>A process can run multiple application component instances, and each application component instance runs in an independent ArkTS engine instance.<br>2. Thread model<br>Each ArkTS engine instance is created on an independent thread (non-main thread). The main thread does not have an ArkTS engine instance.<br>3. Intra-process object sharing: not supported.<br>For details, see [Thread Model (FA Model)](thread-model-fa.md).| 1. ArkTS engine instance creation<br>A process can run multiple application component instances, and all application component instances share one ArkTS engine instance.<br>2. Thread model<br>The ArkTS engine instance is created on the main thread.<br>3. Intra-process object sharing: supported.<br>For details, see [Thread Model (Stage Model)](thread-model-stage.md).|
| **Mission management model**| - A mission is created for each PageAbility component instance.<br>- Missions are stored persistently until the number of missions exceeds the maximum (customized based on the product configuration) or users delete missions.<br>- PageAbility components do not form a stack structure.<br>For details, see [Mission Management Scenarios](mission-management-overview.md).| - A mission is created for each UIAbility component instance.<br>- Missions are stored persistently until the number of missions exceeds the maximum (customized based on the product configuration) or users delete missions.<br>- UIAbility components do not form a stack structure.<br>For details, see [Mission Management Scenarios](mission-management-overview.md).|
| **Application configuration file**| The **config.json** file is used to describe the application, HAP, and application component information.<br>For details, see [Application Configuration File Overview (FA Model)](../quick-start/application-configuration-file-overview-fa.md).| The **app.json5** file is used to describe the application information, and the **module.json5** file is used to describe the HAP and application component information.<br>For details, see [Application Configuration File Overview (Stage Model)](../quick-start/application-configuration-file-overview-stage.md).|
# Background Services (Stage Model)
The stage model uses ServiceExtensionAbility to provide background services. A system application can implement a background service and provide external capabilities. For example, if system application A implements a background service, third-party application B can communicate with A by connecting to A's background service.
For details about ServiceExtensionAbility, see [Background Service Development](serviceextensionability.md).
# Connecting to a ServiceAbility from the Stage Model
This topic describes how the two application components of the stage model connect to the ServiceAbility component of the FA model.
## UIAbility Accessing a ServiceAbility
A UIAbility accesses a ServiceAbility in the same way as it accesses a ServiceExtensionAbility.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
console.info("EntryAbility onCreate");
}
onDestroy() {
console.info("EntryAbility onDestroy")
}
onWindowStageCreate(windowStage) {
console.info("EntryAbility onWindowStageCreate")
let want = {
bundleName: "com.ohos.fa",
abilityName: "ServiceAbility",
};
let options = {
onConnect:function (elementName, proxy) {
console.info("onConnect called.");
},
onDisconnect:function (elementName) {
console.info("onDisconnect called.");
},
onFailed:function (code) {
console.info("onFailed code is: " + code);
}
};
let connectionId = this.context.connectServiceExtensionAbility(want, options);
}
onWindowStageDestroy() {
console.info("EntryAbility onWindowStageDestroy")
}
onForeground() {
console.info("EntryAbility onForeground")
}
onBackground() {
console.info("EntryAbility onBackground")
}
}
```
## ExtensionAbility Accessing a ServiceAbility
The following uses the ServiceExtensionAbility component as an example to describe how an ExtensionAbility accesses a ServiceAbility. A ServiceExtensionAbility accesses a ServiceAbility in the same way as it accesses another ServiceExtensionAbility.
```ts
import Extension from '@ohos.app.ability.ServiceExtensionAbility'
export default class ServiceExtension extends Extension {
onCreate(want) {
console.info("ServiceExtension onCreate")
}
onDestroy() {
console.info("ServiceExtension onDestroy")
}
onRequest(want, startId) {
console.info("ServiceExtension onRequest")
let wantFA = {
bundleName: "com.ohos.fa",
abilityName: "ServiceAbility",
};
let options = {
onConnect:function (elementName, proxy) {
console.info("onConnect called.");
},
onDisconnect:function (elementName) {
console.info("onDisconnect called.");
},
onFailed:function (code) {
console.info("onFailed code is: " + code);
}
};
let connectionId = this.context.connectServiceExtensionAbility(wantFA, options);
}
}
```
# Connecting to a ServiceExtensionAbility from the FA Model
This topic describes how the three application components of the FA model connect to the ServiceExtensionAbility component of the stage model.
## PageAbility Accessing a ServiceExtensionAbility
A PageAbility accesses a ServiceExtensionAbility in the same way as it accesses a ServiceAbility.
```ts
import featureAbility from '@ohos.ability.featureAbility';
let want = {
bundleName: "com.ohos.stage",
abilityName: "com.ohos.stage.ServiceExtensionAbility"
};
let faConnect = {
onConnect:function (elementName, proxy) {
console.info("Faconnection onConnect called.");
},
onDisconnect:function (elementName) {
console.info("Faconnection onDisconnect called.");
},
onFailed:function (code) {
console.info("Faconnection onFailed code is: " + code);
}
};
let connectionId = featureAbility.connectAbility(want, faConnect);
```
## ServiceAbility or DataAbility Accessing a ServiceExtensionAbility
A ServiceAbility or DataAbility accesses a ServiceExtensionAbility in the same way as it accesses a ServiceAbility.
```ts
import particleAbility from '@ohos.ability.particleAbility';
let want = {
bundleName: "com.ohos.stage",
abilityName: "com.ohos.stage.ServiceExtensionAbility"
};
let faConnect = {
onConnect:function (elementName, proxy) {
console.info("Faconnection onConnect called.");
},
onDisconnect:function (elementName) {
console.info("Faconnection onDisconnect called.");
},
onFailed:function (code) {
console.info("Faconnection onFailed code is: " + code);
}
};
let connectionId = particleAbility.connectAbility(want, faConnect);
```
# Common Events (FA Model)
For details, see [Common Events](common-event-overview.md) in the stage model.
# Introduction to Common Events
OpenHarmony provides Common Event Service (CES) for applications to subscribe to, publish, and unsubscribe from common events.
Common events are classified into system common events and custom common events.
- System common events: defined in CES. Only system applications and system services can publish system common events, such as HAP installation, update, and uninstall. For details about the supported system common events, see [Support](../reference/apis/js-apis-commonEventManager.md#support).
- Custom common events: customized by applications to implement cross-process event communication.
Common events are also classified into unordered, ordered, and sticky common events.
- Unordered common events: common events that CES forwards regardless of whether subscribers receive the events and when they subscribe to the events.
- Ordered common events: common events that CES forwards based on the subscriber priority. CES forwards common events to the subscriber with lower priority only after receiving a reply from the previous subscriber with higher priority. Subscribers with the same priority receive common events in a random order.
- Sticky common events: common events that can be sent to a subscriber before or after they initiate a subscription. Only system applications and system services can send sticky common events, which remain in the system after being sent. The sends must first request the **ohos.permission.COMMONEVENT_STICKY** permission. For details about the configuration, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
Each application can subscribe to common events as required. After your application subscribes to a common event, the system sends it to your application every time the event is published. Such an event may be published by the system, other applications, or your own application.
**Figure 1** Common events
![common-event](figures/common-event.png)
\ No newline at end of file
# Publishing Common Events
## When to Use
You can use [publish()](../reference/apis/js-apis-commonEventManager.md#commoneventmanagerpublish) to publish a custom common event, which can carry data for subscribers to parse and process.
> **NOTE**
>
> Subscribers can receive sticky common events that have been sent. However, they must subscribe to common events of other types before receiving them. For details about subscription, see [Subscribing to Common Events](common-event-subscription.md).
## Available APIs
For details about the APIs, see [API Reference](../reference/apis/js-apis-commonEventManager.md#commoneventmanagerpublish).
| API| Description|
| -------- | -------- |
| publish(event: string, callback: AsyncCallback) | Publishes a common event.|
| publish(event: string, options: [CommonEventPublishData](../reference/apis/js-apis-commonEventManager.md#commoneventpublishdata), callback: AsyncCallback) | Publishes a common event with given attributes.|
## Publishing a Common Event That Does Not Carry Information
Common events that do not carry information can be published only as unordered common events.
1. Import the **commonEventManager** module.
```ts
import commonEventManager from '@ohos.commonEventManager';
```
2. Pass in the common event name and callback, and publish the event.
```ts
// Publish a common event.
commonEventManager.publish("usual.event.SCREEN_OFF", (err) => {
if (err) {
console.error(`[CommonEvent] PublishCallBack err=${JSON.stringify(err)}`);
} else {
console.info(`[CommonEvent] Publish success`);
}
})
```
## Publishing a Common Event That Carries Information
Common events that carry information can be published as unordered, ordered, and sticky common events, which are specified by the **isOrdered** and **isSticky** fields of [CommonEventPublishData](../reference/apis/js-apis-commonEventManager.md#commoneventpublishdata).
1. Import the **commonEventManager** module.
```ts
import commonEventManager from '@ohos.commonEventManager';
```
2. Pass in the common event name and callback, and publish the event.
```ts
// Attributes of a common event.
let options = {
code: 1, // Result code of the common event.
data: "initial data", // Result data of the common event.
}
```
3. Pass in the common event name, attributes of the common event, and callback, and publish the event.
```ts
// Publish a common event.
commonEventManager.publish("usual.event.SCREEN_OFF", options, (err) => {
if (err) {
console.error('[CommonEvent] PublishCallBack err=' + JSON.stringify(err));
} else {
console.info('[CommonEvent] Publish success')
}
})
```
# Subscribing to Common Events in Static Mode (for System Applications Only)
## When to Use
A static subscriber is started once it receives a target event published by the system or application. At the same time, the **onReceiveEvent** callback is triggered, in which you can implement the service logic. For example, if an application needs to execute some initialization tasks during device power-on, the application can subscribe to the power-on event in static mode. After receiving the power-on event, the application is started to execute the initialization tasks. Subscribing to a common event in static mode is achieved by configuring a declaration file and implementing a class that inherits from **StaticSubscriberExtensionAbility**. Note that this subscribing mode has negative impact on system power consumption. Therefore, exercise caution when using this mode.
## How to Develop
1. Declaring a Static Subscriber
To declare a static subscriber, create an ExtensionAbility, which is derived from the **StaticSubscriberExtensionAbility** class, in the project. The sample code is as follows:
```ts
import StaticSubscriberExtensionAbility from '@ohos.application.StaticSubscriberExtensionAbility'
export default class StaticSubscriber extends StaticSubscriberExtensionAbility {
onReceiveEvent(event) {
console.log('onReceiveEvent, event:' + event.event);
}
}
```
You can implement service logic in the **onReceiveEvent** callback.
2. Project Configuration for a Static Subscriber
After writing the static subscriber code, configure the subscriber in the **module.json5** file. The configuration format is as follows:
```ts
{
"module": {
......
"extensionAbilities": [
{
"name": "StaticSubscriber",
"srcEntrance": "./ets/StaticSubscriber/StaticSubscriber.ts",
"description": "$string:StaticSubscriber_desc",
"icon": "$media:icon",
"label": "$string:StaticSubscriber_label",
"type": "staticSubscriber",
"visible": true,
"metadata": [
{
"name": "ohos.extension.staticSubscriber",
"resource": "$profile:subscribe"
}
]
}
]
......
}
}
```
Pay attention to the following fields in the JSON file:
- **srcEntrance**: entry file path of the ExtensionAbility, that is, the file path of the static subscriber declared in Step 2.
- **type**: ExtensionAbility type. For a static subscriber, set this field to **staticSubscriber**.
- **metadata**: level-2 configuration file information of the ExtensionAbility. The configuration information varies according to the ExtensionAbility type. Therefore, you must use different config files to indicate the specific configuration.
- **name**: name of the ExtensionAbility. For a static subscriber, declare the name as **ohos.extension.staticSubscriber** for successful identification.
- **resource**: path that stores the ExtensionAbility configuration, which is customizable. In this example, the path is **resources/base/profile/subscribe.json**.
A level-2 configuration file pointed to by **metadata** must be in the following format:
```ts
{
"commonEvents": [
{
"name": "xxx",
"permission": "xxx",
"events":[
"xxx"
]
}
]
}
```
If the level-2 configuration file is not declared in this format, the file cannot be identified. The fields are described as follows:
- **name**: name of the ExtensionAbility, which must be the same as the name of **extensionAbility** declared in **module.json5**.
- **permission**: permission required for the publisher. If a publisher without the required permission attempts to publish an event, the event is regarded as invalid and will not be published.
- **events**: list of target events to subscribe to.
3. Device System Configuration
In the device system configuration file **/system/etc/app/install_list_capability.json**, add the bundle name of the static subscriber.
```json
{
"install_list": [
{
"bundleName": "ohos.extension.staticSubscriber",
"allowCommonEvent": ["usual.event.A", "usual.event.B"],
}
]
}
```
# Common Event Subscription Overview
​The common event service provides two subscription modes: dynamic and static. The biggest difference between these two modes is that dynamic subscription requires the application to be running, while static subscription does not.
- In dynamic subscription mode, a subscriber subscribes to common events by calling an API during the running period. For details, see [Subscribing to Common Events in Dynamic Mode](common-event-subscription.md).
- In static subscription mode, a subscriber subscribes to common events by configuring a declaration file and implementing a class that inherits from StaticSubscriberExtensionAbility. For details, see [Subscribing to Common Events in Static Mode](common-event-static-subscription.md).
# Subscribing to Common Events in Dynamic Mode
## When to Use
In dynamic subscription mode, an application subscribes to a common event when it is running. If the subscribed event is published during the running period, the subscriber application will receive the event, together with the parameters passed in the event. For example, if an application expects to be notified of low battery so that it can reduce power consumption accordingly when running, then the application can subscribe to the low-battery event. Upon receiving the event, the application can close some unnecessary tasks to reduce power consumption. Certain system common events [require specific permissions](../security/accesstoken-guidelines.md) to subscribe to. For details, see [Required Permissions](../reference/apis/js-apis-commonEventManager.md#support).
## Available APIs
For details about the APIs, see [API Reference](../reference/apis/js-apis-commonEventManager.md#commoneventmanagersubscribe).
| API| Description|
| -------- | -------- |
| createSubscriber(subscribeInfo: [CommonEventSubscribeInfo](../reference/apis/js-apis-commonEventManager.md#commoneventsubscribeinfo), callback: AsyncCallback&lt;[CommonEventData](../reference/apis/js-apis-commonEventManager.md#commoneventdata)&gt;): void | Creates a subscriber. This API uses an asynchronous callback to return the result.|
| createSubscriber(subscribeInfo: CommonEventSubscribeInfo): Promise&lt;CommonEventSubscriber&gt; | Creates a subscriber. This API uses a promise to return the result.|
| subscribe(subscriber: CommonEventSubscriber, callback: AsyncCallback): void | Subscribes to common events.|
## How to Develop
1. Import the **commonEventManager** module.
```ts
import commonEventManager from '@ohos.commonEventManager';
```
2. Create a **subscribeInfo** object. For details about the data types and parameters of the object, see [CommonEventSubscribeInfo](../reference/apis/js-apis-commonEventManager.md#commoneventsubscribeinfo).
```ts
// Used to save the created subscriber object for subsequent subscription and unsubscription.
let subscriber = null;
// Subscriber information.
let subscribeInfo = {
events: ["usual.event.SCREEN_OFF"], // Subscribe to the common event screen-off.
}
```
3. Create a subscriber object and save the returned object for subsequent operations such as subscription and unsubscription.
```ts
// Callback for subscriber creation.
commonEventManager.createSubscriber(subscribeInfo, (err, data) => {
if (err) {
console.error(`[CommonEvent] CreateSubscriberCallBack err=${JSON.stringify(err)}`);
} else {
console.info(`[CommonEvent] CreateSubscriber success`);
subscriber = data;
// Callback for common event subscription.
}
})
```
4. Create a subscription callback, which is triggered when an event is received. The data returned in the subscription callback contains information such as the common event name and data carried by the publisher. For details about the data types and parameters of the common event data, see [CommonEventData](../reference/apis/js-apis-commonEventManager.md#commoneventdata).
```ts
// Callback for common event subscription.
if (subscriber !== null) {
commonEventManager.subscribe(subscriber, (err, data) => {
if (err) {
console.error(`[CommonEvent] SubscribeCallBack err=${JSON.stringify(err)}`);
} else {
console.info(`[CommonEvent] SubscribeCallBack data=${JSON.stringify(data)}`);
}
})
} else {
console.error(`[CommonEvent] Need create subscriber`);
}
```
# Unsubscribing from Common Events in Dynamic Mode
## When to Use
You can call [unsubscribe()](../reference/apis/js-apis-commonEventManager.md#commoneventmanagerunsubscribe) to unsubscribe from a common event that is no longer required in dynamic mode.
## Available APIs
| API| Description|
| -------- | -------- |
| unsubscribe(subscriber: CommonEventSubscriber, callback?: AsyncCallback) | Unsubscribes from a common event.|
## How to Develop
1. Import the **commonEventManager** module.
```ts
import commonEventManager from '@ohos.commonEventManager';
```
2. Subscribe to an event by following the procedure described in [Subscribing to Common Events in Dynamic Mode](common-event-subscription.md).
3. Call **unsubscribe** in **CommonEvent** to unsubscribe from the common event.
```ts
// The subscriber object is created during event subscription.
if (subscriber !== null) {
commonEventManager.unsubscribe(subscriber, (err) => {
if (err) {
console.error(`[CommonEvent] UnsubscribeCallBack err=${JSON.stringify(err)}`);
} else {
console.info(`[CommonEvent] Unsubscribe`);
subscriber = null;
}
})
}
```
# Component Startup Rules (FA Model)
Component startup refers to the behavior of starting or connecting to an application component.
- Start the PageAbility and ServiceAbility. For example, you can use **startAbility()**.
- Connect to the ServiceAbility and DataAbility. For example, you can use **connectAbility()** and **acquireDataAbilityHelper()**.
To deliver a better user experience, OpenHarmony restricts the following behavior:
- A background application randomly displays a dialog box, such as an ads pop-up.
- Background applications wake up each other. This type of behavior occupies system resources and increases power consumption, or even causes system frozen.
- A foreground application randomly redirects to another application, for example, redirecting to the payment page of another application. This type of behavior poses security risks.
In view of this, OpenHarmony formulates a set of component startup rules, as follows:
- **Before starting a component of another application, verify the visible field of the target component.**
- This rule applies only to cross-application scenarios.
- If the **visible** field of the target component is **false**, verify the **ohos.permission.START_INVISIBLE_ABILITY** permission.
- For details, see [Component Visible Configuration](../quick-start/module-configuration-file.md#abilities).
- **Before starting a component of a background application, verify the BACKGROUND permission.**
- 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.
- **Before starting the ServiceAbility or DataAbility component of an application, verify the AssociateWakeUp field of the target application.**
- This rule applies only to cross-application scenarios.
- This rule is valid only when the target component is ServiceAbility or DataAbility.
- The ServiceAbility and DataAbility of an application can be accessed by others only when **AssociateWakeUp** of the target application is set to **true**.
- The **AssociateWakeUp** field can be configured only for preset applications. For other applications, this field is set to **false** by default.
> **NOTE**
> 1. Component startup control has been implemented since OpenHarmony v3.2 Release.
>
> 2. The new component startup rules are more strict than the original ones. You must be familiar with the new startup rules to prevent service exceptions.
## Intra-Device Component Startup Rules
The rules for starting components on the same device vary in the following scenarios:
- Starting a PageAbility
- Starting a ServiceAbility or DataAbility
![startup-rule](figures/component-startup-inner-fa.png)
## Inter-Device Component Startup Rules
The rules for starting components on a different device vary in the following scenarios:
- Starting a PageAbility
- Starting a ServiceAbility
![component-startup-rules](figures/component-startup-inter-fa.png)
# Component Startup Rules (Stage Model)
Component startup refers to the behavior of starting or connecting to an application component.
- Start the UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility components. For example, you can use **startAbility()**, **startServiceExtensionAbility()**, and **startAbilityByCall()**.
- Connect to the ServiceExtensionAbility and DataShareExtensionAbility components. For example, you can use **connectServiceExtensionAbility()** and **createDataShareHelper()**.
To deliver a better user experience, OpenHarmony restricts the following behavior:
- A background application randomly displays a dialog box, such as an ads pop-up.
- Background applications wake up each other. This type of behavior occupies system resources and increases power consumption, or even causes system frozen.
- A foreground application randomly redirects to another application, for example, redirecting to the payment page of another application. This type of behavior poses security risks.
In view of this, OpenHarmony formulates a set of component startup rules, as follows:
- **Before starting a component of another application, verify the visible field of the target component.**
- If the **visible** field of the target component is **false**, verify the **ohos.permission.START_INVISIBLE_ABILITY** permission.
- For details, see [Component Visible Configuration](../quick-start/module-configuration-file.md#abilities).
- **Before starting a component of a background application, verify the BACKGROUND permission.**
- 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.
- **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).
- Verify the **ohos.permission.ABILITY_BACKGROUND_COMMUNICATION** permission.
> **NOTE**
>
> - Component startup control has been implemented since OpenHarmony v3.2 Release.
>
> - The new component startup rules are more strict than the original ones. You must be familiar with the new startup rules to prevent service exceptions.
## Intra-Device Component Startup Rules
The rules for starting components on the same device vary in the following scenarios:
- Starting or connecting to the UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility components
- Using **startAbilityByCall()** to start the UIAbility component
![startup-rule](figures/component-startup-inner-stage.png)
## Inter-Device Component Startup Rules
The rules for starting components on a different device vary in the following scenarios:
- Starting or connecting to the UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility components
- Using **startAbilityByCall()** to start the UIAbility component
![component-startup-rules](figures/component-startup-inter-stage.png)
# Application Configuration File (FA Model)
The application configuration file contains information about the application configuration, application components, and permissions, as well as custom information. The information will be provided for the compiler, application market, and operating system in the build, distribution, and running phases.
The application project code developed based on the FA model contains a **config.json** file. For details about common configuration items, see [Application- or Component-Level Configuration](application-component-configuration-fa.md). For details about the file, see [Application Configuration File Overview (FA Model)](../quick-start/application-configuration-file-overview-fa.md).
# Application Configuration File (Stage Model)
The application configuration file contains information about the application configuration, application components, and permissions, as well as custom information. The information will be provided for the compiler, application market, and operating system in the build, distribution, and running phases.
The application project code developed based on the stage model contains one **app.json5** file and one or more **module.json5** files. For details about common configuration items, see [Application- or Component-Level Configuration (Stage Model)](application-component-configuration-stage.md). For details about the two files, see [Application Configuration File Overview (Stage Model)](../quick-start/application-configuration-file-overview-stage.md).
# Differences in Configuration Files
The FA model uses the [config.json file](../quick-start/application-configuration-file-overview-fa.md) to describe the basic information about an application. An application can have multiple modules, and each module has a **config.json** file. The **config.json** file consists of three parts: **app**, **deviceConfig**, and **module**. The **app** tag is used to configure application-level attributes. If an application has multiple modules, the **app** configuration in each **config.json** file must be consistent.
The stage model uses the [app.json5](../quick-start/app-configuration-file.md) and [module.json](../quick-start/module-configuration-file.md) files to describe the basic information about an application. An application can have multiple modules but only one **app.json5** file. This file is used to configure application-level attributes and takes effect for all the modules. Each module has a **module.json5** file, which is used to configure module-level attributes and takes effect only for the current module.
**Figure 1** Configuration file differences
![comparison-of-configuration-file](figures/comparison-of-configuration-file.png)
# Connecting to a ServiceAbility
If a ServiceAbility wants to interact with a PageAbility or a ServiceAbility in another application, you must first create a connection by calling **connectAbility()**. This method is defined in the **featureAbility** class for the PageAbility and in the **particleAbility** class for the ServiceAbility. For details about the connection rules, see [Component Startup Rules](component-startup-rules.md). When calling **connectAbility()**, you should pass in a **Want** object containing information about the target ServiceAbility and an **IAbilityConnection** object. **IAbilityConnection** provides the following APIs that you need to implement.
**Table 1** IAbilityConnection APIs
| API| Description|
| -------- | -------- |
| onConnect() | Callback invoked when the ServiceAbility is connected.|
| onDisconnect() | Callback invoked when the ServiceAbility is disconnected.|
| onFailed() | Callback invoked when the connection to the ServiceAbility fails.|
The following sample code enables the PageAbility to create connection callback instances and connect to the local ServiceAbility:
```ts
import rpc from "@ohos.rpc"
import prompt from '@system.prompt'
import featureAbility from '@ohos.ability.featureAbility'
let option = {
onConnect: function onConnectCallback(element, proxy) {
console.info(`onConnectLocalService onConnectDone`)
if (proxy === null) {
prompt.showToast({
message: "Connect service failed"
})
return
}
let data = rpc.MessageParcel.create()
let reply = rpc.MessageParcel.create()
let option = new rpc.MessageOption()
data.writeInterfaceToken("connect.test.token")
proxy.sendRequest(0, data, reply, option)
prompt.showToast({
message: "Connect service success"
})
},
onDisconnect: function onDisconnectCallback(element) {
console.info(`onConnectLocalService onDisconnectDone element:${element}`)
prompt.showToast({
message: "Disconnect service success"
})
},
onFailed: function onFailedCallback(code) {
console.info(`onConnectLocalService onFailed errCode:${code}`)
prompt.showToast({
message: "Connect local service onFailed"
})
}
}
let request = {
bundleName: "com.example.myapplication",
abilityName: "com.example.myapplication.ServiceAbility",
}
let connId = featureAbility.connectAbility(request, option)
```
When the ServiceAbility is connected, the **onConnect()** callback is invoked and returns an **IRemoteObject** defining the proxy used for communicating with the ServiceAbility. OpenHarmony provides a default implementation of **IRemoteObject**. You can extend **rpc.RemoteObject** to implement your own class of **IRemoteObject**.
The following sample code shows how the ServiceAbility returns itself to the caller:
```ts
import rpc from "@ohos.rpc"
class FirstServiceAbilityStub extends rpc.RemoteObject {
constructor(des: any) {
if (typeof des === 'string') {
super(des)
} else {
return
}
}
onRemoteRequest(code: number, data: any, reply: any, option: any) {
console.info(`onRemoteRequest called`)
if (code === 1) {
let string = data.readString()
console.info(`string=${string}`)
let result = Array.from(string).sort().join('')
console.info(`result=${result}`)
reply.writeString(result)
} else {
console.info(`unknown request code`)
}
return true
}
}
```
# Context Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API or Field in the Stage Model|
| -------- | -------- | -------- |
| [getOrCreateLocalDir(callback:AsyncCallback&lt;string&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetorcreatelocaldir7)<br>[getOrCreateLocalDir():Promise&lt;string&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetorcreatelocaldir7-1) | There is no corresponding API in the stage model.| Applications developed on the stage model do not have the operation permission in the application root directory. Therefore, no corresponding API is provided.|
| [verifyPermission(permission:string,options:PermissionOptions,callback:AsyncCallback&lt;number&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextverifypermission7)<br>[verifyPermission(permission:string,callback:AsyncCallback&lt;number&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextverifypermission7-1)<br>[verifyPermission(permission:string,options?:PermissionOptions):Promise&lt;number&gt;;](../reference/apis/js-apis-inner-app-context.md#contextverifypermission7-2) | \@ohos.abilityAccessCtrl.d.ts | [verifyAccessTokenSync(tokenID: number, permissionName: Permissions): GrantStatus;](../reference/apis/js-apis-abilityAccessCtrl.md#verifyaccesstokensync9)<br>[verifyAccessToken(tokenID: number, permissionName: Permissions): Promise&lt;GrantStatus&gt;;](../reference/apis/js-apis-abilityAccessCtrl.md#verifyaccesstoken9) |
| [requestPermissionsFromUser(permissions:Array&lt;string&gt;,requestCode:number,resultCallback:AsyncCallback&lt;PermissionRequestResult&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7)<br>[requestPermissionsFromUser(permissions:Array&lt;string&gt;,requestCode:number):Promise&lt;PermissionRequestResult&gt;;](../reference/apis/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7-1) | application\UIAbilityContext.d.ts | [requestPermissionsFromUser(permissions: Array&lt;string&gt;, requestCallback: AsyncCallback&lt;PermissionRequestResult&gt;) : void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextrequestpermissionsfromuser)<br>[requestPermissionsFromUser(permissions: Array&lt;string&gt;) : Promise&lt;PermissionRequestResult&gt;;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextrequestpermissionsfromuser-1) |
| [getApplicationInfo(callback:AsyncCallback&lt;ApplicationInfo&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetapplicationinfo7)<br>[getApplicationInfo():Promise&lt;ApplicationInfo&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetapplicationinfo7-1) | application\Context.d.ts | [applicationInfo: ApplicationInfo;](../reference/apis/js-apis-inner-application-context.md#attributes)|
| [getBundleName(callback : AsyncCallback&lt;string&gt;): void;](../reference/apis/js-apis-inner-app-context.md#contextgetbundlename7)<br>[getBundleName(): Promise&lt;string&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetbundlename7-1) | application\UIAbilityContext.d.ts | [abilityInfo.bundleName: string;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#attributes)|
| [getDisplayOrientation(callback : AsyncCallback&lt;bundle.DisplayOrientation&gt;): void;](../reference/apis/js-apis-inner-app-context.md#contextgetdisplayorientation7)<br>[getDisplayOrientation(): Promise&lt;bundle.DisplayOrientation&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetdisplayorientation7-1) | \@ohos.screen.d.ts | [readonly orientation: Orientation;](../reference/apis/js-apis-screen.md#orientation) |
| [setDisplayOrientation(orientation:bundle.DisplayOrientation, callback:AsyncCallback&lt;void&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextsetdisplayorientation7)<br>[setDisplayOrientation(orientation:bundle.DisplayOrientation):Promise&lt;void&gt;;](../reference/apis/js-apis-inner-app-context.md#contextsetdisplayorientation7-1) | \@ohos.screen.d.ts | [setOrientation(orientation: Orientation, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-screen.md#setorientation)<br>[setOrientation(orientation: Orientation): Promise&lt;void&gt;;](../reference/apis/js-apis-screen.md#setorientation-1) |
| [setShowOnLockScreen(show:boolean, callback:AsyncCallback&lt;void&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextsetshowonlockscreen7)<br>[setShowOnLockScreen(show:boolean):Promise&lt;void&gt;;](../reference/apis/js-apis-inner-app-context.md#contextsetshowonlockscreen7-1) | \@ohos.window.d.ts | [setShowOnLockScreen(showOnLockScreen: boolean): void;](../reference/apis/js-apis-window.md#setshowonlockscreen9) |
| [setWakeUpScreen(wakeUp:boolean, callback:AsyncCallback&lt;void&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextsetwakeupscreen7)<br>[setWakeUpScreen(wakeUp:boolean):Promise&lt;void&gt;;](../reference/apis/js-apis-inner-app-context.md#contextsetwakeupscreen7-1) | \@ohos.window.d.ts | [setWakeUpScreen(wakeUp: boolean): void;](../reference/apis/js-apis-window.md#setwakeupscreen9) |
| [getProcessInfo(callback:AsyncCallback&lt;ProcessInfo&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetprocessinfo7)<br>[getProcessInfo():Promise&lt;ProcessInfo&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetprocessinfo7-1) | \@ohos.app.ability.abilityManager.d.ts | [getAbilityRunningInfos(callback: AsyncCallback&lt;Array&lt;AbilityRunningInfo&gt;&gt;): void;](../reference/apis/js-apis-app-ability-abilityManager.md#getabilityrunninginfos)<br>[getAbilityRunningInfos(): Promise&lt;Array&lt;AbilityRunningInfo&gt;&gt;;](../reference/apis/js-apis-app-ability-abilityManager.md#getabilityrunninginfos-1) |
| [getElementName(callback:AsyncCallback&lt;ElementName&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetelementname7)<br>[getElementName():Promise&lt;ElementName&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetelementname7-1) | application\UIAbilityContext.d.ts | [abilityInfo.name: string;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#attributes)<br>[abilityInfo.bundleName: string;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#attributes)|
| [getProcessName(callback:AsyncCallback&lt;string&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetprocessname7)<br>[getProcessName():Promise&lt;string&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetprocessname7-1) | \@ohos.app.ability.abilityManager.d.ts | [getAbilityRunningInfos(callback: AsyncCallback&lt;Array&lt;AbilityRunningInfo&gt;&gt;): void;](../reference/apis/js-apis-app-ability-abilityManager.md#getabilityrunninginfos)<br>[getAbilityRunningInfos(): Promise&lt;Array&lt;AbilityRunningInfo&gt;&gt;;](../reference/apis/js-apis-app-ability-abilityManager.md#getabilityrunninginfos-1) |
| [getCallingBundle(callback:AsyncCallback&lt;string&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetcallingbundle7)<br>[getCallingBundle():Promise&lt;string&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetcallingbundle7-1) | There is no corresponding API in the stage model.| Applications developed on the stage model can use the **ohos.aafwk.param.callerUid** parameter of **Want.parameters** to obtain the application information of the caller.|
| [getFilesDir(callback:AsyncCallback&lt;string&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetfilesdir)<br>[getFilesDir():Promise&lt;string&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetfilesdir-1) | application\Context.d.ts | [filesDir: string;](../reference/apis/js-apis-inner-application-context.md#attributes)|
| [getCacheDir(callback:AsyncCallback&lt;string&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetcachedir)<br>[getCacheDir():Promise&lt;string&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetcachedir-1) | application\Context.d.ts | [cacheDir: string;](../reference/apis/js-apis-inner-application-context.md#attributes)|
| [getOrCreateDistributedDir(callback:AsyncCallback&lt;string&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetorcreatedistributeddir7)<br>[getOrCreateDistributedDir():Promise&lt;string&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetorcreatedistributeddir7-1) | application\Context.d.ts | [distributedFilesDir: string;](../reference/apis/js-apis-inner-application-context.md#attributes)|
| [getAppType(callback:AsyncCallback&lt;string&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetapptype7)<br>[getAppType():Promise&lt;string&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetapptype7-1) | application\UIAbilityContext.d.ts | The stage model obtains the application type through the **type** attribute of the **abilityInfo** field.<br>[abilityInfo.type: bundleManager.AbilityType;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#attributes)|
| [getHapModuleInfo(callback:AsyncCallback&lt;HapModuleInfo&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgethapmoduleinfo7)<br>[getHapModuleInfo():Promise&lt;HapModuleInfo&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgethapmoduleinfo7-1) | application\UIAbilityContext.d.ts | [currentHapModuleInfo: HapModuleInfo;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#attributes)|
| [getAppVersionInfo(callback:AsyncCallback&lt;AppVersionInfo&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetappversioninfo7)<br>[getAppVersionInfo():Promise&lt;AppVersionInfo&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetappversioninfo7-1) | bundle\bundleInfo.d.ts | [readonly name: string;](../reference/apis/js-apis-bundleManager-bundleInfo.md#bundleinfo-1)<br>[readonly versionCode: number;](../reference/apis/js-apis-bundleManager-bundleInfo.md#bundleinfo-1)<br>[readonly versionName: string;](../reference/apis/js-apis-bundleManager-bundleInfo.md#bundleinfo-1) |
| [getApplicationContext():Context;](../reference/apis/js-apis-inner-app-context.md#contextgetapplicationcontext7) | application\Context.d.ts | [getApplicationContext(): ApplicationContext;](../reference/apis/js-apis-inner-application-context.md#contextgetapplicationcontext) |
| [getAbilityInfo(callback:AsyncCallback&lt;AbilityInfo&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetabilityinfo7)<br>[getAbilityInfo():Promise&lt;AbilityInfo&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetabilityinfo7-1) | application\UIAbilityContext.d.ts | [abilityInfo: AbilityInfo;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#attributes)|
| [isUpdatingConfigurations(callback:AsyncCallback&lt;boolean&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextisupdatingconfigurations7)<br>[isUpdatingConfigurations():Promise&lt;boolean&gt;;](../reference/apis/js-apis-inner-app-context.md#contextisupdatingconfigurations7-1) | There is no corresponding API in the stage model.| OpenHarmony applications do not restart when the system environment changes. The **onConfigurationUpdated** callback is invoked to notify the applications of the changes. This API provides an empty implementation in the FA model, and the stage model does not provide a corresponding API.|
| [printDrawnCompleted(callback:AsyncCallback&lt;void&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextprintdrawncompleted7)<br>[printDrawnCompleted():Promise&lt;void&gt;;](../reference/apis/js-apis-inner-app-context.md#contextprintdrawncompleted7-1) | There is no corresponding API in the stage model.| This API provides an empty implementation in the FA model. The stage model does not provide a corresponding API.|
# Creating a DataAbility
To meet the basic requirements of the database storage service, implement the **Insert**, **Query**, **Update**, and **Delete** methods for a DataAbility. The **BatchInsert** and **ExecuteBatch** methods have already implemented the traversal logic, but not batch data processing.
The following sample code shows how to create a DataAbility:
```ts
import featureAbility from '@ohos.ability.featureAbility'
import dataAbility from '@ohos.data.dataAbility'
import dataRdb from '@ohos.data.rdb'
const TABLE_NAME = 'book'
const STORE_CONFIG = { name: 'book.db' }
const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS book(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, introduction TEXT NOT NULL)'
let rdbStore: dataRdb.RdbStore = undefined
export default {
onInitialized(abilityInfo) {
console.info('DataAbility onInitialized, abilityInfo:' + abilityInfo.bundleName)
let context = featureAbility.getContext()
dataRdb.getRdbStore(context, STORE_CONFIG, 1, (err, store) => {
console.info('DataAbility getRdbStore callback')
store.executeSql(SQL_CREATE_TABLE, [])
rdbStore = store
});
},
insert(uri, valueBucket, callback) {
console.info('DataAbility insert start')
rdbStore.insert(TABLE_NAME, valueBucket, callback)
},
batchInsert(uri, valueBuckets, callback) {
console.info('DataAbility batch insert start')
for (let i = 0;i < valueBuckets.length; i++) {
console.info('DataAbility batch insert i=' + i)
if (i < valueBuckets.length - 1) {
rdbStore.insert(TABLE_NAME, valueBuckets[i], (err: any, num: number) => {
console.info('DataAbility batch insert ret=' + num)
})
} else {
rdbStore.insert(TABLE_NAME, valueBuckets[i], callback)
}
}
},
query(uri, columns, predicates, callback) {
console.info('DataAbility query start')
let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates)
rdbStore.query(rdbPredicates, columns, callback)
},
update(uri, valueBucket, predicates, callback) {
console.info('DataAbilityupdate start')
let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates)
rdbStore.update(valueBucket, rdbPredicates, callback)
},
delete(uri, predicates, callback) {
console.info('DataAbilitydelete start')
let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates)
rdbStore.delete(rdbPredicates, callback)
}
};
```
# Creating a PageAbility
When you create a PageAbility on DevEco Studio, DevEco Studio automatically generates the **onCreate()** and **onDestroy()** callbacks in **app.js** and **app.ets**. You need to implement the other lifecycle callbacks in **app.js** and **app.ets**. The following code snippet shows how to create a PageAbility:
```ts
export default {
onCreate() {
console.info('Application onCreate')
},
onDestroy() {
console.info('Application onDestroy')
},
onShow() {
console.info('Application onShow')
},
onHide() {
console.info('Application onHide')
},
onActive() {
console.info('Application onActive')
},
onInactive() {
console.info('Application onInactive')
},
onNewWant() {
console.info('Application onNewWant')
},
}
```
After the PageAbility is created, its abilities-related configuration items are displayed in the **config.json** file. The following is an example **config.json** file of an ability named EntryAbility:
```json
{
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
],
"orientation": "unspecified",
"visible": true,
"srcPath": "EntryAbility",
"name": ".EntryAbility",
"srcLanguage": "ets",
"icon": "$media:icon",
"description": "$string:EntryAbility_desc",
"formsEnabled": false,
"label": "$string:EntryAbility_label",
"type": "page",
"launchType": "singleton"
}
]
}
```
In the FA model, you can call **getContext** of **featureAbility** to obtain the application context and then use the capabilities provided by the context.
**Table 1** featureAbility APIs
| API| Description|
| -------- | -------- |
| getContext() | Obtains the application context.|
The following code snippet shows how to use **getContext()** to obtain the application context and distributed directory:
```ts
import featureAbility from '@ohos.ability.featureAbility'
import fileIo from '@ohos.fileio'
(async () => {
let dir: string
try {
console.info('Begin to getOrCreateDistributedDir')
dir = await featureAbility.getContext().getOrCreateDistributedDir()
console.info('distribute dir is ' + dir)
} catch (error) {
console.error('getOrCreateDistributedDir failed with ' + error)
}
let fd: number;
let path = dir + "/a.txt";
fd = fileIo.openSync(path, 0o2 | 0o100, 0o666);
fileIo.close(fd);
})()
```
# Creating a ServiceAbility
1. Create a ServiceAbility.
Override the ServiceAbility lifecycle callbacks to implement your own logic for processing interaction requests.
```ts
import rpc from "@ohos.rpc"
class FirstServiceAbilityStub extends rpc.RemoteObject {
constructor(des: any) {
if (typeof des === 'string') {
super(des)
} else {
return
}
}
}
export default {
onStart() {
console.info('ServiceAbility onStart')
},
onStop() {
console.info('ServiceAbility onStop')
},
onCommand(want, startId) {
console.info('ServiceAbility onCommand')
},
onConnect(want) {
console.info('ServiceAbility onConnect' + want)
return new FirstServiceAbilityStub('test')
},
onDisconnect(want) {
console.info('ServiceAbility onDisconnect' + want)
}
}
```
2. Register the ServiceAbility.
Declare the ServiceAbility in the **config.json** file by setting its **type** attribute to **service**. The **visible** attribute specifies whether the ServiceAbility can be called by other applications. The value **true** means that the ServiceAbility can be called by other applications, and **false** means that the ServiceAbility can be called only within the application. To enable the ServiceAbility to be called by other applications, set **visible** to **true** when registering the ServiceAbility and enable associated startup. For details about the startup rules, see [Component Startup Rules](component-startup-rules.md).
```json
{
"module": {
"abilities": [
{
"name": ".ServiceAbility",
"srcLanguage": "ets",
"srcPath": "ServiceAbility",
"icon": "$media:icon",
"description": "hap sample empty service",
"type": "service",
"visible": true
}
]
}
}
```
# Using 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.
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:
- **ohos.want.action.select**: action of starting the application selector.
- **ohos.want.action.sendData**: action of sending a single data record, that is, transferring data to the shared 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
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**.
```ts
import common from '@ohos.app.ability.common';
let fileType = 'application/pdf';
let fileName = 'TestFile.pdf';
let fileFd = -1; // Obtain the file descriptor (FD) of the file to share.
let fileSize; // Obtain the size of the file to share.
function implicitStartAbility() {
let context = getContext(this) as common.UIAbilityContext;
let wantInfo = {
/ This action is used to implicitly match the application selector.
action: 'ohos.want.action.select',
// This is the custom parameter in the first layer of Want,
/ which is intended to add information to the application selector.
parameters: {
// MIME type of PDF.
"ability.picker.type": fileType,
"ability.picker.fileNames": [fileName],
"ability.picker.fileSizes": [fileSize],
// This is nested Want ,which will be directly sent to the selected application.
"ability.want.params.INTENT": {
"action": "ohos.want.action.sendData",
"type": "application/pdf",
"parameters": {
"keyFd": { "type": "FD", "value": fileFd }
}
}
}
}
context.startAbility(wantInfo).then(() => {
// ...
}).catch((err) => {
// ...
})
}
```
> **NOTE**
>
> 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:
- **ability.picker.type**: file type icon.
- **ability.picker.fileNames**: file name.
- **ability.picker.fileSizes**: file size, in bytes.
- **ability.picker.fileNames** and **ability.picker.fileSizes** are arrays and have a one-to-one mapping.
The following figure shows an example.
![](figures/ability-startup-with-implicit-want2.png)
## Shared Party
To enable the shared party to identify the shared content, configure **skills** in the [module.json5 file](../quick-start/module-configuration-file.md) of the UIAbility of the shared party. The **actions** and **type** fields in **uris** match the **action** and **type** fields in **ability.want.params.INTENT** of the sharing party, respectively.
```json
{
"module": {
// ...
"abilities": [
{
// ...
"skills": [
{
// ...
"actions": [
"action.system.home",
"ohos.want.action.sendData"
// ...
],
"uris": [
{
"type": "application/pdf"
},
]
}
]
}
]
}
}
```
After the user selects an application, the Want nested in the **ability.want.params.INTENT** field is passed to that application. The UIAbility of the shared party, after being started, can call [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) or [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonnewwant) to obtain the passed Want.
The following is an example of the Want obtained. You can use the FD of the shared file to perform required operations.
```json
{
"deviceId": "",
"bundleName": "com.example.myapplication",
"abilityName": "EntryAbility",
"moduleName": "entry",
"uri": "",
"type": "application/pdf",
"flags": 0,
"action": "ohos.want.action.sendData",
"parameters": {
"component.startup.newRules": true,
"keyFd": {
"type": "FD",
"value": 36
},
"mime-type": "application/pdf",
"moduleName": "entry",
"ohos.aafwk.param.callerPid": 3488,
"ohos.aafwk.param.callerToken": 537379209,
"ohos.aafwk.param.callerUid": 20010014
},
"entities": []
}
```
# DataAbility Component Configuration
## URI Introduction
A Uniform Resource Identifier (URI) is used to identify a specific data item, such as a table in the database or a file on the disk. URIs used in OpenHarmony comply with the commonly used URI standard. A URI consists of the components:
![fa-dataability-uri](figures/fa-dataability-uri.png)
- **scheme**: name of the scheme used by the DataAbility. The value is fixed at **dataability**.
- **authority**: device ID. To access data on a remote device, set this component to the ID of the remote device. To access data on the local device, leave this component empty.
- **path**: location of the specific resource to access.
- **query**: query parameters.
- **fragment**: subordinate resources to access.
Example URIs:
- Cross-device communication: dataability://*device*id_/*com.domainname.dataability.persondata*/*person*/*10*
- Local-device communication: dataability:///*com.domainname.dataability.persondata*/*person*/*1*
> **NOTE**
>
> In the case of local-device communication, **device_id** is empty, and therefore, there are three slashes (/) after **dataability:**.
## Introduction to Certain Configuration Items
Similar to a PageAbility, a DataAbility is configured in **abilities** under **module** of the **config.json** file. The difference between a DataAbility and PageAbility lies in the **type** and **uri** fields.
**Table 1** DataAbility configuration items
| Name| Description|
| -------- | -------- |
| "name" | Ability name.|
| "type" | Type of the ability. The value **data** indicates a DataAbility.|
| "uri" | URI used for communication.|
| "visible" | Whether the ability is visible to other applications. Data sharing is allowed only when the value is **true**.|
The following is an example **config.json** file:
```json
"abilities": [{
"srcPath": "DataAbility",
"name": ".DataAbility",
"icon": "$media:icon",
"srcLanguage": "ets",
"description": "$string:description_dataability",
"type": "data",
"visible": true,
"uri": "dataability://ohos.samples.etsdataability.DataAbility"
}]
```
For details about the configuration items, see [Internal Structure of module](../quick-start/module-structure.md).
# DataAbility Lifecycle
You can override lifecycle callbacks (described in the table below) for a DataAbility based on service requirements.
**Table 1** DataAbility lifecycle APIs
| API| Description|
| -------- | -------- |
| onInitialized?(info: AbilityInfo): void | Called during ability initialization to initialize the relational database (RDB).|
| update?(uri: string, valueBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback&lt;number&gt;): void | Updates data in the database.|
| query?(uri: string, columns: Array&lt;string&gt;, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback&lt;ResultSet&gt;): void | Queries data in the database.|
| delete?(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback&lt;number&gt;): void | Deletes one or more data records from the database.|
| normalizeUri?(uri: string, callback: AsyncCallback&lt;string&gt;): void | Normalizes the URI. A normalized URI applies to cross-device use, persistence, backup, and restore. When the context changes, it ensures that the same data item can be referenced.|
| batchInsert?(uri: string, valueBuckets: Array&lt;rdb.ValuesBucket&gt;, callback: AsyncCallback&lt;number&gt;): void | Inserts multiple data records into the database.|
| denormalizeUri?(uri: string, callback: AsyncCallback&lt;string&gt;): void | Converts a normalized URI generated by **normalizeUri** into a denormalized URI.|
| insert?(uri: string, valueBucket: rdb.ValuesBucket, callback: AsyncCallback&lt;number&gt;): void | Inserts a data record into the database.|
| openFile?(uri: string, mode: string, callback: AsyncCallback&lt;number&gt;): void | Opens a file.|
| getFileTypes?(uri: string, mimeTypeFilter: string, callback: AsyncCallback&lt;Array&lt;string&gt;&gt;): void | Obtains the MIME type of a file.|
| getType?(uri: string, callback: AsyncCallback&lt;string&gt;): void | Obtains the MIME type matching the data specified by the URI.|
| executeBatch?(ops: Array&lt;DataAbilityOperation&gt;, callback: AsyncCallback&lt;Array&lt;DataAbilityResult&gt;&gt;): void | Operates data in the database in batches.|
| call?(method: string, arg: string, extras: PacMap, callback: AsyncCallback&lt;PacMap&gt;): void | Calls a custom API.|
# DataAbility Component Overview
A DataAbility is an ability that uses the Data template. It provides unified data access for external systems, but not a UI for user interaction. A DataAbility can be started by a PageAbility, a ServiceAbility, or other applications. It remains to run in the background even after the user switches to another application.
A DataAbility helps applications manage access to data stored by themselves and other applications, and provides methods for sharing data with other applications, either on the same device or across devices.
Data can be stored in a database or files on disks. The DataAbility provide methods for inserting, deleting, updating, and querying data, and opening files. You should implement these methods.
# DataAbility Permission Control
The DataAbility uses permission control to determine whether an ability can access the data service it provides. There are static and dynamic permission controls.
## Static Permission Control
The DataAbility functions as the server. When being started, the DataAbility verifies the client permissions against the settings of the optional fields **readPermission**, **writePermission**, and **Permission** fields in the **config.json** file. The following is an example:
```json
"abilities": [{
"srcPath": "DataAbility",
"name": ".DataAbility",
"icon": "$media:icon",
"srcLanguage": "ets",
"description": "$string:description_dataability",
"type": "data",
"visible": true,
"uri": "dataability://ohos.samples.etsdataability.DataAbility",
"readPermission":"ohos.permission.READ_CONTACTS",
"writePermission":"ohos.permission.WRITE_CONTACTS"
}]
```
The client permission is configured in **reqPermissions** under **module** in the **config.json** file. The following is an example:
```json
{
"module": {
"reqPermissions":{
{
"name":"ohos.permission.READ_CONTACTS"
},
{
"name":"ohos.permission.WRITE_CONTACTS"
}
}
}
}
```
## Dynamic Permission Control
Static permission control determines whether a DataAbility can be started by another ability or application. It does not verify the permission of each read/write interface.
Dynamic permission control verifies whether the client has the corresponding permission for every read/write interface. The table below lists the permissions required for calling these interfaces.
**Table 1** Permission configuration for data read/write interfaces
| Interface with the Read Permission| Interface with the Write Permission| Interface with the Read/Write Permission Based on Actual Requirements|
| -------- | -------- | -------- |
| query, normalizeUri, denormalizeUri, openfile (with **mode** set to **'r'**)| insert, batchInsert, delete, update, openfile (with **mode** set to **'w'**)| executeBatch |
For interfaces that require the read permission, the server must have **readPermission** specified, and the client must obtain the read permission before calling them.
For interfaces that require the write permission, the server must have **writePermission** specified, and the client must obtain the write permission before calling them.
# DataAbility Switching
The DataAbility component in the FA model corresponds to the DataShareExtensionAbility component in the stage model.
The DataShareExtensionAbility class provides system APIs. Only system applications can create DataShareExtensionAbility instances. Therefore, DataAbility switching adopts different policies for system applications and third-party applications.
## Switching a DataAbility of a System Application
The procedure for switching a DataAbility of a system application is similar to the procedure of PageAbility switching.
1. Create a DataShareExtensionAbility in the stage model.
2. Migrate the DataAbility code to the DataShareExtensionAbility.
The table below describes the lifecycle comparison of the DataAbility and DataShareExtensionAbility.
| DataAbility| DataShareExtensionAbility| Comparison Description|
| -------- | -------- | -------- |
| onInitialized?(info: AbilityInfo): void | onCreate?(want: Want, callback: AsyncCallback&lt;void&gt;): void<br> | The two methods have the same invoking time but different input parameters. In the stage model, the **want** parameter is added so that you can obtain parameters during creation.|
| update?(uri: string, valueBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback&lt;number&gt;): void | update?(uri: string, predicates: dataSharePredicates.DataSharePredicates, value: ValuesBucket, callback: AsyncCallback&lt;number&gt;): void | The two methods have the same meaning and invoking time, but slightly different parameter sequence and parameter type. A simple reconstruction is required.|
| query?(uri: string, columns: Array&lt;string&gt;, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback&lt;ResultSet&gt;): void | query?(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array&lt;string&gt;, callback: AsyncCallback&lt;Object&gt;): void;| The two methods have the same meaning and invoking time, but slightly different parameter sequence and parameter type. A simple reconstruction is required.|
| delete?(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback&lt;number&gt;): void | delete?(uri: string, predicates: dataSharePredicates.DataSharePredicates, callback: AsyncCallback&lt;number&gt;):| The two methods have the same meaning and invoking time, but slightly different parameter type. A simple reconstruction is required.|
| normalizeUri?(uri: string, callback: AsyncCallback&lt;string&gt;): void | normalizeUri?(uri: string, callback: AsyncCallback&lt;string&gt;): void| The two methods have the same meaning, invoking time, and parameters.|
| batchInsert?(uri: string, valueBuckets: Array&lt;rdb.ValuesBucket&gt;, callback: AsyncCallback&lt;number&gt;): void | batchInsert?(uri: string, values: Array&lt;ValuesBucket&gt;, callback: AsyncCallback&lt;number&gt;): void| The two methods have the same meaning and invoking time, but slightly different parameter type. A simple reconstruction is required.|
| denormalizeUri?(uri: string, callback: AsyncCallback&lt;string&gt;): void | denormalizeUri?(uri: string, callback: AsyncCallback&lt;string&gt;): void | The two methods have the same meaning, invoking time, and parameters.|
| insert?(uri: string, valueBucket: rdb.ValuesBucket, callback: AsyncCallback&lt;number&gt;): void | insert?(uri: string, value: ValuesBucket, callback: AsyncCallback&lt;number&gt;): void | The two methods have the same meaning and invoking time, but slightly different parameter type. A simple reconstruction is required.|
| openFile?(uri: string, mode: string, callback: AsyncCallback&lt;number&gt;): void | NA | The stage model does not support cross-process URI access. You are advised to use [the **want** parameter to carry the file descriptor and file information](data-share-via-want.md) for cross-process file access.|
| getFileTypes?(uri: string, mimeTypeFilter: string, callback: AsyncCallback&lt;Array&lt;string&gt;&gt;): void | NA | The stage model does not support cross-process URI access. You are advised to use [the **want** parameter to carry the file descriptor and file information](data-share-via-want.md) for cross-process file access.|
| getType?(uri: string, callback: AsyncCallback&lt;string&gt;): void | NA | The stage model does not support cross-process URI access. You are advised to use [the **want** parameter to carry the file descriptor and file information](data-share-via-want.md) for cross-process file access.|
| executeBatch?(ops: Array&lt;DataAbilityOperation&gt;, callback: AsyncCallback&lt;Array&lt;DataAbilityResult&gt;&gt;): void | NA | This method is not provided in the stage model. You need to implement the functionality based on service functions.|
| call?(method: string, arg: string, extras: PacMap, callback: AsyncCallback&lt;PacMap&gt;): void | NA | This method is not provided in the stage model. You need to implement the functionality based on service functions.|
## Switching a DataAbility of a Third-Party Application
In the stage model, third-party applications cannot provide data services for other third-party applications. You can select a switching solution based on your service requirements.
| Service Type| Switching Solution|
| -------- | -------- |
| Providing data for third-party applications| Match a scenario-specific [ExtensionAbility](../reference/apis/js-apis-bundleManager.md#extensionabilitytype).|
| Providing data within the application| Extract the component code as a common module for other components to use.|
# DataAbilityHelper Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model|
| -------- | -------- | -------- |
| [openFile(uri: string, mode: string, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperopenfile)<br>[openFile(uri: string, mode: string): Promise&lt;number&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperopenfile-1) | \@ohos.data.fileAccess.d.ts | [openFile(uri: string, flags: OPENFLAGS) : Promise&lt;number&gt;;](../reference/apis/js-apis-fileAccess.md#fileaccesshelperopenfile)<br>[openFile(uri: string, flags: OPENFLAGS, callback: AsyncCallback&lt;number&gt;) : void;](../reference/apis/js-apis-fileAccess.md#fileaccesshelperopenfile) |
| [on(type: 'dataChange', uri: string, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperon) | \@ohos.data.dataShare.d.ts | [on(type: 'dataChange', uri: string, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-data-dataShare.md#ondatachange) |
| [off(type: 'dataChange', uri: string, callback?: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperoff) | \@ohos.data.dataShare.d.ts | [off(type: 'dataChange', uri: string, callback?: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-data-dataShare.md#offdatachange) |
| [getType(uri: string, callback: AsyncCallback&lt;string&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpergettype)<br>[getType(uri: string): Promise&lt;string&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpergettype-1) | There is no corresponding API in the stage model.| The stage model does not support cross-process URI access. You are advised to use [the want parameter to carry the file descriptor and file information](data-share-via-want.md) for cross-process file access.|
| [getFileTypes(uri: string, mimeTypeFilter: string, callback: AsyncCallback&lt;Array&lt;string&gt;&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpergetfiletypes)<br>[getFileTypes(uri: string, mimeTypeFilter: string): Promise&lt;Array&lt;string&gt;&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpergetfiletypes-1) | There is no corresponding API in the stage model.| The stage model does not support cross-process URI access. You are advised to use [the want parameter to carry the file descriptor and file information](data-share-via-want.md) for cross-process file access.|
| [normalizeUri(uri: string, callback: AsyncCallback&lt;string&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpernormalizeuri)<br>[normalizeUri(uri: string): Promise&lt;string&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpernormalizeuri-1) | \@ohos.data.dataShare.d.ts | [normalizeUri(uri: string, callback: AsyncCallback&lt;string&gt;): void;](../reference/apis/js-apis-data-dataShare.md#normalizeuri)<br>[normalizeUri(uri: string): Promise&lt;string&gt;;](../reference/apis/js-apis-data-dataShare.md#normalizeuri-1) |
| [denormalizeUri(uri: string, callback: AsyncCallback&lt;string&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperdenormalizeuri)<br>[denormalizeUri(uri: string): Promise&lt;string&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperdenormalizeuri-1) | \@ohos.data.dataShare.d.ts | [denormalizeUri(uri: string, callback: AsyncCallback&lt;string&gt;): void;](../reference/apis/js-apis-data-dataShare.md#denormalizeuri)<br>[denormalizeUri(uri: string): Promise&lt;string&gt;;](../reference/apis/js-apis-data-dataShare.md#denormalizeuri-1) |
| [notifyChange(uri: string, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpernotifychange)<br>[notifyChange(uri: string): Promise&lt;void&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpernotifychange-1) | \@ohos.data.dataShare.d.ts | [notifyChange(uri: string, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-data-dataShare.md#notifychange)<br>[notifyChange(uri: string): Promise&lt;void&gt;;](../reference/apis/js-apis-data-dataShare.md#notifychange-1) |
| [insert(uri: string, valuesBucket: rdb.ValuesBucket, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperinsert)<br>[insert(uri: string, valuesBucket: rdb.ValuesBucket): Promise&lt;number&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperinsert-1) | \@ohos.data.dataShare.d.ts | [insert(uri: string, value: ValuesBucket, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-data-dataShare.md#insert)<br>[insert(uri: string, value: ValuesBucket): Promise&lt;number&gt;;](../reference/apis/js-apis-data-dataShare.md#insert-1) |
| [batchInsert(uri: string, valuesBuckets: Array&lt;rdb.ValuesBucket&gt;, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperbatchinsert)<br>[batchInsert(uri: string, valuesBuckets: Array&lt;rdb.ValuesBucket&gt;): Promise&lt;number&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperbatchinsert-1) | \@ohos.data.dataShare.d.ts | [batchInsert(uri: string, values: Array&lt;ValuesBucket&gt;, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-data-dataShare.md#batchinsert)<br>[batchInsert(uri: string, values: Array&lt;ValuesBucket&gt;): Promise&lt;number&gt;;](../reference/apis/js-apis-data-dataShare.md#batchinsert-1) |
| [delete(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperdelete)<br>[delete(uri: string, predicates?: dataAbility.DataAbilityPredicates): Promise&lt;number&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperdelete-1)<br>[delete(uri: string, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperdelete) | \@ohos.data.dataShare.d.ts | [delete(uri: string, predicates: dataSharePredicates.DataSharePredicates, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-data-dataShare.md#delete)<br>[delete(uri: string, predicates: dataSharePredicates.DataSharePredicates): Promise&lt;number&gt;;](../reference/apis/js-apis-data-dataShare.md#delete-1) |
| [update(uri: string, valuesBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperupdate)<br>[update(uri: string, valuesBucket: rdb.ValuesBucket, predicates?: dataAbility.DataAbilityPredicates): Promise&lt;number&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperupdate-1)<br>[update(uri: string, valuesBucket: rdb.ValuesBucket, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperupdate) | \@ohos.data.dataShare.d.ts | [update(uri: string, predicates: dataSharePredicates.DataSharePredicates, value: ValuesBucket, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-data-dataShare.md#update)<br>[update(uri: string, predicates: dataSharePredicates.DataSharePredicates, value: ValuesBucket): Promise&lt;number&gt;;](../reference/apis/js-apis-data-dataShare.md#update-1) |
| [query(uri: string, columns: Array&lt;string&gt;, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback&lt;ResultSet&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperquery)<br>[query(uri: string, callback: AsyncCallback&lt;ResultSet&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperquery)<br>[query(uri: string, columns: Array&lt;string&gt;, callback: AsyncCallback&lt;ResultSet&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperquery)<br>[query(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback&lt;ResultSet&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperquery)<br>[query(uri: string, columns?: Array&lt;string&gt;, predicates?: dataAbility.DataAbilityPredicates): Promise&lt;ResultSet&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperquery-1) | \@ohos.data.dataShare.d.ts | [query(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array&lt;string&gt;, callback: AsyncCallback&lt;DataShareResultSet&gt;): void;](../reference/apis/js-apis-data-dataShare.md#query)<br>[query(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array&lt;string&gt;): Promise&lt;DataShareResultSet&gt;;](../reference/apis/js-apis-data-dataShare.md#query-1) |
| [call(uri: string, method: string, arg: string, extras: PacMap, callback: AsyncCallback&lt;PacMap&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpercall-1)<br>[call(uri: string, method: string, arg: string, extras: PacMap): Promise&lt;PacMap&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpercall) | There is no corresponding API in the stage model.| No corresponding API is provided.|
| [executeBatch(uri: string, operations: Array&lt;DataAbilityOperation&gt;, callback: AsyncCallback&lt;Array&lt;DataAbilityResult&gt;&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperexecutebatch)<br>[executeBatch(uri: string, operations: Array&lt;DataAbilityOperation&gt;): Promise&lt;Array&lt;DataAbilityResult&gt;&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperexecutebatch-1) | There is no corresponding API in the stage model.| No corresponding API is provided.|
# DataShareExtensionAbility (for System Applications Only)
DataShareExtensionAbility provides the data sharing capability. System applications can implement a DataShareExtensionAbility or access an existing DataShareExtensionAbility in the system. Third-party applications can only access an existing DataShareExtensionAbility. For details, see [DataShare Development](../database/database-datashare-guidelines.md).
# EnterpriseAdminExtensionAbility Development
## Introduction to EnterpriseAdminExtensionAbility
EnterpriseAdminExtensionAbility is a mandatory component for Mobile Device Management (MDM) applications. When developing MDM applications for enterprises, you need to inherit EnterpriseAdminExtensionAbility and implement MDM service logic in the EnterpriseAdminExtensionAbility instance. EnterpriseAdminExtensionAbility implements notifications of system management status changes and defines the callbacks for when a device administrator application is enabled or disabled or an application is installed or uninstalled.
## Constraints
- **Function constraints**
EnterpriseAdminExtensionAbility is applicable only to enterprise administrator applications.
## Observing Activation/Deactivation of a Device Administrator Application and Installation/Removal of an Application
### Overview
**onAdminEnabled**: When an enterprise administrator or employee deploys an MDM application and activates the device administrator application, this callback is invoked to notify the MDM application that the DeviceAdmin permission is activated. The initialization policy of the MDM application can set in **onAdminEnabled**.
**onAdminDisabled**: When the device administrator application is deactivated, the callback is invoked to notify the MDM application that the DeviceAdmin permission is deactivated.
**onBundleAdded**: The enterprise administrator can subscribe to application installation and uninstallation events. When an application is installed on an enterprise device, the MDM application reports the event in this callback to notify the enterprise administrator.
**onBundleRemoved**: When an application is removed from an enterprise device, the MDM application reports the event in this callback to notify the enterprise administrator.
### Available APIs
| Class | API | Description |
| :------------------------------ | ----------------------------------------- | ---------------------------- |
| EnterpriseAdminExtensionAbility | onAdminDisabled(): void | Called when a device administrator application is deactivated.|
| EnterpriseAdminExtensionAbility | onBundleAdded(bundleName: string): void | Called when an application is installed on a device. |
| EnterpriseAdminExtensionAbility | onAdminEnabled(): void | Called when a device administrator application is activated. |
| EnterpriseAdminExtensionAbility | onBundleRemoved(bundleName: string): void | Called when an application is removed from a device. |
### How to Develop
To implement EnterpriseAdminExtensionAbility, you need to activate the device administrator application and create **ExtensionAbility** in the code directory of the device administrator application. The procedure is as follows:
1. In the **ets** directory of the target module, right-click and choose **New > Directory** to create a directory named **EnterpriseExtAbility**.
2. Right-click the **EnterpriseExtAbility** directory, and choose **New > TypeScript File** to create a file named **EnterpriseExtAbility.ts**.
3. Open the **EnterpriseExtAbility.ts** file and import the **EnterpriseAdminExtensionAbility** module. Inherit the **EnterpriseAdminExtensionAbility** module to the custom class and add application notification callbacks, such as **onAdminEnabled()** and **onAdminDisabled()**. When the device administrator application is activated or deactivated, the device administrator can receive notifications.
```ts
import EnterpriseAdminExtensionAbility from '@ohos.enterprise.EnterpriseAdminExtensionAbility';
export default class EnterpriseAdminAbility extends EnterpriseAdminExtensionAbility {
onAdminEnabled() {
console.info("onAdminEnabled");
}
onAdminDisabled() {
console.info("onAdminDisabled");
}
onBundleAdded(bundleName: string) {
console.info("EnterpriseAdminAbility onBundleAdded bundleName:" + bundleName)
}
onBundleRemoved(bundleName: string) {
console.info("EnterpriseAdminAbility onBundleRemoved bundleName" + bundleName)
}
};
```
4. Register **ServiceExtensionAbility** in the [**module.json5**](../quick-start/module-configuration-file.md) file corresponding to the project module. Set **type** to **enterpriseAdmin** and **srcEntrance** to the path of the ExtensionAbility code.
```ts
"extensionAbilities": [
{
"name": "ohos.samples.enterprise_admin_ext_ability",
"type": "enterpriseAdmin",
"visible": true,
"srcEntrance": "./ets/enterpriseextability/EnterpriseAdminAbility.ts"
}
]
```
## Example
Use **subscribeManagedEvent()** and **unsubscribeManagedEvent()** in the **@ohos.enterprise.adminManager** module to subscribe to application installation and removal events. When an application is installed or removed, the MDM application is notified of the event. Then, the MDM application reports the event in the callback to notify the enterprise administrator.
```ts
@State managedEvents: Array<adminManager.ManagedEvent> = [0,1]
@State subscribeManagedEventMsg: string = ""
@State unsubscribeManagedEventMsg: string = ""
async subscribeManagedEventCallback() {
await adminManager.subscribeManagedEvent(this.admin,
[adminManager.ManagedEvent.MANAGED_EVENT_BUNDLE_ADDED,
adminManager.ManagedEvent.MANAGED_EVENT_BUNDLE_REMOVED], (error) => {
if (error) {
this.subscribeManagedEventMsg = 'subscribeManagedEvent Callback::errorCode: ' + error.code + ' errorMessage: ' + error.message
} else {
this.subscribeManagedEventMsg = 'subscribeManagedEvent Callback::success'
}
})
}
async unsubscribeManagedEventPromise() {
await adminManager.unsubscribeManagedEvent(this.admin,
[adminManager.ManagedEvent.MANAGED_EVENT_BUNDLE_ADDED,
adminManager.ManagedEvent.MANAGED_EVENT_BUNDLE_REMOVED]).then(() => {
this.unsubscribeManagedEventMsg = 'unsubscribeManagedEvent Promise::success'
}).catch((error) => {
this.unsubscribeManagedEventMsg = 'unsubscribeManagedEvent Promise::errorCode: ' + error.code + ' errorMessage: ' + error.message
})
}
```
# Matching Rules of Explicit Want and Implicit Want
Both explicit Want and implicit Want can be used to match an ability to start based on certain rules. These rules determine how the parameters set in Want match the configuration file declared by the target ability.
## Matching Rules of Explicit Want
The table below describes the matching rules of explicit Want.
| Name| Type| Matching Item| Mandatory| Rule Description|
| -------- | -------- | -------- | -------- | -------- |
| deviceId | string | Yes| No| If this field is unspecified, only abilities on the local device are matched.|
| bundleName | string | Yes| Yes| If **abilityName** is specified but **bundleName** is unspecified, the matching fails.|
| moduleName | string | Yes| No| If this field is unspecified and multiple modules with the same ability name exist in the application, the first ability is matched by default.|
| abilityName | string | Yes| Yes| To use explicit Want, this field must be specified.|
| uri | string | No| No| This field is not used for matching. It is passed to the target ability as a parameter.|
| type | string | No| No| This field is not used for matching. It is passed to the target ability as a parameter.|
| action | string | No| No| This field is not used for matching. It is passed to the target ability as a parameter.|
| entities | Array&lt;string&gt; | No| No| This field is not used for matching. It is passed to the target ability as a parameter.|
| flags | number | No| No| This field is not used for matching and is directly transferred to the system for processing. It is generally used to set runtime information, such as URI data authorization.|
| parameters | {[key:&nbsp;string]:&nbsp;any} | No| No| This field is not used for matching. It is passed to the target ability as a parameter.|
## Matching Rules for Implicit Want
The table below describes the matching rules of implicit Want.
| Name | Type | Matching Item| Mandatory| Rule Description |
| ----------- | ------------------------------ | ------ | ---- | ------------------------------------------------------------ |
| deviceId | string | Yes | No | Implicit invoking is not supported across devices. |
| abilityName | string | No | No | To use implicit Want, this field must be left unspecified. |
| bundleName | string | Yes | No | - When only **bundleName** is specified, matching is limited to that application.<br>- When both **bundleName** and **moduleName** are specified, matching is limited to that module in that application.<br>- When only **moduleName** is specified, the setting is invalid.<br> <br>These fields will be used for implicit matching.|
| moduleName | string | Yes | No | |
| uri | string | Yes | No | |
| type | string | Yes | No | |
| action | string | Yes | No | |
| entities | Array&lt;string&gt; | Yes | No | |
| flags | number | No | No | This field is not used for matching and is directly transferred to the system for processing. It is generally used to set runtime information, such as URI data authorization.|
| parameters | {[key:&nbsp;string]:&nbsp;any} | No | No | This field is not used for matching. It is passed to the target ability as a parameter. |
Get familiar with the following about implicit Want:
- The **want** parameter passed by the caller indicates the operation to be performed by the caller. It also provides data and application type restrictions.
- The **skills** field declares the capabilities of the target ability. For details, see [the skills tag](../quick-start/module-configuration-file.md#skills) in the [module.json5 file](../quick-start/module-configuration-file.md).
The system matches the **want** parameter (including the **action**, **entities**, **uri**, and **type** attributes) passed by the caller against the **skills** configuration (including the **actions**, **entities**, **uris**, and **type** attributes) of the abilities one by one. When all the four attributes are matched, a dialog box is displayed for users to select a matched application.
### Matching Rules of action in the want Parameter
The system matches the **action** attribute in the **want** parameter passed by the caller against **actions** under **skills** of the abilities.
- If **action** in the passed **want** parameter is specified but **actions** under **skills** of an ability is unspecified, the matching fails.
- If **action** in the passed **want** parameter is unspecified but **actions** under **skills** of an ability is specified, the matching is successful.
- If **action** in the passed **want** parameter is specified, and **actions** under **skills** of an ability is specified and contains **action** in the passed **want** parameter, the matching is successful.
- If **action** in the passed **want** parameter is specified, and **actions** under **skills** of an ability is specified but does not contain **action** in the passed **want** parameter, the matching fails.
**Figure 1** Matching rules of action in the want parameter
![want-action](figures/want-action.png)
### Matching Rules of entities in the want Parameter
The system matches the **entities** attribute in the **want** parameter passed by the caller against **entities** under **skills** of the abilities.
- If **entities** in the passed **want** parameter is unspecified but **entities** under **skills** of an ability is specified, the matching is successful.
- If **entities** in the passed **want** parameter is unspecified but **entities** under **skills** of an ability is unspecified, the matching is successful.
- If **entities** in the passed **want** parameter is specified but **entities** under **skills** of an ability is unspecified, the matching fails.
- If **entities** in the passed **want** parameter is specified, and **entities** under **skills** of an ability is specified and contains **entities** in the passed **want** parameter, the matching is successful.
- 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
![want-entities](figures/want-entities.png)
### 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.
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:
- Neither **uri** or **type** is specified in the **want** parameter.
- If the **uris** array under **skills** of an ability is unspecified, the matching is successful.
- If the **uris** array under **skills** of an ability contains an URI element whose **scheme** and **type** are unspecified, the matching is successful.
- In other cases, the matching fails.
- Only **uri** is specified in the **want** parameter.
- 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 unspecified, the matching is successful. Otherwise, the matching fails.
- Only **type** is specified in the **want** parameter.
- 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 URI element whose **scheme** is unspecified and [type is matched](#matching-rules-of-type), the matching is successful. Otherwise, the matching fails.
- Both **uri** and **type** are specified in the **want** parameter, as shown in Figure 3.
- 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.
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
![want-uri-type2](figures/want-uri-type2.png)
### Matching Rules of uri
To simplify the description, **uri** in the passed **want** parameter is called **w_uri**; **uri** under **skills** of an ability to match is called **s_uri**. The matching rules are as follows:
- If **scheme** of **s_uri** is unspecified and **w_uri** is unspecified, 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 **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 **pathStartWith** of **s_uri** is specified and **w_uri** contains the prefix expression of **s_uri**, the matching is successful. Otherwise, **pathRegex** matching continues.
- If **pathRegex** of **s_uri** is specified and **w_uri** meets the regular expression of **s_uri**, the matching is successful. Otherwise, the matching fails.
> **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:
>
> - **Full path expression**: `scheme://host:port/path`
>
> - **Prefix expression**: `scheme://host:port/pathStartWith`
>
> - **Regular expression**: `scheme://host:port/pathRegex`
### Matching Rules of type
> **NOTE**
>
> The matching rules of **type** described in this section are based on the fact that **type** in the **want** parameter is specified. If **type** is unspecified, follow the [matching rules of uri and type in the want parameter](#matching-rules-of-uri-and-type-in-the-want-parameter).
To simplify the description, **uri** in the passed **want** parameter is called **w_type**, and **type** of **uris** under **skills** of an ability to match is called **s_type**. The matching rules are as follows:
- If **s_type** is unspecified, the matching fails.
- If **s_type** or **w_type** contains the wildcard `*/*`, the matching is successful.
- If the last character of **s_type** is the wildcard `*`, for example, `prefixType/*`, the matching is successful only when **w_type** contains `prefixType/`.
- If the last character of **w_type** is the wildcard `*`, for example, `prefixType/*`, the matching is successful only when **s_type** contains `prefixType/`.
# ExtensionAbility Component Overview
The ExtensionAbility component is used for specific scenarios such as widgets and input methods.
An [ExtensionAbilityType](../reference/apis/js-apis-bundleManager.md#extensionabilitytype) is provided for every specific scenario. All types of ExtensionAbility components are managed by the corresponding system services in a unified manner. For example, the InputMethodExtensionAbility component is managed by the input method management service. The following ExtensionAbility types are supported:
- [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md): ExtensionAbility component of the form type, which provides APIs related to widgets.
- [WorkSchedulerExtensionAbility](../reference/apis/js-apis-WorkSchedulerExtensionAbility.md): ExtensionAbility component of the work_scheduler type, which provides callbacks for Work Scheduler tasks.
- [InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod.md): ExtensionAbility component of the input_method type, which provides an input method framework that can be used to hide the keyboard, obtain the list of installed input methods, display the dialog box for input method selection, and more.
- [ServiceExtensionAbility](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md): ExtensionAbility component of the service type, which provides APIs related to background service scenarios.
- [AccessibilityExtensionAbility](../reference/apis/js-apis-application-accessibilityExtensionAbility.md): ExtensionAbility component of the accessibility type, which provides APIs related to the accessibility feature.
- [DataShareExtensionAbility](../reference/apis/js-apis-application-dataShareExtensionAbility.md): ExtensionAbility component of the data_share type, which provides APIs for data sharing.
- [StaticSubscriberExtensionAbility](../reference/apis/js-apis-application-staticSubscriberExtensionAbility.md): ExtensionAbility component of the static_subscriber type, which provides APIs for static broadcast.
- [WindowExtensionAbility](../reference/apis/js-apis-application-windowExtensionAbility.md): ExtensionAbility component of the window type, which allows a system application to be embedded in and displayed over another application.
- [EnterpriseAdminExtensionAbility](../reference/apis/js-apis-EnterpriseAdminExtensionAbility.md): ExtensionAbility component of the enterprise_admin type, which provides APIs for processing enterprise management events, such as application installation events on devices and events indicating too many incorrect screen-lock password attempts.
## Using ExtensionAbility of the Specified Type
All types of ExtensionAbility components are started by the corresponding system management service, rather than applications, so that their lifecycles are under control by the system. The caller of the ExtensionAbility component does not need to care about its lifecycle.
The following uses [InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod.md) as an example. As shown in the figure below, when an application calls the InputMethodExtensionAbility component, the input method management service is called first. The input method management service starts the InputMethodExtensionAbility component, returns the component to the application, and starts to manage its lifecycle.
**Figure 1** Using the InputMethodExtensionAbility component
![ExtensionAbility-start](figures/ExtensionAbility-start.png)
## Implementing ExtensionAbility of the Specified Type
The following uses [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md) as an example. The widget framework provides the base class [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md). You derive this base class to create your own class (such as **MyFormExtensionAbility**), implement the callbacks, such as **onCreate()** and **onUpdateForm()**, to provide specific widget functionalities. For details, see [FormExtensionAbility](Widget-development-stage.md).
You do not need to care when to add or delete a widget. The lifecycle of the FormExtensionAbility instance and the lifecycle of the ExtensionAbility process where the FormExtensionAbility instance is located are scheduled and managed by FormManagerService.
![form_extension](figures/form_extension.png)
> **NOTE**
>
> For an application, all ExtensionAbility components of the same type run in an independent process, whereas UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility run in another independent process. For details, see [Process Model (Stage Model)](process-model-stage.md).
>
> For example, an application has one UIAbility component, one ServiceExtensionAbility, one DataShareExtensionAbility, two FormExtensionAbility, and one ImeExtensionAbility. When the application is running, there are three processes:
>
> - UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility run in an independent process.
>
> - The two FormExtensionAbility components run in an independent process.
>
> - The two ImeExtensionAbility components run in an independent process.
# FA Model Development Overview
During application development based on the Feature Ability (FA) model, the following tasks are involved in the application model.
**Table 1** FA model development process
| Task| Introduction| Guide|
| -------- | -------- | -------- |
| Application component development| Use the PageAbility, ServiceAbility, DataAbility, and widgets of the FA model to develop applications.| - [Application- or Component-Level Configuration](application-component-configuration-fa.md)<br>- [PageAbility Component](pageability-overview.md)<br>- [ServiceAbility Component](serviceability-overview.md)<br>- [DataAbility Component](dataability-overview.md)<br>- [Widget Development](Widget-development-fa.md)<br>- [Context](application-context-fa.md)<br>- [Want](want-fa.md) |
| Inter-process communication (IPC)| Learn the process model and common IPC modes of the FA model.| [Common Events](common-event-fa.md)<br>[Background Services](rpc.md) |
| Inter-thread communication| Learn the thread model and common inter-thread communication modes of the FA model.| [Inter-Thread Communication](itc-fa-overview.md)|
| Mission management| Learn the basic concepts and typical scenarios of mission management in the FA model.| [Mission Management](mission-management-fa.md)|
| Application configuration file| Learn the requirements for developing application configuration files in the FA model.| [Application Configuration File](config-file-fa.md) |
# Component Interaction Between the FA Model and Stage Model
The FA model is supported by API version 8 and earlier versions, and the stage model is recommended since API version 9. The FA model and stage model have their respective components. The FA model provides three types of application components: PageAbility, ServiceAbility, and DataAbility. The stage model provides two types of application components: UIAbility and ExtensionAbility.
You cannot use both models for the development of an application (see the figure below). However, a device (system) can contain applications developed on both models (scenario 3 in the figure below). In this case, their components may interact with each other.
Figure 1 Coexistent application components of the FA model and stage model
![coexistence-of-FAandStage](figures/coexistence-of-FAandStage.png)
The following table lists the possible interaction scenarios. You must pay attention to the concerns listed below during your application development.
Table 1 Application component interaction scenarios
| Interaction Scenario| Concerns|
| -------- | -------- |
| [Starting a UIAbility from the FA Model](start-uiability-from-fa.md) | Set **bundleName** and **abilityName** in the **want** parameter to the bundle name and ability name of the UIAbility in the stage model.|
| [Connecting to a ServiceExtensionAbility from the FA Model](bind-serviceextensionability-from-fa.md) | Set **bundleName** and **abilityName** in the **want** parameter to the bundle name and ability name of the ServiceExtensionAbility in the stage model.|
| [Accessing a DataShareExtensionAbility from the FA Model](access-datashareextensionability-from-fa.md) | No code modification is required. However, you need to understand the API compatibility of **DataShareHelper** and **DataAbilityHelper**.|
| [Starting a PageAbility from the Stage Model](start-pageability-from-stage.md) | Set **bundleName** and **abilityName** in the **want** parameter to the bundle name and ability name of the PageAbility in the FA model.|
| [Connecting to a ServiceAbility from the Stage Model](bind-serviceability-from-stage.md) | Set **bundleName** and **abilityName** in the **want** parameter to the bundle name and ability name of the ServiceAbility in the FA model.|
| Accessing a DataAbility from the Stage Model | This type of access is not supported.|
# featureAbility Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model|
| -------- | -------- | -------- |
| [getWant(callback: AsyncCallback&lt;Want&gt;): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitygetwant)<br>[getWant(): Promise&lt;Want&gt;;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitygetwant-1) | \@ohos.app.ability.UIAbility.d.ts | [launchWant: Want;](../reference/apis/js-apis-app-ability-uiAbility.md#attributes)|
| [startAbility(parameter: StartAbilityParameter, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartability)<br>[startAbility(parameter: StartAbilityParameter): Promise&lt;number&gt;;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartability-1) | application\UIAbilityContext.d.ts | [startAbility(want: Want, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartability)<br>[startAbility(want: Want, options: StartOptions, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartability-1)<br>[startAbility(want: Want, options?: StartOptions): Promise&lt;void&gt;;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartability-2) |
| [getContext(): Context;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitygetcontext) | \@ohos.app.ability.UIAbility.d.ts | [context: UIAbilityContext;](../reference/apis/js-apis-app-ability-uiAbility.md#attributes)|
| [startAbilityForResult(parameter: StartAbilityParameter, callback: AsyncCallback&lt;AbilityResult&gt;): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartabilityforresult7)<br>[startAbilityForResult(parameter: StartAbilityParameter): Promise&lt;AbilityResult&gt;;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartabilityforresult7-1) | application\UIAbilityContext.d.ts | [startAbilityForResult(want: Want, callback: AsyncCallback&lt;AbilityResult&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilityforresult)<br>[startAbilityForResult(want: Want, options: StartOptions, callback: AsyncCallback&lt;AbilityResult&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilityforresult-1)<br>[startAbilityForResult(want: Want, options?: StartOptions): Promise&lt;AbilityResult&gt;;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilityforresult-2) |
| [terminateSelfWithResult(parameter: AbilityResult, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilityterminateselfwithresult7)<br>[terminateSelfWithResult(parameter: AbilityResult): Promise&lt;void&gt;;](../reference/apis/js-apis-ability-featureAbility.md#featureabilityterminateselfwithresult7-1) | application\UIAbilityContext.d.ts | [terminateSelfWithResult(parameter: AbilityResult, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextterminateselfwithresult)<br>[terminateSelfWithResult(parameter: AbilityResult): Promise&lt;void&gt;;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextterminateselfwithresult-1) |
| [terminateSelf(callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilityterminateself7)<br>[terminateSelf(): Promise&lt;void&gt;;](../reference/apis/js-apis-ability-featureAbility.md#featureabilityterminateself7-1) | application\UIAbilityContext.d.ts | [terminateSelf(callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextterminateself)<br>[terminateSelf(): Promise&lt;void&gt;;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextterminateself-1) |
| [acquireDataAbilityHelper(uri: string): DataAbilityHelper;](../reference/apis/js-apis-ability-featureAbility.md#featureabilityacquiredataabilityhelper7) | \@ohos.data.dataShare.d.ts<br>\@ohos.data.fileAccess.d.ts | [createDataShareHelper(context: Context, uri: string, callback: AsyncCallback&lt;DataShareHelper&gt;): void;](../reference/apis/js-apis-data-dataShare.md#datasharecreatedatasharehelper)<br>[createDataShareHelper(context: Context, uri: string): Promise&lt;DataShareHelper&gt;;](../reference/apis/js-apis-data-dataShare.md#datasharecreatedatasharehelper-1)<br>[createFileAccessHelper(context: Context): FileAccessHelper;](../reference/apis/js-apis-fileAccess.md#fileaccesscreatefileaccesshelper-1)<br>[createFileAccessHelper(context: Context, wants: Array&lt;Want&gt;): FileAccessHelper;](../reference/apis/js-apis-fileAccess.md#fileaccesscreatefileaccesshelper) |
| [hasWindowFocus(callback: AsyncCallback&lt;boolean&gt;): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilityhaswindowfocus7)<br>[hasWindowFocus(): Promise&lt;boolean&gt;;](../reference/apis/js-apis-ability-featureAbility.md#featureabilityhaswindowfocus7-1) | \@ohos.window.d.ts | [on(eventType: 'windowStageEvent', callback: Callback&lt;WindowStageEventType&gt;): void;](../reference/apis/js-apis-window.md#onwindowstageevent9)<br>Checks whether the [active window](../reference/apis/js-apis-window.md#windowstageeventtype9) has the focus.|
| [connectAbility(request: Want, options:ConnectOptions ): number;](../reference/apis/js-apis-ability-featureAbility.md#featureabilityconnectability7) | application\UIAbilityContext.d.ts | [connectServiceExtensionAbility(want: Want, options: ConnectOptions): number;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextconnectserviceextensionability) |
| [disconnectAbility(connection: number, callback:AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitydisconnectability7)<br>[disconnectAbility(connection: number): Promise&lt;void&gt;;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitydisconnectability7-1) | application\UIAbilityContext.d.ts | [disconnectAbility(connection: number, callback:AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextdisconnectserviceextensionability-1)<br>[disconnectAbility(connection: number): Promise&lt;void&gt;;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextdisconnectserviceextensionability) |
| [getWindow(callback: AsyncCallback&lt;window.Window&gt;): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitygetwindow7)<br>[getWindow(): Promise&lt;window.Window&gt;;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitygetwindow7-1) | \@ohos.window.d.ts | [getLastWindow(ctx: BaseContext, callback: AsyncCallback&lt;Window&gt;): void;](../reference/apis/js-apis-window.md#windowgetlastwindow9)<br>[getLastWindow(ctx: BaseContext): Promise&lt;Window&gt;;](../reference/apis/js-apis-window.md#windowgetlastwindow9-1) |
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册