diff --git a/CODEOWNERS b/CODEOWNERS index e9503e13f3c5ba3f95847fc264284eb6feca9c9f..1e61b5d70d7ea0768b8683ea7956a4b34e212a5c 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -517,6 +517,7 @@ zh-cn/application-dev/reference/apis/js-apis-commonEventManager.md @jayleehw @Ra zh-cn/application-dev/reference/apis/js-apis-configPolicy.md @Buda-Liu @ningningW @budda-wang @yangqing3 zh-cn/application-dev/reference/apis/js-apis-cooperate.md @mayunteng_1 @ningningW @cococoler @alien0208 zh-cn/application-dev/reference/apis/js-apis-cryptoFramework.md @gaoyong @zengyawen @niejiteng @jumozhanjiang +zh-cn/application-dev/reference/apis/js-apis-cert.md @gaoyong @zengyawen @niejiteng @jumozhanjiang zh-cn/application-dev/reference/apis/js-apis-curve.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy zh-cn/application-dev/reference/apis/js-apis-defaultAppManager.md @shuaytao @RayShih @wangzhen107 @inter515 zh-cn/application-dev/reference/apis/js-apis-distributedBundle.md @shuaytao @RayShih @wangzhen107 @inter515 diff --git a/en/application-dev/application-models/Readme-EN.md b/en/application-dev/application-models/Readme-EN.md index a9473b7f6c2d0fb75e160cafdd1fb94b43633fa7..2a920300623358bc25f7256d6af8b957665bc600 100644 --- a/en/application-dev/application-models/Readme-EN.md +++ b/en/application-dev/application-models/Readme-EN.md @@ -1,2 +1,130 @@ # 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](datashareextensionability.md) + - [FormExtensionAbility (Widget)](widget-development-stage.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](hop-cross-device-migration.md) + - [Multi-device Collaboration](hop-multi-device-collaboration.md) + - IPC + - [Process Model](process-model-stage.md) + - Common Events + - [Introduction to Common Events](common-event-overview.md) + - [Subscribing to Common Events](common-event-subscription.md) + - [Publishing Common Events](common-event-publish.md) + - [Unsubscribing from Common Events](common-event-unsubscription.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) + - [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](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) diff --git a/en/application-dev/application-models/ability-startup-with-explicit-want.md b/en/application-dev/application-models/ability-startup-with-explicit-want.md new file mode 100644 index 0000000000000000000000000000000000000000..9186379f32299ee7a42b7f82af4fc7f464c160d1 --- /dev/null +++ b/en/application-dev/application-models/ability-startup-with-explicit-want.md @@ -0,0 +1,4 @@ +# 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, the explicit Want is used. For details about how to use the explicit Want, see [Starting UIAbility in the Same Application](uiability-intra-device-interaction.md#starting-uiability-in-the-same-application). diff --git a/en/application-dev/application-models/ability-startup-with-implicit-want.md b/en/application-dev/application-models/ability-startup-with-implicit-want.md new file mode 100644 index 0000000000000000000000000000000000000000..0a5ba865f4b8c9894523666de1582b012f8f2237 --- /dev/null +++ b/en/application-dev/application-models/ability-startup-with-implicit-want.md @@ -0,0 +1,83 @@ +# Using Implicit Want to Open a Website + + +## Prerequisites + +One or more browsers are installed on your device. + +The **module.json5** of a browser application is as follows: + +```json +"skills": [ + { + "entities": [ + "entity.system.browsable" + // ... + ], + "actions": [ + "ohos.want.action.viewData" + // ... + ], + "uris": [ + { + "scheme": "https", + "host": "www.test.com", + "port": "8080", + // Prefix matching is used. + "pathStartWith": "query", + "type": "text/*" + }, + { + "scheme": "http", + // ... + } + // ... + ] + }, +] +``` + + +## How to Develop + +1. Use the custom function **implicitStartAbility** to start an ability. + + ```ts + async implicitStartAbility() { + try { + let want = { + // 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" + } + let context = getContext(this) as common.UIAbilityContext; + await context.startAbility(want) + console.info(`explicit start ability succeed`) + } catch (error) { + console.info(`explicit start ability failed with ${error.code}`) + } + let context = getContext(this) as common.UIAbilityContext; + await context.startAbility(want) + console.info(`explicit start ability succeed`) + } catch (error) { + console.info(`explicit start ability failed with ${error.code}`) + } + } + ``` + + The matching process is as follows: + 1. If **action** in the passed **want** parameter is specified and is included in **actions** under **skills**, the matching is successful. + + 2. If **entities** in the passed **want** parameter is specified and is included in **entities** under **skills**, the matching is successful. + + 3. If **uri** in the passed **want** parameter is included in **uris** under **skills**, 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**, the matching is successful. + +2. When there are multiple matching applications, a dialog box is displayed for you to select one of them. + +stage-want1 \ No newline at end of file diff --git a/en/application-dev/application-models/abilitystage.md b/en/application-dev/application-models/abilitystage.md new file mode 100644 index 0000000000000000000000000000000000000000..fa3aa07c60287688749c13035451d0b470e621ea --- /dev/null +++ b/en/application-dev/application-models/abilitystage.md @@ -0,0 +1,58 @@ +# 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"; + } + } + ``` + + +[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. + } + } + ``` + + \ No newline at end of file diff --git a/en/application-dev/application-models/access-dataability.md b/en/application-dev/application-models/access-dataability.md new file mode 100644 index 0000000000000000000000000000000000000000..24dc9305f194a61c974c63db224f2e7727689f5f --- /dev/null +++ b/en/application-dev/application-models/access-dataability.md @@ -0,0 +1,204 @@ +# 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). diff --git a/en/application-dev/application-models/access-datashareextensionability-from-fa.md b/en/application-dev/application-models/access-datashareextensionability-from-fa.md new file mode 100644 index 0000000000000000000000000000000000000000..0abc7e3b8e948529b9916f936bf59b4a60a93637 --- /dev/null +++ b/en/application-dev/application-models/access-datashareextensionability-from-fa.md @@ -0,0 +1,52 @@ +# 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| diff --git a/en/application-dev/application-models/actions-entities.md b/en/application-dev/application-models/actions-entities.md new file mode 100644 index 0000000000000000000000000000000000000000..2479ab317cfdff8bc642f3f307fb4d8423efe112 --- /dev/null +++ b/en/application-dev/application-models/actions-entities.md @@ -0,0 +1,25 @@ +# Common action and entities Values + +The [action](../reference/apis/js-apis-ability-wantConstant.md#wantconstantaction) field specifies the common operation (such as viewing, sharing, and application details) to be performed 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. + +The [entities](../reference/apis/js-apis-ability-wantConstant.md#wantconstantentity) field specifies the additional 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. diff --git a/en/application-dev/application-models/api-switch-overview.md b/en/application-dev/application-models/api-switch-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..461e321d410a7f0036f5b4a1700c6176d7d451da --- /dev/null +++ b/en/application-dev/application-models/api-switch-overview.md @@ -0,0 +1,41 @@ +# 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: "ohos.samples.demo", + abilityName: "ohos.samples.demo.MainAbility" + } + } + 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: "ohos.samples.demo", + abilityName: "ohos.samples.demo.MainAbility" + }; + this.context.startAbility(wantInfo).then((data) => { + console.info('startAbility success.'); + }).catch((error) => { + console.error('startAbility failed.'); + }) + ``` diff --git a/en/application-dev/application-models/app-deviceconfig-switch.md b/en/application-dev/application-models/app-deviceconfig-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..8630746cb46979d1a7e37c2c6e30787ad5fe91ec --- /dev/null +++ b/en/application-dev/application-models/app-deviceconfig-switch.md @@ -0,0 +1,31 @@ +# 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": {
"code": 1,
} | "versionCode": 1 , | +| Text description of the version number, which is displayed to users| "version": {
"name": "1.0.0",
} | "versionName" : "1.0.0" , | +| Earliest compatible version of the application| "version": {
"minCompatibleVersionCode": 1,
} | "minCompatibleVersionCode" : 1 , | +| Minimum API version required for application running| "apiVersion": {
"compatible": 7,
} | "minAPIVersion" : 7 , | +| Target API version required for application running| "apiVersion": {
"target": 8,
} | "targetApiVersion" : 8 , | +| Type of the target API version required for application running| "apiVersion": {
"releaseType": Release,
} | "apiReleaseType": "Release" , | + + +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.| + + \ No newline at end of file diff --git a/en/application-dev/application-models/application-component-configuration-fa.md b/en/application-dev/application-models/application-component-configuration-fa.md new file mode 100644 index 0000000000000000000000000000000000000000..d460966545bc6e4901169779f0450308b44c8866 --- /dev/null +++ b/en/application-dev/application-models/application-component-configuration-fa.md @@ -0,0 +1,41 @@ +# 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). + + \ No newline at end of file diff --git a/en/application-dev/application-models/application-component-configuration-stage.md b/en/application-dev/application-models/application-component-configuration-stage.md new file mode 100644 index 0000000000000000000000000000000000000000..56a5ddac56d43e09609fa8e6e9669fab39681988 --- /dev/null +++ b/en/application-dev/application-models/application-component-configuration-stage.md @@ -0,0 +1,74 @@ +# 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** + + 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 icon is usually displayed in an application list, for example, the application list in **Settings**. + + 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. + + The **icon** and **label** fields in the **app.json5** file are under **app**, as follows: + + ```json + { + "app": { + "icon": "$media:app_icon", + "label": "$string:app_name" + // ... + } + } + ``` + +- **Configuring the entry icon and label** + + The entry icon and label are configured by specifying **icon** and **label** under **abilities** in the [module.json5 file](../quick-start/module-configuration-file.md). For example, if you want to display the icon and label of the UIAbility component on the home screen, add **entity.system.home** to **entities** and **action.system.home** to **actions** under **skills**. If the preceding fields are configured for multiple UIAbility components of an application, multiple icons and labels 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": [ + "action.system.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. + + \ No newline at end of file diff --git a/en/application-dev/application-models/application-context-fa.md b/en/application-dev/application-models/application-context-fa.md new file mode 100644 index 0000000000000000000000000000000000000000..9f68b42a873782c9fd1693c73724354cbf347ced --- /dev/null +++ b/en/application-dev/application-models/application-context-fa.md @@ -0,0 +1,66 @@ +# 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') + }, + } + ``` diff --git a/en/application-dev/application-models/application-context-stage.md b/en/application-dev/application-models/application-context-stage.md new file mode 100644 index 0000000000000000000000000000000000000000..af8f5d82a3f162381f4b970c82e0def06b91070b --- /dev/null +++ b/en/application-dev/application-models/application-context-stage.md @@ -0,0 +1,311 @@ +# 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 + +- The figure below illustrates the holding relationship of contexts. + context-holding + +- 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 the ability, obtain the ability configuration, request permissions from users, and more. + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility'; + export default class EntryAbility extends UIAbility { + onCreate(want, launchParam) { + let uiAbilityContext = this.context; + // ... + } + } + ``` + - 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 ability 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 Ability Lifecycle Changes in a Process](#subscribing-to-ability-lifecycle-changes-in-a-process) + +- [Requesting Permissions from Users Through AbilityContext](#requesting-permissions-from-users-through-uiabilitycontext) + + +### 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.
It is the content of **Storage** of an application under **Settings > Apps & services > Apps**.| +| tempDir | string | Yes| No| Temporary file directory of the application.
Files in this directory are deleted after the application is uninstalled.| +| filesDir | string | Yes| No| File directory of the application on the internal storage.
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 + +- 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; + // ... + } +} +``` + + +### 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 Ability 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 ability lifecycle changes. + +When the ability 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(ability) { + console.info(TAG, "onAbilityCreate ability:" + JSON.stringify(ability)); + }, + onWindowStageCreate(ability, windowStage) { + console.info(TAG, "onWindowStageCreate ability:" + JSON.stringify(ability)); + console.info(TAG, "onWindowStageCreate windowStage:" + JSON.stringify(windowStage)); + }, + onWindowStageActive(ability, windowStage) { + console.info(TAG, "onWindowStageActive ability:" + JSON.stringify(ability)); + console.info(TAG, "onWindowStageActive windowStage:" + JSON.stringify(windowStage)); + }, + onWindowStageInactive(ability, windowStage) { + console.info(TAG, "onWindowStageInactive ability:" + JSON.stringify(ability)); + console.info(TAG, "onWindowStageInactive windowStage:" + JSON.stringify(windowStage)); + }, + onWindowStageDestroy(ability, windowStage) { + console.info(TAG, "onWindowStageDestroy ability:" + JSON.stringify(ability)); + console.info(TAG, "onWindowStageDestroy windowStage:" + JSON.stringify(windowStage)); + }, + onAbilityDestroy(ability) { + console.info(TAG, "onAbilityDestroy ability:" + JSON.stringify(ability)); + }, + onAbilityForeground(ability) { + console.info(TAG, "onAbilityForeground ability:" + JSON.stringify(ability)); + }, + onAbilityBackground(ability) { + console.info(TAG, "onAbilityBackground ability:" + JSON.stringify(ability)); + }, + onAbilityContinue(ability) { + console.info(TAG, "onAbilityContinue ability:" + JSON.stringify(ability)); + } + } + // 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)); + }); + } +} +``` + + +### Requesting Permissions from Users Through UIAbilityContext + +Each ability has the **Context** attribute. The ability is used to process the lifecycle. Methods use to operate the ability (such as **startAbility()**, **connectServiceExtensionAbility()**, and **terminateSelf()**) are implemented in the corresponding context. The context also provides methods for obtaining the ability configuration and requesting permissions from users. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). + + +When an application needs to obtain users' privacy information or use system capabilities, for example, to obtain location information, to access the calendar, or to use the camera to take photos or record videos, the application must request permissions from users, as shown below. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md). + +**Figure 2** Requesting the permission to access the calendar from users +application-context-stage \ No newline at end of file diff --git a/en/application-dev/application-models/application-model-composition.md b/en/application-dev/application-models/application-model-composition.md new file mode 100644 index 0000000000000000000000000000000000000000..2d7ed88490136c6e94277e94da375278fcab0adf --- /dev/null +++ b/en/application-dev/application-models/application-model-composition.md @@ -0,0 +1,27 @@ +# 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. diff --git a/en/application-dev/application-models/application-model-description.md b/en/application-dev/application-models/application-model-description.md new file mode 100644 index 0000000000000000000000000000000000000000..2c15a15ee2aa30c9e56a04fb21497af01969cd07 --- /dev/null +++ b/en/application-dev/application-models/application-model-description.md @@ -0,0 +1,61 @@ +# 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
- PageAbility: has the UI and supports user interaction. For details, see [PageAbility Component Overview](pageability-overview.md).
- ServiceAbility: provides background services and has no UI. For details, see [ServiceAbility Component Overview](serviceability-overview.md).
- DataAbility: provides the data sharing capability and has no UI. For details, see [DataAbility Component Overview](dataability-overview.md).
2. Development mode
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
- UIAbility: has the UI and supports user interaction. For details, see [UIAbility Component Overview](uiability-overview.md).
- ExtensionAbility: provides extension capabilities (such as widget and input methods) for specific scenarios. For details, see [ExtensionAbility Component Overview](extensionability-overview.md).
2. Development mode
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:
1. Main process
2. Rendering process
For details, see [Process Model (FA Model)](process-model-fa.md). | There are three types of processes:
1. Main process
2. ExtensionAbility process
3. Rendering process
For details, see [Process Model (Stage Model)](process-model-stage.md). | +| **Thread model**| 1. ArkTS engine instance creation
A process can run multiple application component instances, and each application component instance runs in an independent ArkTS engine instance.
2. Thread model
Each ArkTS engine instance is created on an independent thread (non-main thread). The main thread does not have an ArkTS engine instance.
3. Intra-process object sharing: not supported.
For details, see [Thread Model (FA Model)](thread-model-fa.md). | 1. ArkTS engine instance creation
A process can run multiple application component instances, and all application component instances share one ArkTS engine instance.
2. Thread model
The ArkTS engine instance is created on the main thread.
3. Intra-process object sharing: supported.
For details, see [Thread Model (Stage Model)](thread-model-stage.md). | +| **Mission management model**| - A mission is created for each PageAbility component instance.
- Missions are stored persistently until the number of missions exceeds the maximum (customized based on the product configuration) or users delete missions.
- PageAbility components do not form a stack structure.
For details, see [Mission Management Scenarios](mission-management-overview.md).| - A mission is created for each UIAbility component instance.
- Missions are stored persistently until the number of missions exceeds the maximum (customized based on the product configuration) or users delete missions.
- UIAbility components do not form a stack structure.
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.
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.
For details, see [Application Configuration File Overview (Stage Model)](../quick-start/application-configuration-file-overview-stage.md).| + + \ No newline at end of file diff --git a/en/application-dev/application-models/background-services.md b/en/application-dev/application-models/background-services.md new file mode 100644 index 0000000000000000000000000000000000000000..77ed5d98c0798037e57f2867b8e216928bfc2240 --- /dev/null +++ b/en/application-dev/application-models/background-services.md @@ -0,0 +1,7 @@ +# 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). diff --git a/en/application-dev/application-models/bind-serviceability-from-stage.md b/en/application-dev/application-models/bind-serviceability-from-stage.md new file mode 100644 index 0000000000000000000000000000000000000000..0ee35195b8810efea9af4382c80d0c8e37e0fd70 --- /dev/null +++ b/en/application-dev/application-models/bind-serviceability-from-stage.md @@ -0,0 +1,90 @@ +# 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 MainAbility extends UIAbility { + onCreate(want, launchParam) { + console.info("MainAbility onCreate"); + } + onDestroy() { + console.info("MainAbility onDestroy") + } + onWindowStageCreate(windowStage) { + console.info("MainAbility 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("MainAbility onWindowStageDestroy") + } + onForeground() { + console.info("MainAbility onForeground") + } + onBackground() { + console.info("MainAbility 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); + } +} +``` diff --git a/en/application-dev/application-models/bind-serviceextensionability-from-fa.md b/en/application-dev/application-models/bind-serviceextensionability-from-fa.md new file mode 100644 index 0000000000000000000000000000000000000000..e5f90bf9d6b7616261d2ae1eb1e62438fe2e71e3 --- /dev/null +++ b/en/application-dev/application-models/bind-serviceextensionability-from-fa.md @@ -0,0 +1,60 @@ +# 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); +``` diff --git a/en/application-dev/application-models/common-event-fa.md b/en/application-dev/application-models/common-event-fa.md new file mode 100644 index 0000000000000000000000000000000000000000..9e2f44144d8f028c61c538b48797f5842a48d2a7 --- /dev/null +++ b/en/application-dev/application-models/common-event-fa.md @@ -0,0 +1,4 @@ +# Common Events (FA Model) + + +For details, see [Common Events](common-event-overview.md) in the stage model. diff --git a/en/application-dev/application-models/common-event-overview.md b/en/application-dev/application-models/common-event-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..0d3788b41b516d0af9619d320ceeefc3f52c74c5 --- /dev/null +++ b/en/application-dev/application-models/common-event-overview.md @@ -0,0 +1,28 @@ +# 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: CES forwards common events based on the subscription sequence, regardless of whether subscribers receive the events. + +- Ordered common event: CES forwards common events to the next subscriber only after receiving a reply from the previous subscriber. + +- Sticky common event: a public event that can be sent to a subscriber before they initiate a subscription. Only system applications or system services can send sticky common event, and they must 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 diff --git a/en/application-dev/application-models/common-event-publish.md b/en/application-dev/application-models/common-event-publish.md new file mode 100644 index 0000000000000000000000000000000000000000..b29c137319fcbb1fe4eaff8e262dca1a403c87e4 --- /dev/null +++ b/en/application-dev/application-models/common-event-publish.md @@ -0,0 +1,78 @@ +# 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') + } + }) + ``` diff --git a/en/application-dev/application-models/common-event-subscription.md b/en/application-dev/application-models/common-event-subscription.md new file mode 100644 index 0000000000000000000000000000000000000000..ce61e40458a7cbd5c9ec226138535da93d3766b1 --- /dev/null +++ b/en/application-dev/application-models/common-event-subscription.md @@ -0,0 +1,69 @@ +# Subscribing to Common Events + + +## When to Use + +You can create a subscriber object to subscribe to a common event so as to obtain the parameters passed in the event. 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<[CommonEventData](../reference/apis/js-apis-commonEventManager.md#commoneventdata)>): void | Creates a subscriber. This API uses an asynchronous callback to return the result.| +| createSubscriber(subscribeInfo: CommonEventSubscribeInfo): Promise<CommonEventSubscriber> | 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`); + } + ``` diff --git a/en/application-dev/application-models/common-event-unsubscription.md b/en/application-dev/application-models/common-event-unsubscription.md new file mode 100644 index 0000000000000000000000000000000000000000..c87017ef08c05e8a22097c4bd2a05f52fc758134 --- /dev/null +++ b/en/application-dev/application-models/common-event-unsubscription.md @@ -0,0 +1,40 @@ +# Unsubscribing from Common Events + + +## 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. + + +## 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](common-event-subscription.md). + +3. Call **unsubscribe** in **CommonEvent** to unsubscribe from the common event. + + ```ts + // The subscriber object iscreated 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; + } + }) + } + ``` diff --git a/en/application-dev/application-models/component-startup-rules-fa.md b/en/application-dev/application-models/component-startup-rules-fa.md new file mode 100644 index 0000000000000000000000000000000000000000..15788e109c4406d740f403d3e21a27d7d0a451c6 --- /dev/null +++ b/en/application-dev/application-models/component-startup-rules-fa.md @@ -0,0 +1,70 @@ +# 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-tag) + +- **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) + + \ No newline at end of file diff --git a/en/application-dev/application-models/component-startup-rules.md b/en/application-dev/application-models/component-startup-rules.md new file mode 100644 index 0000000000000000000000000000000000000000..a00d01780d9bf67b6b64ec90b4c3bd0635865c74 --- /dev/null +++ b/en/application-dev/application-models/component-startup-rules.md @@ -0,0 +1,65 @@ +# 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-tag) + +- **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) + + \ No newline at end of file diff --git a/en/application-dev/application-models/config-file-fa.md b/en/application-dev/application-models/config-file-fa.md new file mode 100644 index 0000000000000000000000000000000000000000..f19104d0db5b36346ff3f868d0fb9e5773460ac1 --- /dev/null +++ b/en/application-dev/application-models/config-file-fa.md @@ -0,0 +1,7 @@ +# 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). + + \ No newline at end of file diff --git a/en/application-dev/application-models/config-file-stage.md b/en/application-dev/application-models/config-file-stage.md new file mode 100644 index 0000000000000000000000000000000000000000..bf667dcb0d33228581cfbec3a7ab4750a3cb4b94 --- /dev/null +++ b/en/application-dev/application-models/config-file-stage.md @@ -0,0 +1,7 @@ +# 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). + + \ No newline at end of file diff --git a/en/application-dev/application-models/configuration-file-diff.md b/en/application-dev/application-models/configuration-file-diff.md new file mode 100644 index 0000000000000000000000000000000000000000..141eeab16f692b144c57488918e978217e61d08f --- /dev/null +++ b/en/application-dev/application-models/configuration-file-diff.md @@ -0,0 +1,12 @@ +# 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) + + \ No newline at end of file diff --git a/en/application-dev/application-models/connect-serviceability.md b/en/application-dev/application-models/connect-serviceability.md new file mode 100644 index 0000000000000000000000000000000000000000..ac2acb898a3bd7ef905b8a33dc10f7980ce74548 --- /dev/null +++ b/en/application-dev/application-models/connect-serviceability.md @@ -0,0 +1,93 @@ +# 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 + } +} +``` diff --git a/en/application-dev/application-models/context-switch.md b/en/application-dev/application-models/context-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..2f52158f5d36be8c59f747376195e9e43078d1f9 --- /dev/null +++ b/en/application-dev/application-models/context-switch.md @@ -0,0 +1,28 @@ +# 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<string>):void;](../reference/apis/js-apis-inner-app-context.md#contextgetorcreatelocaldir7)
[getOrCreateLocalDir():Promise<string>;](../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<number>):void;](../reference/apis/js-apis-inner-app-context.md#contextverifypermission7)
[verifyPermission(permission:string,callback:AsyncCallback<number>):void;](../reference/apis/js-apis-inner-app-context.md#contextverifypermission7-1)
[verifyPermission(permission:string,options?:PermissionOptions):Promise<number>;](../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)
[verifyAccessToken(tokenID: number, permissionName: Permissions): Promise<GrantStatus>;](../reference/apis/js-apis-abilityAccessCtrl.md#verifyaccesstoken9) | +| [requestPermissionsFromUser(permissions:Array<string>,requestCode:number,resultCallback:AsyncCallback<PermissionRequestResult>):void;](../reference/apis/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7)
[requestPermissionsFromUser(permissions:Array<string>,requestCode:number):Promise<PermissionRequestResult>;](../reference/apis/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7-1) | application\UIAbilityContext.d.ts | [requestPermissionsFromUser(permissions: Array<string>, requestCallback: AsyncCallback<PermissionRequestResult>) : void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextrequestpermissionsfromuser)
[requestPermissionsFromUser(permissions: Array<string>) : Promise<PermissionRequestResult>;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextrequestpermissionsfromuser-1) | +| [getApplicationInfo(callback:AsyncCallback<ApplicationInfo>):void;](../reference/apis/js-apis-inner-app-context.md#contextgetapplicationinfo7)
[getApplicationInfo():Promise<ApplicationInfo>;](../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<string>): void;](../reference/apis/js-apis-inner-app-context.md#contextgetbundlename7)
[getBundleName(): Promise<string>;](../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<bundle.DisplayOrientation>): void;](../reference/apis/js-apis-inner-app-context.md#contextgetdisplayorientation7)
[getDisplayOrientation(): Promise<bundle.DisplayOrientation>;](../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<void>):void;](../reference/apis/js-apis-inner-app-context.md#contextsetdisplayorientation7)
[setDisplayOrientation(orientation:bundle.DisplayOrientation):Promise<void>;](../reference/apis/js-apis-inner-app-context.md#contextsetdisplayorientation7-1) | \@ohos.screen.d.ts | [setOrientation(orientation: Orientation, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-screen.md#setorientation)
[setOrientation(orientation: Orientation): Promise<void>;](../reference/apis/js-apis-screen.md#setorientation-1) | +| [setShowOnLockScreen(show:boolean, callback:AsyncCallback<void>):void;](../reference/apis/js-apis-inner-app-context.md#contextsetshowonlockscreen7)
[setShowOnLockScreen(show:boolean):Promise<void>;](../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<void>):void;](../reference/apis/js-apis-inner-app-context.md#contextsetwakeupscreen7)
[setWakeUpScreen(wakeUp:boolean):Promise<void>;](../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<ProcessInfo>):void;](../reference/apis/js-apis-inner-app-context.md#contextgetprocessinfo7)
[getProcessInfo():Promise<ProcessInfo>;](../reference/apis/js-apis-inner-app-context.md#contextgetprocessinfo7-1) | \@ohos.app.ability.abilityManager.d.ts | [getAbilityRunningInfos(callback: AsyncCallback<Array<AbilityRunningInfo>>): void;](../reference/apis/js-apis-app-ability-abilityManager.md#getabilityrunninginfos)
[getAbilityRunningInfos(): Promise<Array<AbilityRunningInfo>>;](../reference/apis/js-apis-app-ability-abilityManager.md#getabilityrunninginfos-1) | +| [getElementName(callback:AsyncCallback<ElementName>):void;](../reference/apis/js-apis-inner-app-context.md#contextgetelementname7)
[getElementName():Promise<ElementName>;](../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)
[abilityInfo.bundleName: string;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#attributes)| +| [getProcessName(callback:AsyncCallback<string>):void;](../reference/apis/js-apis-inner-app-context.md#contextgetprocessname7)
[getProcessName():Promise<string>;](../reference/apis/js-apis-inner-app-context.md#contextgetprocessname7-1) | \@ohos.app.ability.abilityManager.d.ts | [getAbilityRunningInfos(callback: AsyncCallback<Array<AbilityRunningInfo>>): void;](../reference/apis/js-apis-app-ability-abilityManager.md#getabilityrunninginfos)
[getAbilityRunningInfos(): Promise<Array<AbilityRunningInfo>>;](../reference/apis/js-apis-app-ability-abilityManager.md#getabilityrunninginfos-1) | +| [getCallingBundle(callback:AsyncCallback<string>):void;](../reference/apis/js-apis-inner-app-context.md#contextgetcallingbundle7)
[getCallingBundle():Promise<string>;](../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<string>):void;](../reference/apis/js-apis-inner-app-context.md#contextgetfilesdir)
[getFilesDir():Promise<string>;](../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<string>):void;](../reference/apis/js-apis-inner-app-context.md#contextgetcachedir)
[getCacheDir():Promise<string>;](../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<string>):void;](../reference/apis/js-apis-inner-app-context.md#contextgetorcreatedistributeddir7)
[getOrCreateDistributedDir():Promise<string>;](../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<string>):void;](../reference/apis/js-apis-inner-app-context.md#contextgetapptype7)
[getAppType():Promise<string>;](../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.
[abilityInfo.type: bundleManager.AbilityType;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#attributes)| +| [getHapModuleInfo(callback:AsyncCallback<HapModuleInfo>):void;](../reference/apis/js-apis-inner-app-context.md#contextgethapmoduleinfo7)
[getHapModuleInfo():Promise<HapModuleInfo>;](../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<AppVersionInfo>):void;](../reference/apis/js-apis-inner-app-context.md#contextgetappversioninfo7)
[getAppVersionInfo():Promise<AppVersionInfo>;](../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)
[readonly versionCode: number;](../reference/apis/js-apis-bundleManager-bundleInfo.md#bundleinfo-1)
[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<AbilityInfo>):void;](../reference/apis/js-apis-inner-app-context.md#contextgetabilityinfo7)
[getAbilityInfo():Promise<AbilityInfo>;](../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<boolean>):void;](../reference/apis/js-apis-inner-app-context.md#contextisupdatingconfigurations7)
[isUpdatingConfigurations():Promise<boolean>;](../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<void>):void;](../reference/apis/js-apis-inner-app-context.md#contextprintdrawncompleted7)
[printDrawnCompleted():Promise<void>;](../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.| diff --git a/en/application-dev/application-models/create-dataability.md b/en/application-dev/application-models/create-dataability.md new file mode 100644 index 0000000000000000000000000000000000000000..488b0593dbdc23bc1e6ea30c17f9165a92c79f20 --- /dev/null +++ b/en/application-dev/application-models/create-dataability.md @@ -0,0 +1,62 @@ +# 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) + } +}; +``` diff --git a/en/application-dev/application-models/create-pageability.md b/en/application-dev/application-models/create-pageability.md new file mode 100644 index 0000000000000000000000000000000000000000..7a79770c309a165b8421974b28263bb20fa587ee --- /dev/null +++ b/en/application-dev/application-models/create-pageability.md @@ -0,0 +1,96 @@ +# 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 MainAbility: + +```json +{ + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "visible": true, + "srcPath": "MainAbility", + "name": ".MainAbility", + "srcLanguage": "ets", + "icon": "$media:icon", + "description": "$string:MainAbility_desc", + "formsEnabled": false, + "label": "$string:MainAbility_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); +})() +``` diff --git a/en/application-dev/application-models/create-serviceability.md b/en/application-dev/application-models/create-serviceability.md new file mode 100644 index 0000000000000000000000000000000000000000..78623839266f4e97de26d0a3d66c19236eacf815 --- /dev/null +++ b/en/application-dev/application-models/create-serviceability.md @@ -0,0 +1,61 @@ +# 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 + } + ] + } + } + ``` diff --git a/en/application-dev/application-models/data-share-via-want.md b/en/application-dev/application-models/data-share-via-want.md new file mode 100644 index 0000000000000000000000000000000000000000..63d7d26d47b64407e30fc03c2edb7ead210dc392 --- /dev/null +++ b/en/application-dev/application-models/data-share-via-want.md @@ -0,0 +1,111 @@ +# 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. + + +## Prerequisites + +1. There are 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 through **startAbility()**, the application selector is started. 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 that application to complete data sharing. + +2. 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 the Want configuration used for data sharing. + +3. The following actions are involved in this section: + - **ACTION_SELECT (ohos.want.action.select)**: action of displaying the application selector. + - **ACTION_SEND_DATA (ohos.want.action.sendData)**: action of launching the UI for sending a single data record. It is used to transfer data to the shared party. + + +## How to Develop + +- Sharing party + 1. In the stage mode, the [File Descriptor (FD)](../reference/apis/js-apis-fileio.md#fileioopensync) is used for file transfer. This example assumes that the path of the file to share is obtained. + + ```ts + import fileIO from '@ohos.fileio'; + + // let path = ... + // Open the file whose path is a variable. + let fileFd = fileIO.openSync(path, 0o102, 0o666); + ``` + + 2. As described in the prerequisites, the sharing party starts an application selector and shares the data to the selector, and the selector transfers the data to the shared party. Want of the sharing party must be nested at two layers. At the first layer, implicit Want is used together with the **ohos.want.action.select** action to display the application selector. At the second layer, complete Want is declared in the custom field **parameters** to transfer the data to share. + + ```ts + import wantConstant from '@ohos.app.ability.wantConstant'; + + // let path = ... + // let fileFd = ... + // let fileSize = ... + let want = { + / This action is used to implicitly match the application selector. + action: wantConstant.Action.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": "application/pdf", + "ability.picker.fileNames": [path], + "ability.picker.fileSizes": [fileSize], + // This 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} + } + } + } + } + ``` + + In the preceding code, the custom field **parameters** is used. The **ability.picker.\*** fields in the first-layer **parameters** are used to pass the information to be displayed on the application selector. The following fields are involved: + + - **"ability.picker.type"**: The application selector renders the file type icon based on this field. + - **"ability.picker.fileNames"**: The application selector displays the file name based on this field. + - **"ability.picker.fileSizes"**: The application selector displays the file size based on this field. The unit is byte. + - **"ability.picker.fileNames"** and **"ability.picker.fileSizes"** are arrays and have a one-to-one mapping. + + For example, when **"ability.picker.type"** is **"application/pdf"**, **"ability.picker.fileNames"** is **"["APIs.pdf"]"**, and **"ability.picker.fileSizes"** is **"[350 \* 1024]"**, the application selector is displayed as follows: + + stage-want2 + + In the preceding code, the **ability.want.params.INTENT** field is nested Want. In this field, **action** and **type** are used for implicit matching by the application selector. For details about implicit matching, see [Implicit Want Matching Rules](explicit-implicit-want-mappings.md#interpretation-of-implicit-want-matching-rules). After the user selects an application, the nested Want of the **ability.want.params.INTENT** field is passed to that application. + +- Shared party + 1. As mentioned above, the application selector performs implicit matching based on the **ability.want.params.INTENT** field. Therefore, you must set **skills** in the ability configuration file (**module.json5** file in the stage model) of the shared party as follows: + + ```ts + "skills": [ + { + "entities": [ + // ... + ], + "actions": [ + "ohos.want.action.sendData" + // ... + ], + "uris": [ + { + "type": "application/pdf" + }, + // ... + ] + }, + ] + ``` + + The **actions** and **type** fields in **uris** match the **action** and **type** fields in **ability.want.params.INTENT**, respectively. + + Files can be transferred in FD mode, but not URI mode. In implicit matching, the **type** field in Want must match the **type** field in **uris** under **skills** of the shared party. Therefore, specify only the **type** field in **uris**. If **host** and **port** are specified, the matching fails. The application selector initiates implicit matching based on **ability.want.params.INTENT**. Therefore, when the **uri** field added to **ability.want.params.INTENT** matches the **uris** field under **skills**, the matching is successful and additional data can be transferred. + 2. After the application selector starts the shared party, the system calls **onCreate** and passes **ability.want.params.INTENT** to the **want** parameter. + + ```ts + onCreate(want, launchParam) { + // When keyFd is undefined, the application crashes. + if (want["parameters"]["keyFd"] !== undefined) { + // Receive the file descriptor. + let fd = want["parameters"]["keyFd"].value; + // ... + } + } + ``` diff --git a/en/application-dev/application-models/dataability-configuration.md b/en/application-dev/application-models/dataability-configuration.md new file mode 100644 index 0000000000000000000000000000000000000000..d3618ea7a026311004524a9eb79ff3d1951d6a93 --- /dev/null +++ b/en/application-dev/application-models/dataability-configuration.md @@ -0,0 +1,62 @@ +# 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). + + \ No newline at end of file diff --git a/en/application-dev/application-models/dataability-lifecycle.md b/en/application-dev/application-models/dataability-lifecycle.md new file mode 100644 index 0000000000000000000000000000000000000000..f35f46ffd9504a29897694054efc15f9a8465a57 --- /dev/null +++ b/en/application-dev/application-models/dataability-lifecycle.md @@ -0,0 +1,23 @@ +# 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<number>): void | Updates data in the database.| +| query?(uri: string, columns: Array<string>, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback<ResultSet>): void | Queries data in the database.| +| delete?(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback<number>): void | Deletes one or more data records from the database.| +| normalizeUri?(uri: string, callback: AsyncCallback<string>): 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<rdb.ValuesBucket>, callback: AsyncCallback<number>): void | Inserts multiple data records into the database.| +| denormalizeUri?(uri: string, callback: AsyncCallback<string>): void | Converts a normalized URI generated by **normalizeUri** into a denormalized URI.| +| insert?(uri: string, valueBucket: rdb.ValuesBucket, callback: AsyncCallback<number>): void | Inserts a data record into the database.| +| openFile?(uri: string, mode: string, callback: AsyncCallback<number>): void | Opens a file.| +| getFileTypes?(uri: string, mimeTypeFilter: string, callback: AsyncCallback<Array<string>>): void | Obtains the MIME type of a file.| +| getType?(uri: string, callback: AsyncCallback<string>): void | Obtains the MIME type matching the data specified by the URI.| +| executeBatch?(ops: Array<DataAbilityOperation>, callback: AsyncCallback<Array<DataAbilityResult>>): void | Operates data in the database in batches.| +| call?(method: string, arg: string, extras: PacMap, callback: AsyncCallback<PacMap>): void | Calls a custom API.| diff --git a/en/application-dev/application-models/dataability-overview.md b/en/application-dev/application-models/dataability-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..b89ee68bb5fe6cda341dea332a24cf1010c4935f --- /dev/null +++ b/en/application-dev/application-models/dataability-overview.md @@ -0,0 +1,10 @@ +# 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. diff --git a/en/application-dev/application-models/dataability-permission-control.md b/en/application-dev/application-models/dataability-permission-control.md new file mode 100644 index 0000000000000000000000000000000000000000..25c5e82726dbc3a7dba8158a0847b5c59ea0c98e --- /dev/null +++ b/en/application-dev/application-models/dataability-permission-control.md @@ -0,0 +1,60 @@ +# 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. diff --git a/en/application-dev/application-models/dataability-switch.md b/en/application-dev/application-models/dataability-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..b91d50ca37a97fdc1d4824a93a6093bac7cd0f77 --- /dev/null +++ b/en/application-dev/application-models/dataability-switch.md @@ -0,0 +1,44 @@ +# 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<void>): void
| 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<number>): void | update?(uri: string, predicates: dataSharePredicates.DataSharePredicates, value: ValuesBucket, callback: AsyncCallback<number>): 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<string>, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback<ResultSet>): void | query?(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array<string>, callback: AsyncCallback<Object>): 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<number>): void | delete?(uri: string, predicates: dataSharePredicates.DataSharePredicates, callback: AsyncCallback<number>):| 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<string>): void | normalizeUri?(uri: string, callback: AsyncCallback<string>): void| The two methods have the same meaning, invoking time, and parameters.| + | batchInsert?(uri: string, valueBuckets: Array<rdb.ValuesBucket>, callback: AsyncCallback<number>): void | batchInsert?(uri: string, values: Array<ValuesBucket>, callback: AsyncCallback<number>): 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<string>): void | denormalizeUri?(uri: string, callback: AsyncCallback<string>): void | The two methods have the same meaning, invoking time, and parameters.| + | insert?(uri: string, valueBucket: rdb.ValuesBucket, callback: AsyncCallback<number>): void | insert?(uri: string, value: ValuesBucket, callback: AsyncCallback<number>): 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<number>): 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<Array<string>>): 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<string>): 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<DataAbilityOperation>, callback: AsyncCallback<Array<DataAbilityResult>>): 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<PacMap>): 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.| diff --git a/en/application-dev/application-models/dataabilityhelper-switch.md b/en/application-dev/application-models/dataabilityhelper-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..c709e30ae9c25bcbd47f781e1f43a51100960998 --- /dev/null +++ b/en/application-dev/application-models/dataabilityhelper-switch.md @@ -0,0 +1,20 @@ +# 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<number>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperopenfile)
[openFile(uri: string, mode: string): Promise<number>;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperopenfile-1) | \@ohos.data.fileAccess.d.ts | [openFile(uri: string, flags: OPENFLAGS) : Promise<number>;](../reference/apis/js-apis-fileAccess.md#fileaccesshelperopenfile)
[openFile(uri: string, flags: OPENFLAGS, callback: AsyncCallback<number>) : void;](../reference/apis/js-apis-fileAccess.md#fileaccesshelperopenfile) | +| [on(type: 'dataChange', uri: string, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperon) | \@ohos.data.dataShare.d.ts | [on(type: 'dataChange', uri: string, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-data-dataShare.md#ondatachange) | +| [off(type: 'dataChange', uri: string, callback?: AsyncCallback<void>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperoff) | \@ohos.data.dataShare.d.ts | [off(type: 'dataChange', uri: string, callback?: AsyncCallback<void>): void;](../reference/apis/js-apis-data-dataShare.md#offdatachange) | +| [getType(uri: string, callback: AsyncCallback<string>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpergettype)
[getType(uri: string): Promise<string>;](../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<Array<string>>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpergetfiletypes)
[getFileTypes(uri: string, mimeTypeFilter: string): Promise<Array<string>>;](../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<string>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpernormalizeuri)
[normalizeUri(uri: string): Promise<string>;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpernormalizeuri-1) | \@ohos.data.dataShare.d.ts | [normalizeUri(uri: string, callback: AsyncCallback<string>): void;](../reference/apis/js-apis-data-dataShare.md#normalizeuri)
[normalizeUri(uri: string): Promise<string>;](../reference/apis/js-apis-data-dataShare.md#normalizeuri-1) | +| [denormalizeUri(uri: string, callback: AsyncCallback<string>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperdenormalizeuri)
[denormalizeUri(uri: string): Promise<string>;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperdenormalizeuri-1) | \@ohos.data.dataShare.d.ts | [denormalizeUri(uri: string, callback: AsyncCallback<string>): void;](../reference/apis/js-apis-data-dataShare.md#denormalizeuri)
[denormalizeUri(uri: string): Promise<string>;](../reference/apis/js-apis-data-dataShare.md#denormalizeuri-1) | +| [notifyChange(uri: string, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpernotifychange)
[notifyChange(uri: string): Promise<void>;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpernotifychange-1) | \@ohos.data.dataShare.d.ts | [notifyChange(uri: string, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-data-dataShare.md#notifychange)
[notifyChange(uri: string): Promise<void>;](../reference/apis/js-apis-data-dataShare.md#notifychange-1) | +| [insert(uri: string, valuesBucket: rdb.ValuesBucket, callback: AsyncCallback<number>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperinsert)
[insert(uri: string, valuesBucket: rdb.ValuesBucket): Promise<number>;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperinsert-1) | \@ohos.data.dataShare.d.ts | [insert(uri: string, value: ValuesBucket, callback: AsyncCallback<number>): void;](../reference/apis/js-apis-data-dataShare.md#insert)
[insert(uri: string, value: ValuesBucket): Promise<number>;](../reference/apis/js-apis-data-dataShare.md#insert-1) | +| [batchInsert(uri: string, valuesBuckets: Array<rdb.ValuesBucket>, callback: AsyncCallback<number>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperbatchinsert)
[batchInsert(uri: string, valuesBuckets: Array<rdb.ValuesBucket>): Promise<number>;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperbatchinsert-1) | \@ohos.data.dataShare.d.ts | [batchInsert(uri: string, values: Array<ValuesBucket>, callback: AsyncCallback<number>): void;](../reference/apis/js-apis-data-dataShare.md#batchinsert)
[batchInsert(uri: string, values: Array<ValuesBucket>): Promise<number>;](../reference/apis/js-apis-data-dataShare.md#batchinsert-1) | +| [delete(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback<number>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperdelete)
[delete(uri: string, predicates?: dataAbility.DataAbilityPredicates): Promise<number>;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperdelete-1)
[delete(uri: string, callback: AsyncCallback<number>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperdelete) | \@ohos.data.dataShare.d.ts | [delete(uri: string, predicates: dataSharePredicates.DataSharePredicates, callback: AsyncCallback<number>): void;](../reference/apis/js-apis-data-dataShare.md#delete)
[delete(uri: string, predicates: dataSharePredicates.DataSharePredicates): Promise<number>;](../reference/apis/js-apis-data-dataShare.md#delete-1) | +| [update(uri: string, valuesBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback<number>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperupdate)
[update(uri: string, valuesBucket: rdb.ValuesBucket, predicates?: dataAbility.DataAbilityPredicates): Promise<number>;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperupdate-1)
[update(uri: string, valuesBucket: rdb.ValuesBucket, callback: AsyncCallback<number>): 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<number>): void;](../reference/apis/js-apis-data-dataShare.md#update)
[update(uri: string, predicates: dataSharePredicates.DataSharePredicates, value: ValuesBucket): Promise<number>;](../reference/apis/js-apis-data-dataShare.md#update-1) | +| [query(uri: string, columns: Array<string>, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback<ResultSet>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperquery)
[query(uri: string, callback: AsyncCallback<ResultSet>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperquery)
[query(uri: string, columns: Array<string>, callback: AsyncCallback<ResultSet>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperquery)
[query(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback<ResultSet>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperquery)
[query(uri: string, columns?: Array<string>, predicates?: dataAbility.DataAbilityPredicates): Promise<ResultSet>;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperquery-1) | \@ohos.data.dataShare.d.ts | [query(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array<string>, callback: AsyncCallback<DataShareResultSet>): void;](../reference/apis/js-apis-data-dataShare.md#query)
[query(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array<string>): Promise<DataShareResultSet>;](../reference/apis/js-apis-data-dataShare.md#query-1) | +| [call(uri: string, method: string, arg: string, extras: PacMap, callback: AsyncCallback<PacMap>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelpercall-1)
[call(uri: string, method: string, arg: string, extras: PacMap): Promise<PacMap>;](../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<DataAbilityOperation>, callback: AsyncCallback<Array<DataAbilityResult>>): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperexecutebatch)
[executeBatch(uri: string, operations: Array<DataAbilityOperation>): Promise<Array<DataAbilityResult>>;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperexecutebatch-1) | There is no corresponding API in the stage model.| No corresponding API is provided.| diff --git a/en/application-dev/application-models/datashareextensionability.md b/en/application-dev/application-models/datashareextensionability.md new file mode 100644 index 0000000000000000000000000000000000000000..5b07ba68180fbcc2a51047d37ca9a82addd89cd8 --- /dev/null +++ b/en/application-dev/application-models/datashareextensionability.md @@ -0,0 +1,4 @@ +# DataShareExtensionAbility + + +DataShareExtensionAbility is available only for system application. It 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). diff --git a/en/application-dev/application-models/explicit-implicit-want-mappings.md b/en/application-dev/application-models/explicit-implicit-want-mappings.md new file mode 100644 index 0000000000000000000000000000000000000000..99aa45c9f8f387e5717a90478a0a24d2be60f463 --- /dev/null +++ b/en/application-dev/application-models/explicit-implicit-want-mappings.md @@ -0,0 +1,162 @@ +# 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** + + | 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<string> | 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: string]: 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** + | 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.
- When both **bundleName** and **moduleName** are specified, matching is limited to that module in that application.
- When only **moduleName** is specified, the setting is invalid.
For details, see [Interpretation of Implicit Want Matching Rules](#interpretation-of-implicit-want-matching-rules). | + | moduleName | string | Yes| No|| + | uri | string | Yes| No|| + | type | string | Yes| No|| + | action | string | Yes| No|| + | entities | Array<string> | 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: string]: any} | No| No| This field is not used for matching. It is passed to the target ability as a parameter.| + + +## Interpretation of Implicit Want Matching Rules + + +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-tag) 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](../reference/apis/js-apis-ability-wantConstant.md#wantconstantaction) 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 + + +### Matching Rules of entities in the want Parameter + +The system matches the [entities](../reference/apis/js-apis-ability-wantConstant.md#wantconstantentity) 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 + + +### 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 + +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 + + +### 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/`. + + \ No newline at end of file diff --git a/en/application-dev/application-models/extensionability-overview.md b/en/application-dev/application-models/extensionability-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..d85f02ace879e409a8d42d6f09408680a99f8056 --- /dev/null +++ b/en/application-dev/application-models/extensionability-overview.md @@ -0,0 +1,58 @@ +# 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-resourceschedule-workScheduler.md): ExtensionAbility component of the work_scheduler type, which provides APIs for registering, canceling, and querying 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 system applications to display UIs of other applications. + +- [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. diff --git a/en/application-dev/application-models/fa-model-development-overview.md b/en/application-dev/application-models/fa-model-development-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..07e7ef8a0bdaea927762c15e4123ae728c026cb7 --- /dev/null +++ b/en/application-dev/application-models/fa-model-development-overview.md @@ -0,0 +1,15 @@ +# 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)
- [PageAbility Component](pageability-overview.md)
- [ServiceAbility Component](serviceability-overview.md)
- [DataAbility Component](dataability-overview.md)
- [Widget Development](Widget-development-fa.md)
- [Context](application-context-fa.md)
- [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)
[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) | diff --git a/en/application-dev/application-models/fa-stage-interaction-overview.md b/en/application-dev/application-models/fa-stage-interaction-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..0d1ed27f0df2d4964b0d69faf48afcb42e32bf91 --- /dev/null +++ b/en/application-dev/application-models/fa-stage-interaction-overview.md @@ -0,0 +1,25 @@ +# 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.| diff --git a/en/application-dev/application-models/featureability-switch.md b/en/application-dev/application-models/featureability-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..f7db8056ea156650e11b55a78137de194ce9d43f --- /dev/null +++ b/en/application-dev/application-models/featureability-switch.md @@ -0,0 +1,16 @@ +# featureAbility Switching + + +| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| +| -------- | -------- | -------- | +| [getWant(callback: AsyncCallback<Want>): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitygetwant)
[getWant(): Promise<Want>;](../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<number>): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartability)
[startAbility(parameter: StartAbilityParameter): Promise<number>;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartability-1) | application\UIAbilityContext.d.ts | [startAbility(want: Want, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartability)
[startAbility(want: Want, options: StartOptions, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartability-1)
[startAbility(want: Want, options?: StartOptions): Promise<void>;](../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<AbilityResult>): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartabilityforresult7)
[startAbilityForResult(parameter: StartAbilityParameter): Promise<AbilityResult>;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartabilityforresult7-1) | application\UIAbilityContext.d.ts | [startAbilityForResult(want: Want, callback: AsyncCallback<AbilityResult>): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilityforresult)
[startAbilityForResult(want: Want, options: StartOptions, callback: AsyncCallback<AbilityResult>): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilityforresult-1)
[startAbilityForResult(want: Want, options?: StartOptions): Promise<AbilityResult>;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilityforresult-2) | +| [terminateSelfWithResult(parameter: AbilityResult, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilityterminateselfwithresult7)
[terminateSelfWithResult(parameter: AbilityResult): Promise<void>;](../reference/apis/js-apis-ability-featureAbility.md#featureabilityterminateselfwithresult7-1) | application\UIAbilityContext.d.ts | [terminateSelfWithResult(parameter: AbilityResult, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextterminateselfwithresult)
[terminateSelfWithResult(parameter: AbilityResult): Promise<void>;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextterminateselfwithresult-1) | +| [terminateSelf(callback: AsyncCallback<void>): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilityterminateself7)
[terminateSelf(): Promise<void>;](../reference/apis/js-apis-ability-featureAbility.md#featureabilityterminateself7-1) | application\UIAbilityContext.d.ts | [terminateSelf(callback: AsyncCallback<void>): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextterminateself)
[terminateSelf(): Promise<void>;](../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
\@ohos.data.fileAccess.d.ts | [createDataShareHelper(context: Context, uri: string, callback: AsyncCallback<DataShareHelper>): void;](../reference/apis/js-apis-data-dataShare.md#datasharecreatedatasharehelper)
[createDataShareHelper(context: Context, uri: string): Promise<DataShareHelper>;](../reference/apis/js-apis-data-dataShare.md#datasharecreatedatasharehelper-1)
[createFileAccessHelper(context: Context): FileAccessHelper;](../reference/apis/js-apis-fileAccess.md#fileaccesscreatefileaccesshelper-1)
[createFileAccessHelper(context: Context, wants: Array<Want>): FileAccessHelper;](../reference/apis/js-apis-fileAccess.md#fileaccesscreatefileaccesshelper) | +| [hasWindowFocus(callback: AsyncCallback<boolean>): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilityhaswindowfocus7)
[hasWindowFocus(): Promise<boolean>;](../reference/apis/js-apis-ability-featureAbility.md#featureabilityhaswindowfocus7-1) | \@ohos.window.d.ts | [on(eventType: 'windowStageEvent', callback: Callback<WindowStageEventType>): void;](../reference/apis/js-apis-window.md#onwindowstageevent9)
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<void>): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitydisconnectability7)
[disconnectAbility(connection: number): Promise<void>;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitydisconnectability7-1) | application\UIAbilityContext.d.ts | [disconnectAbility(connection: number, callback:AsyncCallback<void>): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextdisconnectserviceextensionability-1)
[disconnectAbility(connection: number): Promise<void>;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextdisconnectserviceextensionability) | +| [getWindow(callback: AsyncCallback<window.Window>): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitygetwindow7)
[getWindow(): Promise<window.Window>;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitygetwindow7-1) | \@ohos.window.d.ts | [getLastWindow(ctx: BaseContext, callback: AsyncCallback<Window>): void;](../reference/apis/js-apis-window.md#windowgetlastwindow9)
[getLastWindow(ctx: BaseContext): Promise<Window>;](../reference/apis/js-apis-window.md#windowgetlastwindow9-1) | diff --git a/en/application-dev/application-models/figures/Ability-Life-Cycle-WindowStage.png b/en/application-dev/application-models/figures/Ability-Life-Cycle-WindowStage.png new file mode 100644 index 0000000000000000000000000000000000000000..e140763dfda32a5ad168e8a6daa38a9c51baf147 Binary files /dev/null and b/en/application-dev/application-models/figures/Ability-Life-Cycle-WindowStage.png differ diff --git a/en/application-dev/application-models/figures/Ability-Life-Cycle.png b/en/application-dev/application-models/figures/Ability-Life-Cycle.png new file mode 100644 index 0000000000000000000000000000000000000000..cc0681f5f2678ca15008d7b98d7ddc34d20dcf83 Binary files /dev/null and b/en/application-dev/application-models/figures/Ability-Life-Cycle.png differ diff --git a/en/application-dev/application-models/figures/ExtensionAbility-start.png b/en/application-dev/application-models/figures/ExtensionAbility-start.png new file mode 100644 index 0000000000000000000000000000000000000000..3bd844f462199d5b7792cc5229fa763eb851a2d3 Binary files /dev/null and b/en/application-dev/application-models/figures/ExtensionAbility-start.png differ diff --git a/en/application-dev/application-models/figures/FAvsStage-uri.png b/en/application-dev/application-models/figures/FAvsStage-uri.png new file mode 100644 index 0000000000000000000000000000000000000000..132c1ba0f09f7da7344d6edcfae3c59fe355e7f9 Binary files /dev/null and b/en/application-dev/application-models/figures/FAvsStage-uri.png differ diff --git a/en/application-dev/application-models/figures/ServiceExtensionAbility-lifecycle.png b/en/application-dev/application-models/figures/ServiceExtensionAbility-lifecycle.png new file mode 100644 index 0000000000000000000000000000000000000000..fd3a15c8b1588e19d88938b39dbbc12b98d3c723 Binary files /dev/null and b/en/application-dev/application-models/figures/ServiceExtensionAbility-lifecycle.png differ diff --git a/en/application-dev/application-models/figures/api-switch-overview.png b/en/application-dev/application-models/figures/api-switch-overview.png new file mode 100644 index 0000000000000000000000000000000000000000..c17f5d3deb13d9c2d31d1b1d8b8569c7bc842676 Binary files /dev/null and b/en/application-dev/application-models/figures/api-switch-overview.png differ diff --git a/en/application-dev/application-models/figures/application-component-configuration-stage.png b/en/application-dev/application-models/figures/application-component-configuration-stage.png new file mode 100644 index 0000000000000000000000000000000000000000..8957b1b4a85a7bdc8d0d9ab422d7cf379ae6cf75 Binary files /dev/null and b/en/application-dev/application-models/figures/application-component-configuration-stage.png differ diff --git a/en/application-dev/application-models/figures/application-context-stage.png b/en/application-dev/application-models/figures/application-context-stage.png new file mode 100644 index 0000000000000000000000000000000000000000..9423fd5f99deb310315c13173422cb050d93fbb7 Binary files /dev/null and b/en/application-dev/application-models/figures/application-context-stage.png differ diff --git a/en/application-dev/application-models/figures/call.png b/en/application-dev/application-models/figures/call.png new file mode 100644 index 0000000000000000000000000000000000000000..5a374f942e7754fa7b4e9303c89ee53d4ff8ee2b Binary files /dev/null and b/en/application-dev/application-models/figures/call.png differ diff --git a/en/application-dev/application-models/figures/coexistence-of-FAandStage.png b/en/application-dev/application-models/figures/coexistence-of-FAandStage.png new file mode 100644 index 0000000000000000000000000000000000000000..02e09b48b3f146371ddb6acac7e4a259be4448fb Binary files /dev/null and b/en/application-dev/application-models/figures/coexistence-of-FAandStage.png differ diff --git a/en/application-dev/application-models/figures/common-event.png b/en/application-dev/application-models/figures/common-event.png new file mode 100644 index 0000000000000000000000000000000000000000..24b51ff8718ae504ba69c1e12656d4daad797a62 Binary files /dev/null and b/en/application-dev/application-models/figures/common-event.png differ diff --git a/en/application-dev/application-models/figures/comparison-of-configuration-file.png b/en/application-dev/application-models/figures/comparison-of-configuration-file.png new file mode 100644 index 0000000000000000000000000000000000000000..e0a2b47835f7814511049807f8582c50057bb459 Binary files /dev/null and b/en/application-dev/application-models/figures/comparison-of-configuration-file.png differ diff --git a/en/application-dev/application-models/figures/component-startup-inner-fa.png b/en/application-dev/application-models/figures/component-startup-inner-fa.png new file mode 100644 index 0000000000000000000000000000000000000000..f6ed21c09d9ae0d409a180885c172918a123c728 Binary files /dev/null and b/en/application-dev/application-models/figures/component-startup-inner-fa.png differ diff --git a/en/application-dev/application-models/figures/component-startup-inner-stage.png b/en/application-dev/application-models/figures/component-startup-inner-stage.png new file mode 100644 index 0000000000000000000000000000000000000000..00514276f4ac3eb8ead650e5858cebb0a344d2c6 Binary files /dev/null and b/en/application-dev/application-models/figures/component-startup-inner-stage.png differ diff --git a/en/application-dev/application-models/figures/component-startup-inter-fa.png b/en/application-dev/application-models/figures/component-startup-inter-fa.png new file mode 100644 index 0000000000000000000000000000000000000000..2d50fb61e502ae2d2af917931d579ca2404d19b0 Binary files /dev/null and b/en/application-dev/application-models/figures/component-startup-inter-fa.png differ diff --git a/en/application-dev/application-models/figures/component-startup-inter-stage.png b/en/application-dev/application-models/figures/component-startup-inter-stage.png new file mode 100644 index 0000000000000000000000000000000000000000..a6f79e6803edc160e5570729456569f46cc80967 Binary files /dev/null and b/en/application-dev/application-models/figures/component-startup-inter-stage.png differ diff --git a/en/application-dev/application-models/figures/context-dir.png b/en/application-dev/application-models/figures/context-dir.png new file mode 100644 index 0000000000000000000000000000000000000000..f16b56b43fbd0f493a10acecfb9b1edb79b2421f Binary files /dev/null and b/en/application-dev/application-models/figures/context-dir.png differ diff --git a/en/application-dev/application-models/figures/context-holding.png b/en/application-dev/application-models/figures/context-holding.png new file mode 100644 index 0000000000000000000000000000000000000000..fe4fbd4a4dff7024e3d5d35bd46d304d23e1f8c9 Binary files /dev/null and b/en/application-dev/application-models/figures/context-holding.png differ diff --git a/en/application-dev/application-models/figures/context-inheritance.png b/en/application-dev/application-models/figures/context-inheritance.png new file mode 100644 index 0000000000000000000000000000000000000000..2619daca03187d58db5b3690734704c66fb70d06 Binary files /dev/null and b/en/application-dev/application-models/figures/context-inheritance.png differ diff --git a/en/application-dev/application-models/figures/fa-dataability-uri.png b/en/application-dev/application-models/figures/fa-dataability-uri.png new file mode 100644 index 0000000000000000000000000000000000000000..d89ada0ee9b2f9f655a6c3d8b0df17d6b1ca9326 Binary files /dev/null and b/en/application-dev/application-models/figures/fa-dataability-uri.png differ diff --git a/en/application-dev/application-models/figures/fa-pageAbility-lifecycle.png b/en/application-dev/application-models/figures/fa-pageAbility-lifecycle.png new file mode 100644 index 0000000000000000000000000000000000000000..59a06741053c85cab6ea90b41bd16a6f2e1ff508 Binary files /dev/null and b/en/application-dev/application-models/figures/fa-pageAbility-lifecycle.png differ diff --git a/en/application-dev/application-models/figures/form-extension.png b/en/application-dev/application-models/figures/form-extension.png new file mode 100644 index 0000000000000000000000000000000000000000..ce47308856c4d41baff5dbaefdcefe9561b383b7 Binary files /dev/null and b/en/application-dev/application-models/figures/form-extension.png differ diff --git a/en/application-dev/application-models/figures/form_extension.png b/en/application-dev/application-models/figures/form_extension.png new file mode 100644 index 0000000000000000000000000000000000000000..daf36c75dae010492fa57ac05c85eaed58fbe00c Binary files /dev/null and b/en/application-dev/application-models/figures/form_extension.png differ diff --git a/en/application-dev/application-models/figures/globalThis1.png b/en/application-dev/application-models/figures/globalThis1.png new file mode 100644 index 0000000000000000000000000000000000000000..128f79d3437304845ac822d32377dab4cf0c9e05 Binary files /dev/null and b/en/application-dev/application-models/figures/globalThis1.png differ diff --git a/en/application-dev/application-models/figures/globalThis2.png b/en/application-dev/application-models/figures/globalThis2.png new file mode 100644 index 0000000000000000000000000000000000000000..11e015286489df52d5b9cd3ed35a564223b7ab4c Binary files /dev/null and b/en/application-dev/application-models/figures/globalThis2.png differ diff --git a/en/application-dev/application-models/figures/hop-cross-device-migration.png b/en/application-dev/application-models/figures/hop-cross-device-migration.png new file mode 100644 index 0000000000000000000000000000000000000000..1623bc94af414539f6634aea6d583e205eccf409 Binary files /dev/null and b/en/application-dev/application-models/figures/hop-cross-device-migration.png differ diff --git a/en/application-dev/application-models/figures/hop-multi-device-collaboration.png b/en/application-dev/application-models/figures/hop-multi-device-collaboration.png new file mode 100644 index 0000000000000000000000000000000000000000..28fa0a6e269a4266236898e19ce7bca4e670027d Binary files /dev/null and b/en/application-dev/application-models/figures/hop-multi-device-collaboration.png differ diff --git a/en/application-dev/application-models/figures/hop-structure.png b/en/application-dev/application-models/figures/hop-structure.png new file mode 100644 index 0000000000000000000000000000000000000000..96b82de856fcbc7db6d7668791a668ec152141fc Binary files /dev/null and b/en/application-dev/application-models/figures/hop-structure.png differ diff --git a/en/application-dev/application-models/figures/mission-and-singleton.png b/en/application-dev/application-models/figures/mission-and-singleton.png new file mode 100644 index 0000000000000000000000000000000000000000..eee0a39644d7080e9f9f26f30b184d679a5bff3c Binary files /dev/null and b/en/application-dev/application-models/figures/mission-and-singleton.png differ diff --git a/en/application-dev/application-models/figures/mission-and-specified.png b/en/application-dev/application-models/figures/mission-and-specified.png new file mode 100644 index 0000000000000000000000000000000000000000..6af8c28d4277b3582fed2cfc313cc301086e6314 Binary files /dev/null and b/en/application-dev/application-models/figures/mission-and-specified.png differ diff --git a/en/application-dev/application-models/figures/mission-and-standard.png b/en/application-dev/application-models/figures/mission-and-standard.png new file mode 100644 index 0000000000000000000000000000000000000000..feeed48f41371bf22abbee8dbae4695b11ed2514 Binary files /dev/null and b/en/application-dev/application-models/figures/mission-and-standard.png differ diff --git a/en/application-dev/application-models/figures/mission-chain1.png b/en/application-dev/application-models/figures/mission-chain1.png new file mode 100644 index 0000000000000000000000000000000000000000..6b9ce7dd3c74b26e0dd8d1b12e00d6414e3cdadb Binary files /dev/null and b/en/application-dev/application-models/figures/mission-chain1.png differ diff --git a/en/application-dev/application-models/figures/mission-chain2.png b/en/application-dev/application-models/figures/mission-chain2.png new file mode 100644 index 0000000000000000000000000000000000000000..7ed2b6f0052a08445c53ec2882a7f474fa5a4763 Binary files /dev/null and b/en/application-dev/application-models/figures/mission-chain2.png differ diff --git a/en/application-dev/application-models/figures/mission-chain3.png b/en/application-dev/application-models/figures/mission-chain3.png new file mode 100644 index 0000000000000000000000000000000000000000..e02c135ad4a90f99bb65bdccd821d29990b9536e Binary files /dev/null and b/en/application-dev/application-models/figures/mission-chain3.png differ diff --git a/en/application-dev/application-models/figures/mission-list-manager.png b/en/application-dev/application-models/figures/mission-list-manager.png new file mode 100644 index 0000000000000000000000000000000000000000..792745f100e6ba3613c3a496421b00bbb5f6db8f Binary files /dev/null and b/en/application-dev/application-models/figures/mission-list-manager.png differ diff --git a/en/application-dev/application-models/figures/mission-record.png b/en/application-dev/application-models/figures/mission-record.png new file mode 100644 index 0000000000000000000000000000000000000000..77f9c156d83876524977a139308046a6acfed711 Binary files /dev/null and b/en/application-dev/application-models/figures/mission-record.png differ diff --git a/en/application-dev/application-models/figures/model-switch-overview1.png b/en/application-dev/application-models/figures/model-switch-overview1.png new file mode 100644 index 0000000000000000000000000000000000000000..e9d8a120dedcda4f27f5f92e52c826b900a105d9 Binary files /dev/null and b/en/application-dev/application-models/figures/model-switch-overview1.png differ diff --git a/en/application-dev/application-models/figures/model-switch-overview2.png b/en/application-dev/application-models/figures/model-switch-overview2.png new file mode 100644 index 0000000000000000000000000000000000000000..522656745c55d165208be94b23d264c334421722 Binary files /dev/null and b/en/application-dev/application-models/figures/model-switch-overview2.png differ diff --git a/en/application-dev/application-models/figures/model-switch-overview3.png b/en/application-dev/application-models/figures/model-switch-overview3.png new file mode 100644 index 0000000000000000000000000000000000000000..e7fe19489d38bf971619dbb41294c5287377b8dc Binary files /dev/null and b/en/application-dev/application-models/figures/model-switch-overview3.png differ diff --git a/en/application-dev/application-models/figures/model-switch-overview4.png b/en/application-dev/application-models/figures/model-switch-overview4.png new file mode 100644 index 0000000000000000000000000000000000000000..e455ae9333e73b0898d6dd1700e79cbe529b7163 Binary files /dev/null and b/en/application-dev/application-models/figures/model-switch-overview4.png differ diff --git a/en/application-dev/application-models/figures/model-switch-overview5.png b/en/application-dev/application-models/figures/model-switch-overview5.png new file mode 100644 index 0000000000000000000000000000000000000000..82d5dbc6fee5b3b393e0a1abd8f4e7fbbeb0c4ac Binary files /dev/null and b/en/application-dev/application-models/figures/model-switch-overview5.png differ diff --git a/en/application-dev/application-models/figures/model-switch-overview6.png b/en/application-dev/application-models/figures/model-switch-overview6.png new file mode 100644 index 0000000000000000000000000000000000000000..c17f5d3deb13d9c2d31d1b1d8b8569c7bc842676 Binary files /dev/null and b/en/application-dev/application-models/figures/model-switch-overview6.png differ diff --git a/en/application-dev/application-models/figures/multi-process.png b/en/application-dev/application-models/figures/multi-process.png new file mode 100644 index 0000000000000000000000000000000000000000..55ab9a514c3fd1136747efc1bbb80ec900891bce Binary files /dev/null and b/en/application-dev/application-models/figures/multi-process.png differ diff --git a/en/application-dev/application-models/figures/page-ability-lifecycle.png b/en/application-dev/application-models/figures/page-ability-lifecycle.png new file mode 100644 index 0000000000000000000000000000000000000000..b35954967bb9c733725da2f0700481932619ae45 Binary files /dev/null and b/en/application-dev/application-models/figures/page-ability-lifecycle.png differ diff --git a/en/application-dev/application-models/figures/pageability-switch.png b/en/application-dev/application-models/figures/pageability-switch.png new file mode 100644 index 0000000000000000000000000000000000000000..4b68d46e529715a7258eb295bef1648da0b8ebbd Binary files /dev/null and b/en/application-dev/application-models/figures/pageability-switch.png differ diff --git a/en/application-dev/application-models/figures/process-model-fa.png b/en/application-dev/application-models/figures/process-model-fa.png new file mode 100644 index 0000000000000000000000000000000000000000..2a71de2389970a63d0a9dc2ec7d3c5b44e58a9ca Binary files /dev/null and b/en/application-dev/application-models/figures/process-model-fa.png differ diff --git a/en/application-dev/application-models/figures/process-model.png b/en/application-dev/application-models/figures/process-model.png new file mode 100644 index 0000000000000000000000000000000000000000..f6f3b22381539ac73371b4c7f6025a5c3127838b Binary files /dev/null and b/en/application-dev/application-models/figures/process-model.png differ diff --git a/en/application-dev/application-models/figures/stage-concepts.png b/en/application-dev/application-models/figures/stage-concepts.png new file mode 100644 index 0000000000000000000000000000000000000000..42e99447a780b167adaf6ddd196bea4437dfa1a7 Binary files /dev/null and b/en/application-dev/application-models/figures/stage-concepts.png differ diff --git a/en/application-dev/application-models/figures/stage-want1.png b/en/application-dev/application-models/figures/stage-want1.png new file mode 100644 index 0000000000000000000000000000000000000000..09ebc69170dca547c7b965dbf62c1a4df978815f Binary files /dev/null and b/en/application-dev/application-models/figures/stage-want1.png differ diff --git a/en/application-dev/application-models/figures/stage-want2.png b/en/application-dev/application-models/figures/stage-want2.png new file mode 100644 index 0000000000000000000000000000000000000000..3c5358cb3d98f8b519369f8ecce1964fd02c3d58 Binary files /dev/null and b/en/application-dev/application-models/figures/stage-want2.png differ diff --git a/en/application-dev/application-models/figures/standard-mode.png b/en/application-dev/application-models/figures/standard-mode.png new file mode 100644 index 0000000000000000000000000000000000000000..fc903e6c1be80d3c00281d00d9ab0a1e334d7724 Binary files /dev/null and b/en/application-dev/application-models/figures/standard-mode.png differ diff --git a/en/application-dev/application-models/figures/startAbilityWtExplicitWant.PNG b/en/application-dev/application-models/figures/startAbilityWtExplicitWant.PNG new file mode 100644 index 0000000000000000000000000000000000000000..1d9e25f148d08a58a0ac45b703e08072f52fc300 Binary files /dev/null and b/en/application-dev/application-models/figures/startAbilityWtExplicitWant.PNG differ diff --git a/en/application-dev/application-models/figures/thread-model-stage.png b/en/application-dev/application-models/figures/thread-model-stage.png new file mode 100644 index 0000000000000000000000000000000000000000..eb407a10616ce3eb1584f81ad80c4f29a7e95c10 Binary files /dev/null and b/en/application-dev/application-models/figures/thread-model-stage.png differ diff --git a/en/application-dev/application-models/figures/uiability-intra-device-interaction.png b/en/application-dev/application-models/figures/uiability-intra-device-interaction.png new file mode 100644 index 0000000000000000000000000000000000000000..59a0110cfc0b36780adb0a936af34588fcfdeb1a Binary files /dev/null and b/en/application-dev/application-models/figures/uiability-intra-device-interaction.png differ diff --git a/en/application-dev/application-models/figures/uiability-launch-type1.png b/en/application-dev/application-models/figures/uiability-launch-type1.png new file mode 100644 index 0000000000000000000000000000000000000000..c4f5aa4b9a988d8e7148b504c4dcc163961cb103 Binary files /dev/null and b/en/application-dev/application-models/figures/uiability-launch-type1.png differ diff --git a/en/application-dev/application-models/figures/uiability-launch-type2.png b/en/application-dev/application-models/figures/uiability-launch-type2.png new file mode 100644 index 0000000000000000000000000000000000000000..6f0e43d24f745aee41601cc48f4bc138572fbeb5 Binary files /dev/null and b/en/application-dev/application-models/figures/uiability-launch-type2.png differ diff --git a/en/application-dev/application-models/figures/uiability_not_first_started.png b/en/application-dev/application-models/figures/uiability_not_first_started.png new file mode 100644 index 0000000000000000000000000000000000000000..5cff262167ce720b736d6ea554f2355efa0c928e Binary files /dev/null and b/en/application-dev/application-models/figures/uiability_not_first_started.png differ diff --git a/en/application-dev/application-models/figures/usage-of-want.png b/en/application-dev/application-models/figures/usage-of-want.png new file mode 100644 index 0000000000000000000000000000000000000000..86b41b256ee8358c0fa87899b18ae249d28668c7 Binary files /dev/null and b/en/application-dev/application-models/figures/usage-of-want.png differ diff --git a/en/application-dev/application-models/figures/want-action.png b/en/application-dev/application-models/figures/want-action.png new file mode 100644 index 0000000000000000000000000000000000000000..0d8e18ce5870bea777c26b832d3f29674c2fa261 Binary files /dev/null and b/en/application-dev/application-models/figures/want-action.png differ diff --git a/en/application-dev/application-models/figures/want-entities.png b/en/application-dev/application-models/figures/want-entities.png new file mode 100644 index 0000000000000000000000000000000000000000..bf1b85594f1d34c966c061574f6bf6c3cb75bf2f Binary files /dev/null and b/en/application-dev/application-models/figures/want-entities.png differ diff --git a/en/application-dev/application-models/figures/want-uri-type1.png b/en/application-dev/application-models/figures/want-uri-type1.png new file mode 100644 index 0000000000000000000000000000000000000000..e0fe40d1a3cd40b72379bd947aaf2e3977021b32 Binary files /dev/null and b/en/application-dev/application-models/figures/want-uri-type1.png differ diff --git a/en/application-dev/application-models/figures/want-uri-type2.png b/en/application-dev/application-models/figures/want-uri-type2.png new file mode 100644 index 0000000000000000000000000000000000000000..9a64d865066e381536a268023918975e783ddf5e Binary files /dev/null and b/en/application-dev/application-models/figures/want-uri-type2.png differ diff --git a/en/application-dev/application-models/figures/widget-development-fa.png b/en/application-dev/application-models/figures/widget-development-fa.png new file mode 100644 index 0000000000000000000000000000000000000000..795e96171e6d890e72a09382906302dd0fa45fab Binary files /dev/null and b/en/application-dev/application-models/figures/widget-development-fa.png differ diff --git a/en/application-dev/application-models/figures/widget-development-stage.png b/en/application-dev/application-models/figures/widget-development-stage.png new file mode 100644 index 0000000000000000000000000000000000000000..795e96171e6d890e72a09382906302dd0fa45fab Binary files /dev/null and b/en/application-dev/application-models/figures/widget-development-stage.png differ diff --git a/en/application-dev/application-models/figures/widget-switch1.png b/en/application-dev/application-models/figures/widget-switch1.png new file mode 100644 index 0000000000000000000000000000000000000000..71aaf2e41cdf012820c121e5bf538b8c5b8b0784 Binary files /dev/null and b/en/application-dev/application-models/figures/widget-switch1.png differ diff --git a/en/application-dev/application-models/figures/widget-switch2.png b/en/application-dev/application-models/figures/widget-switch2.png new file mode 100644 index 0000000000000000000000000000000000000000..230836fd2c992de1d434e506bf48ff7876f1a5e8 Binary files /dev/null and b/en/application-dev/application-models/figures/widget-switch2.png differ diff --git a/en/application-dev/application-models/figures/widget-switch3.png b/en/application-dev/application-models/figures/widget-switch3.png new file mode 100644 index 0000000000000000000000000000000000000000..1e62fb7ca3be5fa73fb11d809d929b319ce05666 Binary files /dev/null and b/en/application-dev/application-models/figures/widget-switch3.png differ diff --git a/en/application-dev/application-models/figures/widget-switch4.png b/en/application-dev/application-models/figures/widget-switch4.png new file mode 100644 index 0000000000000000000000000000000000000000..65a63969a29dbf9c108618a9ea02db201ec3307d Binary files /dev/null and b/en/application-dev/application-models/figures/widget-switch4.png differ diff --git a/en/application-dev/application-models/hop-cross-device-migration.md b/en/application-dev/application-models/hop-cross-device-migration.md new file mode 100644 index 0000000000000000000000000000000000000000..6d30435a819da49855cf9ae818bac419a1c0b614 --- /dev/null +++ b/en/application-dev/application-models/hop-cross-device-migration.md @@ -0,0 +1,151 @@ +# Cross-Device Migration + + +## When to Use + +Cross-device migration is available only for system applications. The main task is to migrate the current task (including the page control status) of an application to the target device so that the task can continue on it. Cross-device migration supports the following functionalities: + +- Storage and restoration of custom data + +- Storage and restoration of page routing information and page control status data + +- Application compatibility detection + + +## Cross-Device Migration Process + +The following figure shows the cross-device migration process. + +**Figure 1** Cross-device migration process +![hop-cross-device-migration](figures/hop-cross-device-migration.png) + + +## Constraints + +- Since cross-device migration task management is not available, you can only develop applications that support cross-device migration. Your application cannot initiate migration. + +- Cross-device migration can be performed between the same UIAbility component. In other words, the components must have the same **bundleName**, **abilityName**, and **signature**. + + +## Best Practices + +For better user experience, you are advised to use the **wantParam** parameter to transmit data smaller than 100 KB. + + +## Available APIs + +The table below describes the main APIs used for cross-device migration. For details, see [API Reference](../reference/apis/js-apis-app-ability-uiAbility.md). + +**Table 1** Cross-device migration APIs + +| **API**| Description| +| -------- | -------- | +| onContinue(wantParam : {[key: string]: any}): OnContinueResult | Called by the initiator to store the data required for migration and indicate whether the migration is accepted.
- **AGREE**: The migration is accepted.
- **REJECT**: The migration is rejected.
- **MISMATCH**: The version does not match.| +| onCreate(want: Want, param: AbilityConstant.LaunchParam): void; | Called by the target to restore the data and UI page in the multi-instance migration scenario.| +| onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; | Called by the target to restore the data and UI page in the singleton migration scenario.| + + +## How to Develop + +1. Configure the data synchronization permission in the **module.json5** file. The sample code is as follows: + + ```json + { + "module": { + "requestPermissions":[ + { + "name" : "ohos.permission.DISTRIBUTED_DATASYNC", + } + ] + } + } + ``` + +2. Configure the fields related to cross-device migration in the configuration file. + - Configure the application to support migration. + + + Set the **continuable** field in the **module.json5** file to **true**. The default value is **false**. If this parameter is set to **false**, the application cannot be continued on the target device. + ```json + { + "module": { + // ... + "abilities": [ + { + // ... + "continuable": true, + } + ] + } + } + ``` + + - Configure the application launch type. For details, see [UIAbility Component Launch Type](uiability-launch-type.md). + +3. Request the data synchronization permission. The sample code for displaying a dialog box to request the permission is as follows: + + ```ts + requestPermission() { + let context = this.context + let permissions: Array = ['ohos.permission.DISTRIBUTED_DATASYNC'] + context.requestPermissionsFromUser(permissions).then((data) => { + console.info("Succeed to request permission from user with data: "+ JSON.stringify(data)) + }).catch((error) => { + console.info("Failed to request permission from user with error: "+ JSON.stringify(error)) + }) + } + ``` + +4. Implement [onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) in the UIAbility of the initiator. + + [onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) is called on the initiator. You can save the data in this method to implement application compatibility check and migration decision. + + - Saving migrated data: You can save the data to be migrated in key-value pairs in **wantParam**. + + - Checking application compatibility: You can obtain the version number of the target application from **wantParam** and check the compatibility between the target application and the current application. + + - Making a migration decision: You can determine whether to support the migration based on the return value of **onContinue()**. For details about the return value, see [Available APIs](#available-apis). + + The sample code is as follows: + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility'; + import AbilityConstant from '@ohos.app.ability.AbilityConstant'; + + onContinue(wantParam : {[key: string]: any}) { + console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`) + let workInput = AppStorage.Get('ContinueWork'); + // Set the user input data into wantParam. + wantParam["work"] = workInput // set user input data into want params + console.info(`onContinue input = ${wantParam["input"]}`); + return AbilityConstant.OnContinueResult.AGREE + } + ``` + +5. Implement **onCreate()** and **onNewWant()** in the UIAbility of the target application to implement data restoration. + - Implementation example of **onCreate** in the multi-instance scenario + - The target device determines whether the startup is **LaunchReason.CONTINUATION** based on **launchReason** in **onCreate()**. + - You can obtain the saved migration data from the **want** parameter. + - After data restoration is complete, call **restoreWindowStage()** to trigger page restoration. + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility'; + import AbilityConstant from '@ohos.app.ability.AbilityConstant'; + import distributedObject from '@ohos.data.distributedDataObject'; + + export default class EntryAbility extends UIAbility { + storage : LocalStorage; + onCreate(want, launchParam) { + console.info(`EntryAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`) + if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) { + // Obtain the user data from the want parameter. + let workInput = want.parameters.work + console.info(`work input ${workInput}`) + AppStorage.SetOrCreate('ContinueWork', workInput) + this.storage = new LocalStorage(); + this.context.restoreWindowStage(this.storage); + } + } + } + ``` + - For a singleton ability, use **onNewWant()** to achieve the same implementation. diff --git a/en/application-dev/application-models/hop-multi-device-collaboration.md b/en/application-dev/application-models/hop-multi-device-collaboration.md new file mode 100644 index 0000000000000000000000000000000000000000..85d6403187331a40bb9ea6280a3129dfb0e84883 --- /dev/null +++ b/en/application-dev/application-models/hop-multi-device-collaboration.md @@ -0,0 +1,542 @@ +# Multi-device Collaboration + + +## When to Use + +Multi-device coordination is available only for system applications. It involves the following scenarios: + +- [Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-and-serviceextensionability-across-devices-no-data-returned) + +- [Starting UIAbility Across Devices (Data Returned)](#starting-uiability-across-devices-data-returned) + +- [Connecting to ServiceExtensionAbility Across Devices](#connecting-to-serviceextensionability-across-devices) + +- [Using Cross-Device Ability Call](#using-cross-device-ability-call) + + +## Multi-Device Collaboration Process + +The figure below shows the multi-device collaboration process. + +**Figure 1** Multi-device collaboration process +![hop-multi-device-collaboration](figures/hop-multi-device-collaboration.png) + + +## Constraints + +- Since multi-device collaboration task management is not available, you can obtain the device list by developing system applications. Access to third-party applications is not supported. + +- Multi-device collaboration must comply with [Inter-Device Component Startup Rules](component-startup-rules.md#inter-device-component-startup-rules). + +- For better user experience, you are advised to use the **want** parameter to transmit data smaller than 100 KB. + + +## Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned) + +On device A, touch the **Start** button provided by the initiator application to start a specified UIAbility on device B. + + +### Available APIs + +**Table 1** Cross-device startup APIs + +| **API**| **Description**| +| -------- | -------- | +| startAbility(want: Want, callback: AsyncCallback<void>): void; | Starts UIAbility and ServiceExtensionAbility. This API uses an asynchronous callback to return the result.| + + +### How to Develop + +1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). + +2. Request the data synchronization permission. The sample code for displaying a dialog box to request the permission is as follows: + + ```ts + requestPermission() { + let context = this.context; + let permissions: Array = ['ohos.permission.DISTRIBUTED_DATASYNC']; + context.requestPermissionsFromUser(permissions).then((data) => { + console.info("Succeed to request permission from user with data: "+ JSON.stringify(data)); + }).catch((error) => { + console.info("Failed to request permission from user with error: "+ JSON.stringify(error)); + }) + } + ``` + +3. Obtain the device ID of the target device. + + ```ts + import deviceManager from '@ohos.distributedHardware.deviceManager'; + + let dmClass; + function initDmClass() { + // createDeviceManager is a system API. + deviceManager.createDeviceManager('ohos.samples.demo', (err, dm) => { + if (err) { + // ... + return + } + dmClass = dm + }) + } + function getRemoteDeviceId() { + if (typeof dmClass === 'object' && dmClass !== null) { + let list = dmClass.getTrustedDeviceListSync() + if (typeof (list) === 'undefined' || typeof (list.length) === 'undefined') { + console.info('EntryAbility onButtonClick getRemoteDeviceId err: list is null') + return; + } + return list[0].deviceId + } else { + console.info('EntryAbility onButtonClick getRemoteDeviceId err: dmClass is null') + } + } + ``` + +4. Set the target component parameters, and call **startAbility()** to start UIAbility or ServiceExtensionAbility. + + ```ts + let want = { + deviceId: getRemoteDeviceId(), + bundleName: 'com.example.myapplication', + abilityName: 'FuncAbility', + moduleName: 'module1', // moduleName is optional. + } + // context is the ability-level context of the initiator UIAbility. + this.context.startAbility(want).then(() => { + // ... + }).catch((err) => { + // ... + }) + ``` + + +## Starting UIAbility Across Devices (Data Returned) + +On device A, touch the **Start** button provided by the initiator application to start a specified UIAbility on device B. When the UIAbility on device B exits, a value is sent back to the initiator application. + + +### Available APIs + +**Table 2** APIs for starting an ability across devices and returning the result data + +| API| Description| +| -------- | -------- | +| startAbilityForResult(want: Want, callback: AsyncCallback<AbilityResult>): void; | Starts a UIAbility. This API uses an asynchronous callback to return the result when the UIAbility is terminated.| +| terminateSelfWithResult(parameter: AbilityResult, callback: AsyncCallback<void>): void;| Terminates this UIAbility. This API uses an asynchronous callback to return the ability result information. It is used together with **startAbilityForResult**.| +| terminateSelfWithResult(parameter: AbilityResult): Promise<void>; | Terminates this UIAbility. This API uses a promise to return the ability result information. It is used together with **startAbilityForResult**.| + + +### How to Develop + +1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). + +2. Request the data synchronization permission. The sample code for displaying a dialog box to request the permission is as follows: + + ```ts + requestPermission() { + let context = this.context; + let permissions: Array = ['ohos.permission.DISTRIBUTED_DATASYNC']; + context.requestPermissionsFromUser(permissions).then((data) => { + console.info("Succeed to request permission from user with data: "+ JSON.stringify(data)); + }).catch((error) => { + console.info("Failed to request permission from user with error: "+ JSON.stringify(error)); + }) + } + ``` + +3. Set the target component parameters on the initiator, and call **startAbilityForResult()** to start the target UIAbility. **data** in the asynchronous callback is used to receive the information returned by the target UIAbility to the initiator UIAbility after the target UIAbility terminates itself. For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-and-serviceextensionability-across-devices-no-data-returned). + + ```ts + let want = { + deviceId: getRemoteDeviceId(), + bundleName: 'com.example.myapplication', + abilityName: 'FuncAbility', + moduleName: 'module1', // moduleName is optional. + } + // context is the ability-level context of the initiator UIAbility. + this.context.startAbilityForResult(want).then((data) => { + // ... + }).catch((err) => { + // ... + }) + ``` + +4. After the UIAbility task at the target device is complete, call **terminateSelfWithResult()** to return the data to the initiator UIAbility. + + ```ts + const RESULT_CODE: number = 1001; + let abilityResult = { + resultCode: RESULT_CODE, + want: { + bundleName: 'com.example.myapplication', + abilityName: 'FuncAbility', + moduleName: 'module1', + }, + } + // context is the ability-level context of the target UIAbility. + this.context.terminateSelfWithResult(abilityResult, (err) => { + // ... + }); + ``` + +5. The initiator UIAbility receives the information returned by the target UIAbility and processes the information. + + ```ts + const RESULT_CODE: number = 1001; + + // ... + + // context is the ability-level context of the initiator UIAbility. + this.context.startAbilityForResult(want).then((data) => { + if (data?.resultCode === RESULT_CODE) { + // Parse the information returned by the target UIAbility. + let info = data.want?.parameters?.info + // ... + } + }).catch((err) => { + // ... + }) + ``` + + +## Connecting to ServiceExtensionAbility Across Devices + +A system application can connect to a service on another device by calling [connectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextconnectserviceextensionability). For example, in the distributed game scenario, a tablet is used as the remote control and a smart TV is used as the display. + + +### Available APIs + +**Table 3** APIs for cross-device connection + +| API| Description| +| -------- | -------- | +| connectServiceExtensionAbility(want: Want, options: ConnectOptions): number; | Connects to a ServiceExtensionAbility.| +| disconnectServiceExtensionAbility(connection: number, callback: AsyncCallback<void>): void; | Disconnects a connection. This API uses an asynchronous callback to return the result.| +| disconnectServiceExtensionAbility(connection: number): Promise<void>; | Disconnects a connection. This API uses a promise to return the result.| + + +### How to Develop + +1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). + +2. Request the data synchronization permission. The sample code for displaying a dialog box to request the permission is as follows: + + ```ts + requestPermission() { + let context = this.context; + let permissions: Array = ['ohos.permission.DISTRIBUTED_DATASYNC']; + context.requestPermissionsFromUser(permissions).then((data) => { + console.info("Succeed to request permission from user with data: "+ JSON.stringify(data)); + }).catch((error) => { + console.info("Failed to request permission from user with error: "+ JSON.stringify(error)); + }) + } + ``` + +3. (Optional) [Implement a background service](serviceextensionability.md#implementing-a-background-service). Perform this operation only if no background service is available. + +4. Connect to the background service. + - Implement the **IAbilityConnection** class. **IAbilityConnection** provides the following callbacks that you should implement: **onConnect()**, **onDisconnect()**, and **onFailed()**. The **onConnect()** callback is invoked when a service is connected, **onDisconnect()** is invoked when a service is unexpectedly disconnected, and **onFailed()** is invoked when the connection to a service fails. + - Set the target component parameters, including the target device ID, bundle name, and ability name. + - Call **connectServiceExtensionAbility** to initiate a connection. + - Receive the service handle returned by the target device when the connection is successful. + - Perform cross-device invoking and obtain the result returned by the target service. + + ```ts + import rpc from '@ohos.rpc'; + + const REQUEST_CODE = 99; + let want = { + "deviceId": getRemoteDeviceId(), + "bundleName": "com.example.myapplication", + "abilityName": "ServiceExtAbility" + }; + let options = { + onConnect(elementName, remote) { + console.info('onConnect callback'); + if (remote === null) { + console.info(`onConnect remote is null`); + return; + } + let option = new rpc.MessageOption(); + let data = new rpc.MessageParcel(); + let reply = new rpc.MessageParcel(); + data.writeInt(1); + data.writeInt(99); // You can send data to the target application for corresponding operations. + + // @param code Indicates the service request code sent by the client. + // @param data Indicates the {@link MessageParcel} object sent by the client. + // @param reply Indicates the response message object sent by the remote service. + // @param options Specifies whether the operation is synchronous or asynchronous. + // + // @return Returns {@code true} if the operation is successful; returns {@code false} otherwise. + remote.sendRequest(REQUEST_CODE, data, reply, option).then((ret) => { + let msg = reply.readInt(); // Receive the information (100) returned by the target device if the connection is successful. + console.info(`sendRequest ret:${ret} msg:${msg}`); + }).catch((error) => { + console.info('sendRequest failed'); + }); + }, + onDisconnect(elementName) { + console.info('onDisconnect callback'); + }, + onFailed(code) { + console.info('onFailed callback'); + } + } + // The ID returned after the connection is set up must be saved. The ID will be passed for service disconnection. + let connectionId = this.context.connectServiceExtensionAbility(want, options); + ``` + + For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-and-serviceextensionability-across-devices-no-data-returned). + +5. Disconnect the connection. Use **disconnectServiceExtensionAbility()** to disconnect from the background service. + + ```ts + let connectionId = 1 // ID returned when the service is connected through connectServiceExtensionAbility. + this.context.disconnectServiceExtensionAbility(connectionId).then((data) => { + console.info('disconnectServiceExtensionAbility success'); + }).catch((error) => { + console.error('disconnectServiceExtensionAbility failed'); + }) + ``` + + +## Using Cross-Device Ability Call + +The basic principle of cross-device ability call is the same as that of intra-device ability call. For details, see [Using Ability Call to Implement UIAbility Interaction](uiability-intra-device-interaction.md#using-ability-call-to-implement-uiability-interaction). + +The following describes how to implement multi-device collaboration through cross-device ability call. + + +### Available APIs + +**Table 4** Ability call APIs + +| API| Description| +| -------- | -------- | +| startAbilityByCall(want: Want): Promise<Caller>; | Starts a UIAbility in the foreground or background and obtains the caller object for communicating with the UIAbility.| +| on(method: string, callback: CalleeCallBack): void | Callback invoked when the callee ability registers a method.| +| 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.| +| callWithResult(method: string, data: rpc.Sequenceable): Promise<rpc.MessageParcel> | Sends agreed sequenceable data to the callee ability and obtains the agreed sequenceable data returned by the callee ability.| +| release(): void | Releases the caller object.| +| on(type: "release", callback: OnReleaseCallback): void | Callback invoked when the caller object is released.| + + +### How to Develop + +1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). + +2. Request the data synchronization permission. The sample code for displaying a dialog box to request the permission is as follows: + + ```ts + requestPermission() { + let context = this.context; + let permissions: Array = ['ohos.permission.DISTRIBUTED_DATASYNC']; + context.requestPermissionsFromUser(permissions).then((data) => { + console.info("Succeed to request permission from user with data: "+ JSON.stringify(data)); + }).catch((error) => { + console.info("Failed to request permission from user with error: "+ JSON.stringify(error)); + }) + } + ``` + +3. Create the callee ability. + + +For the callee ability, implement the callback to receive data and the methods to marshal and unmarshal data. When data needs to be received, use **on()** to register a listener. When data does not need to be received, use **off()** to deregister the listener. + + 1. Configure the launch type of the UIAbility. + + Set **launchType** of the callee ability to **singleton** in the **module.json5** file. + + | JSON Field| Description| + | -------- | -------- | + | "launchType"| Ability launch type. Set this parameter to **singleton**.| + + An example of the UIAbility configuration is as follows: + + +​ + ```json + "abilities":[{ + "name": ".CalleeAbility", + "srcEntrance": "./ets/CalleeAbility/CalleeAbility.ts", + "launchType": "singleton", + "description": "$string:CalleeAbility_desc", + "icon": "$media:icon", + "label": "$string:CalleeAbility_label", + "visible": true + }] + ``` + + 2. Import the **UIAbility** module. + + ```ts + import Ability from '@ohos.app.ability.UIAbility'; + ``` + + 3. Define the agreed sequenceable data. + + + The data formats sent and received by the caller and callee abilities must be consistent. In the following example, the data formats are number and string. + + + ```ts + export default class MySequenceable { + num: number = 0; + str: string = ""; + + constructor(num, string) { + this.num = num; + this.str = string; + } + + marshalling(messageParcel) { + messageParcel.writeInt(this.num); + messageParcel.writeString(this.str); + return true; + } + + unmarshalling(messageParcel) { + this.num = messageParcel.readInt(); + this.str = messageParcel.readString(); + return true; + } + } + ``` + + 4. Implement **Callee.on** and **Callee.off**. + + In the following example, the **MSG_SEND_METHOD** listener is registered in **onCreate()** of the ability and deregistered in **onDestroy()**. After receiving sequenceable data, the application processes the data and returns the data result. You need to implement processing based on service requirements. + + ```ts + const TAG: string = '[CalleeAbility]'; + const MSG_SEND_METHOD: string = 'CallSendMsg'; + + function sendMsgCallback(data) { + console.info('CalleeSortFunc called'); + + // Obtain the sequenceable data sent by the caller ability. + let receivedData = new MySequenceable(0, ''); + data.readSequenceable(receivedData); + console.info(`receiveData[${receivedData.num}, ${receivedData.str}]`); + + // Process the data. + // Return the sequenceable data result to the caller ability. + return new MySequenceable(receivedData.num + 1, `send ${receivedData.str} succeed`); + } + + export default class CalleeAbility extends Ability { + onCreate(want, launchParam) { + try { + this.callee.on(MSG_SEND_METHOD, sendMsgCallback); + } catch (error) { + console.info(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`); + } + } + + onDestroy() { + try { + this.callee.off(MSG_SEND_METHOD); + } catch (error) { + console.error(TAG, `${MSG_SEND_METHOD} unregister failed with error ${JSON.stringify(error)}`); + } + } + } + ``` + +4. Obtain the caller object and access the callee ability. + 1. Import the **UIAbility** module. + + ```ts + import Ability from '@ohos.app.ability.UIAbility'; + ``` + + 2. Obtain the caller object. + + + The **context** attribute of the ability implements **startAbilityByCall** to obtain the caller object for communication. The following example uses **this.context** to obtain the **context** attribute of the ability, uses **startAbilityByCall** to start the callee ability, obtain the caller object, and register the **onRelease** listener of the caller ability. You need to implement processing based on service requirements. + + + ```ts + async onButtonGetRemoteCaller() { + var caller = undefined; + var context = this.context; + + context.startAbilityByCall({ + deviceId: getRemoteDeviceId(), + bundleName: 'com.samples.CallApplication', + abilityName: 'CalleeAbility' + }).then((data) => { + if (data != null) { + caller = data; + console.info('get remote caller success'); + // Register the onRelease() listener of the caller ability. + caller.onRelease((msg) => { + console.info(`remote caller onRelease is called ${msg}`); + }) + console.info('remote caller register OnRelease succeed'); + } + }).catch((error) => { + console.error(`get remote caller failed with ${error}`); + }) + } + ``` + + For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility and ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-and-serviceextensionability-across-devices-no-data-returned). + ``` + +5. Sends agreed sequenceable data to the callee ability. + 1. The sequenceable data can be sent to the callee ability with or without a return value. The method and sequenceable data must be consistent with those of the callee ability. The following example describes how to send data to the callee ability. + + ```ts + const MSG_SEND_METHOD: string = 'CallSendMsg'; + async onButtonCall() { + try { + let msg = new MySequenceable(1, 'origin_Msg'); + await this.caller.call(MSG_SEND_METHOD, msg); + } catch (error) { + console.info(`caller call failed with ${error}`); + } + } + ``` + 2. In the following, **CallWithResult** is used to send data **originMsg** to the callee ability and assign the data processed by the **CallSendMsg** method to **backMsg**. + + ```ts + const MSG_SEND_METHOD: string = 'CallSendMsg'; + originMsg: string = ''; + backMsg: string = ''; + async onButtonCallWithResult(originMsg, backMsg) { + try { + let msg = new MySequenceable(1, originMsg); + const data = await this.caller.callWithResult(MSG_SEND_METHOD, msg); + console.info('caller callWithResult succeed'); + + let result = new MySequenceable(0, ''); + data.readSequenceable(result); + backMsg(result.str); + console.info(`caller result is [${result.num}, ${result.str}]`); + } catch (error) { + console.info(`caller callWithResult failed with ${error}`); + } + } + ``` + +6. Release the caller object. + + When the caller object is no longer required, use **release()** to release it. + + ```ts + releaseCall() { + try { + this.caller.release(); + this.caller = undefined + console.info('caller release succeed'); + } catch (error) { + console.info(`caller release failed with ${error}`); + } + } + ``` diff --git a/en/application-dev/application-models/inter-device-interaction-hop-overview.md b/en/application-dev/application-models/inter-device-interaction-hop-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..6b1fd28b489f0d6d891abd9dffa0bcaf0f1b9ead --- /dev/null +++ b/en/application-dev/application-models/inter-device-interaction-hop-overview.md @@ -0,0 +1,49 @@ +# Continuation Overview + + +## When to Use + +As the all-scenario, multi-device lifestyle becomes popular, users have an increasing number of devices. Each device provides users with what they need in a certain scenario. For example, watches allow users to view information in a timely manner, and smart TVs bring them an immersive watching experience. However, each device has its limitation, for example, typing text on a smart TV is frustrating as it is much more difficult than on a mobile device. If multiple devices can sense each other through a distributed OS and together form a super device, the strengths of each device can be fully exerted to provide a more natural and smoother distributed experience for users. + +In OpenHarmony, distributed operations across devices are called continuation (previously named hopping), which is further classified into [cross-device migration](hop-cross-device-migration.md) and [multi-device collaboration](hop-multi-device-collaboration.md). To implement continuation, cross-device interaction capabilities of application components are required. Currently, these capabilities are open only to system applications. + + +## Basic Concepts + +- **Continuation** + + Continuation refers to distributed operations across devices. It breaks device boundaries and makes applications modular. For example, a user can edit the same email, carry out fitness, or play a game across devices. Continuation provides broad application scenarios, innovative product perspectives, enhanced product advantages, and superior experience. + +- **Cross-device migration** + + When the environment changes, for example, when a user goes outdoors or when a more appropriate device is detected, the user can migrate an ongoing task to another device for better experience. The original device exits the task. A typical cross-device migration scenario is as follows: You migrate a video playback task from your tablet to a smart TV. The video application on the tablet exits. From the perspective of application development, cross-device migration migrates the UIAbility component running on device A to device B. After the migration is complete, the UIAbility component on device B continues the task, whereas that on device A exits. + +- **Multi-device collaboration** + + Multi-device collaboration enables collaboration between multiple devices, providing users with more efficient and immersive experience than with a single device. A typical multi-device collaboration scenario is as follows: Application A on the tablet is used as the answer board, and application B on the smart TV is used for live broadcast, delivering a better online class experience. From the perspective of application development, multi-device collaboration enables different UIAbility or ServiceExtensionAbility components to run simultaneously or alternately on multiple devices to provide a complete service, or enables the same UIAbility and ServiceExtensionAbility component to run simultaneously on multiple devices to provide a complete service. + + +## Continuation Architecture + +OpenHarmony provides a set of APIs for you to implement continuation in your applications. The continuation architecture has the following advantages: + +- Capabilities such as remote service invocation to facilitate service design + +- Simultaneous continuation of multiple applications + +- Different device forms supported, such as tablets, smart TVs, and watches + +The following figure shows the continuation architecture. + + **Figure 1** Continuation architecture +hop-structure + +- Cross-device migration task management: The initiator accepts a migration request from the user, provides a migration entry, and displays the migration result. (This capability is unavailable yet.) + +- Multi-device collaboration task management: The initiator accepts an application registration request and provides management capabilities such as starting or stopping collaboration and status display. (This capability is unavailable yet.) + +- Distributed component management: provides capabilities such as remote service startup, remote service connection, and remote migration, and enables cross-device migration or multi-device collaboration of applications based on a combination of these capabilities. + +- Distributed security authentication: provides an E2E encrypted channel for cross-device transmission between applications to ensure that the right person uses the right data through the right device. + +- DSoftBus: functions as a unified communication base for a wide range of devices such as tablets, wearables, and smart TVs, and enables unified distributed communication between these devices. diff --git a/en/application-dev/application-models/itc-fa-overview.md b/en/application-dev/application-models/itc-fa-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..112a89edd8ba8236fca714a65d6f93287dcbe41d --- /dev/null +++ b/en/application-dev/application-models/itc-fa-overview.md @@ -0,0 +1,4 @@ +# Inter-Thread Communication (FA Model) + + +For details, see [Inter-Thread Communication](thread-model-stage.md) in the stage model. diff --git a/en/application-dev/application-models/itc-with-emitter.md b/en/application-dev/application-models/itc-with-emitter.md new file mode 100644 index 0000000000000000000000000000000000000000..2966bd8eea41e04893814f20a3c5b2f9e4e456c9 --- /dev/null +++ b/en/application-dev/application-models/itc-with-emitter.md @@ -0,0 +1,49 @@ +# Using Emitter for Inter-Thread Communication + +[Emitter](../reference/apis/js-apis-emitter.md) provides APIs for sending and processing events between threads, including the APIs for processing events that are subscribed to in persistent or one-shot manner, unsubscribing from events, and emitting events to the event queue. + + +To develop the Emitter mode, perform the following steps: + + +1. Subscribe to an event. + + ```ts + import emitter from "@ohos.events.emitter"; + + // Define an event with eventId 1. + let event = { + eventId: 1 + }; + + // Trigger the callback after the event with eventId 1 is received. + let callback = (eventData) => { + console.info('event callback'); + }; + + // Subscribe to the event with eventId 1. + emitter.on(event, callback); + ``` + +2. Emit the event. + + ```ts + import emitter from "@ohos.events.emitter"; + + // Define an event with eventId 1 and priority Low. + let event = { + eventId: 1, + priority: emitter.EventPriority.LOW + }; + + let eventData = { + data: { + "content": "c", + "id": 1, + "isEmpty": false, + } + }; + + // Emit the event with eventId 1 and event content eventData. + emitter.emit(event, eventData); + ``` diff --git a/en/application-dev/application-models/itc-with-worker.md b/en/application-dev/application-models/itc-with-worker.md new file mode 100644 index 0000000000000000000000000000000000000000..8cbe53eeea067ae1875a8ff4b73bc4cde7bdd629 --- /dev/null +++ b/en/application-dev/application-models/itc-with-worker.md @@ -0,0 +1,79 @@ +# Using Worker for Inter-Thread Communication + +[Worker](../reference/apis/js-apis-worker.md) is an independent thread running in parallel with the main thread. The thread that creates the worker thread is referred to as the host thread. The script file passed in during worker creation is executed in the worker thread. Generally, time-consuming operations are processed in the worker thread. However, pages cannot be directly updated in the worker thread. + + +To develop the Worker mode, perform the following steps: + + +1. Configure the **buildOption** field in the [module-level build-profile.json5](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-building-configuration-0000001218440654#section6887184182020) file of the project. + + ```ts + "buildOption": { + "sourceOption": { + "workers": [ + "./src/main/ets/workers/worker.ts" + ] + } + } + ``` + +2. Create the **worker.js** file based on the configuration in **build-profile.json5**. + + ```ts + import worker from '@ohos.worker'; + + let parent = worker.workerPort; + + // Process messages from the main thread. + parent.onmessage = function(message) { + console.info("onmessage: " + message) + // Send a message to the main thread. + parent.postMessage("message from worker thread.") + } + ``` + +3. In the main thread, use the following method to initialize and use the worker thread. + - Stage model: + + ```ts + import worker from '@ohos.worker'; + + let wk = new worker.ThreadWorker("entry/ets/workers/worker.ts"); + + // Send a message to the worker thread. + wk.postMessage("message from main thread.") + + // Process messages from the worker thread. + wk.onmessage = function(message) { + console.info("message from worker: " + message) + + // Stop the worker thread based on service requirements. + wk.terminate() + } + ``` + + - FA model: + + ```ts + import worker from '@ohos.worker'; + + let wk = new worker.ThreadWorker("../workers/worker.js"); + + // Send a message to the worker thread. + wk.postMessage("message from main thread.") + + // Process messages from the worker thread. + wk.onmessage = function(message) { + console.info("message from worker: " + message) + + // Stop the worker thread based on service requirements. + wk.terminate() + } + ``` + +> **NOTE** +> +> - If the relative path of **worker.ts** configured in **build-profile.json5** is **./src/main/ets/workers/worker.ts**, pass in the path **entry/ets/workers/worker.ts** when creating a worker thread in the stage model, and pass in the path **../workers/worker.js** when creating a worker thread in the FA model. +> +> - For details about the data types supported between the main thread and worker thread, see [Sequenceable Data Types](../reference/apis/js-apis-worker.md#sequenceable-data-types). diff --git a/en/application-dev/application-models/lifecycleapp-switch.md b/en/application-dev/application-models/lifecycleapp-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..892a8915bfed9927c2707364bdaffa1547f71bf6 --- /dev/null +++ b/en/application-dev/application-models/lifecycleapp-switch.md @@ -0,0 +1,21 @@ +# LifecycleApp Switching + + + | API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| +| -------- | -------- | -------- | +| onShow?(): void; | \@ohos.window.d.ts | [on(eventType: 'windowStageEvent', callback: Callback<WindowStageEventType>): void;](../reference/apis/js-apis-window.md#onwindowstageevent9)
Listens for the switching to the [foreground](../reference/apis/js-apis-window.md#windowstageeventtype9).| +| onHide?(): void; | \@ohos.window.d.ts | [on(eventType: 'windowStageEvent', callback: Callback<WindowStageEventType>): void;](../reference/apis/js-apis-window.md#onwindowstageevent9)
Listens for the switching to the [background](../reference/apis/js-apis-window.md#windowstageeventtype9).| +| onDestroy?(): void; | \@ohos.app.ability.UIAbility.d.ts | [onDestroy(): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityondestroy) | +| onCreate?(): void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want: Want, param: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate) | +| onWindowDisplayModeChanged?(isShownInMultiWindow: boolean, newConfig: resourceManager.Configuration): void; | There is no corresponding API in the stage model.| No corresponding API is provided.| +| onStartContinuation?(): boolean; | There is no corresponding API in the stage model.| In the stage model, an application does not need to detect whether the continuation is successful (detected when the application initiates the continuation request). Therefore, the **onStartContinuation()** callback is deprecated.| +| onSaveData?(data: Object): boolean; | \@ohos.app.ability.UIAbility.d.ts | [onContinue(wantParam : {[key: string]: any}): AbilityConstant.OnContinueResult;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) | +| onCompleteContinuation?(result: number): void; | application\ContinueCallback.d.ts | [onContinueDone(result: number): void;](../reference/apis/js-apis-distributedMissionManager.md#continuecallback) | +| onRestoreData?(data: Object): void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want: Want, param: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate)
[onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)
In standard or singleton mode, the target ability completes data restoration in the **onCreate()** callback. In the callback, **launchParam.launchReason** is used to determine whether it is a continuation-based launch scenario. If it is, the data saved before continuation can be obtained from the **want** parameter.| +| onRemoteTerminated?(): void; | application\ContinueCallback.d.ts | [onContinueDone(result: number): void;](../reference/apis/js-apis-distributedMissionManager.md#continuecallback) | +| onSaveAbilityState?(outState: PacMap): void; | \@ohos.app.ability.UIAbility.d.ts | [onSaveState(reason: AbilityConstant.StateType, wantParam : {[key: string]: any}): AbilityConstant.OnSaveResult;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonsavestate) | +| onRestoreAbilityState?(inState: PacMap): void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want: Want, param: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate)
After the application is restarted, the **onCreate()** callback is triggered. In the callback, **launchParam.launchReason** is used to determine whether it is a self-recovery scenario. If it is, the data saved before the restart can be obtained from the **want** parameter.| +| onInactive?(): void; | \@ohos.app.ability.UIAbility.d.ts | [onBackground(): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonbackground) | +| onActive?(): void; | \@ohos.app.ability.UIAbility.d.ts | [onForeground(): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonforeground) | +| onNewWant?(want: Want): void; | \@ohos.app.ability.UIAbility.d.ts | [onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) | +| onMemoryLevel?(level: number): void | \@ohos.app.ability.UIAbility.d.ts | [onMemoryLevel(level: AbilityConstant.MemoryLevel): void;](../reference/apis/js-apis-app-ability-ability.md#abilityonmemorylevel) | diff --git a/en/application-dev/application-models/lifecycledata-switch.md b/en/application-dev/application-models/lifecycledata-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..be96421a92161deeb26c9e99af9ec5de332d9e25 --- /dev/null +++ b/en/application-dev/application-models/lifecycledata-switch.md @@ -0,0 +1,18 @@ +# LifecycleData Switching + + + | API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| +| -------- | -------- | -------- | +| update?(uri: string, valueBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback<number>): void; | \@ohos.application.DataShareExtensionAbility.d.ts | [update?(uri: string, predicates: dataSharePredicates.DataSharePredicates, valueBucket: ValuesBucket, callback: AsyncCallback<number>): void;](../reference/apis/js-apis-application-dataShareExtensionAbility.md#update) | +| query?(uri: string, columns: Array<string>, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback<ResultSet>): void; | \@ohos.application.DataShareExtensionAbility.d.ts | [query?(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array<string>, callback: AsyncCallback<Object>): void;](../reference/apis/js-apis-application-dataShareExtensionAbility.md#query) | +| delete?(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback<number>): void; | \@ohos.application.DataShareExtensionAbility.d.ts | [delete?(uri: string, predicates: dataSharePredicates.DataSharePredicates, callback: AsyncCallback<number>): void;](../reference/apis/js-apis-application-dataShareExtensionAbility.md#delete) | +| normalizeUri?(uri: string, callback: AsyncCallback<string>): void; | \@ohos.application.DataShareExtensionAbility.d.ts | [normalizeUri?(uri: string, callback: AsyncCallback<string>): void;](../reference/apis/js-apis-application-dataShareExtensionAbility.md#normalizeuri) | +| batchInsert?(uri: string, valueBuckets: Array<rdb.ValuesBucket>, callback: AsyncCallback<number>): void; | \@ohos.application.DataShareExtensionAbility.d.ts | [batchInsert?(uri: string, valueBuckets: Array<ValuesBucket>, callback: AsyncCallback<number>): void;](../reference/apis/js-apis-application-dataShareExtensionAbility.md#batchinsert) | +| denormalizeUri?(uri: string, callback: AsyncCallback<string>): void; | \@ohos.application.DataShareExtensionAbility.d.ts | [denormalizeUri?(uri: string, callback: AsyncCallback<string>): void;](../reference/apis/js-apis-application-dataShareExtensionAbility.md#denormalizeuri) | +| insert?(uri: string, valueBucket: rdb.ValuesBucket, callback: AsyncCallback<number>): void; | \@ohos.application.DataShareExtensionAbility.d.ts | [insert?(uri: string, valueBucket: ValuesBucket, callback: AsyncCallback<number>): void;](../reference/apis/js-apis-application-dataShareExtensionAbility.md#insert) | +| openFile?(uri: string, mode: string, callback: AsyncCallback<number>): void; | 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<Array<string>>): void; | 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.| +| onInitialized?(info: AbilityInfo): void; | \@ohos.application.DataShareExtensionAbility.d.ts | [onCreate?(want: Want, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-application-dataShareExtensionAbility.md#oncreate) | +| getType?(uri: string, callback: AsyncCallback<string>): void; | 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.| +| executeBatch?(ops: Array<DataAbilityOperation>, callback: AsyncCallback<Array<DataAbilityResult>>): void; | There is no corresponding API in the stage model.| No corresponding API is provided.| +| call?(method: string, arg: string, extras: PacMap, callback: AsyncCallback<PacMap>): void; | There is no corresponding API in the stage model.| No corresponding API is provided.| diff --git a/en/application-dev/application-models/lifecycleform-switch.md b/en/application-dev/application-models/lifecycleform-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..80e577eeac759f589cb53c6b367ae17ba8b98e8c --- /dev/null +++ b/en/application-dev/application-models/lifecycleform-switch.md @@ -0,0 +1,13 @@ +# LifecycleForm Switching + + + | API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| +| -------- | -------- | -------- | +| onCreate?(want: Want): formBindingData.FormBindingData; | \@ohos.app.form.FormExtensionAbility.d.ts | [onAddForm(want: Want): formBindingData.FormBindingData;](../reference/apis/js-apis-app-form-formExtensionAbility.md#onaddform) | +| onCastToNormal?(formId: string): void; | \@ohos.app.form.FormExtensionAbility.d.ts | [onCastToNormalForm(formId: string): void;](../reference/apis/js-apis-app-form-formExtensionAbility.md#oncasttonormalform) | +| onUpdate?(formId: string): void; | \@ohos.app.form.FormExtensionAbility.d.ts | [onUpdateForm(formId: string): void;](../reference/apis/js-apis-app-form-formExtensionAbility.md#onupdateform) | +| onVisibilityChange?(newStatus: { [key: string]: number }): void; | \@ohos.app.form.FormExtensionAbility.d.ts | [onChangeFormVisibility(newStatus: { [key: string]: number }): void;](../reference/apis/js-apis-app-form-formExtensionAbility.md#onchangeformvisibility) | +| onEvent?(formId: string, message: string): void; | \@ohos.app.form.FormExtensionAbility.d.ts | [onFormEvent(formId: string, message: string): void;](../reference/apis/js-apis-app-form-formExtensionAbility.md#onformevent) | +| onDestroy?(formId: string): void; | \@ohos.app.form.FormExtensionAbility.d.ts | [onRemoveForm(formId: string): void;](../reference/apis/js-apis-app-form-formExtensionAbility.md#onremoveform) | +| onAcquireFormState?(want: Want): formInfo.FormState; | \@ohos.app.form.FormExtensionAbility.d.ts | [onAcquireFormState?(want: Want): formInfo.FormState;](../reference/apis/js-apis-app-form-formExtensionAbility.md#onacquireformstate) | +| onShare?(formId: string): {[key: string]: any}; | \@ohos.app.form.FormExtensionAbility.d.ts | [onShareForm?(formId: string): { [key: string]: any };](../reference/apis/js-apis-app-form-formExtensionAbility.md#onshareform) | diff --git a/en/application-dev/application-models/lifecycleservice-switch.md b/en/application-dev/application-models/lifecycleservice-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..d1fcdc7a30efb0114e092ac5a6233566270312fa --- /dev/null +++ b/en/application-dev/application-models/lifecycleservice-switch.md @@ -0,0 +1,11 @@ +# LifecycleService Switching + + + | API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| +| -------- | -------- | -------- | +| onStart?(): void; | \@ohos.app.ability.ServiceExtensionAbility.d.ts | [onCreate(want: Want): void;](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityoncreate) | +| onCommand?(want: Want, startId: number): void; | \@ohos.app.ability.ServiceExtensionAbility.d.ts | [onRequest(want: Want, startId: number): void;](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityonrequest) | | +| onStop?(): void; | \@ohos.app.ability.ServiceExtensionAbility.d.ts | [onDestroy(): void;](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityondestroy) | | +| onConnect?(want: Want): rpc.RemoteObject; | \@ohos.app.ability.ServiceExtensionAbility.d.ts | [onConnect(want: Want): rpc.RemoteObject;](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityonconnect) | | +| onDisconnect?(want: Want): void; | \@ohos.app.ability.ServiceExtensionAbility.d.ts | [onDisconnect(want: Want): void;](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityondisconnect) | | +| onReconnect?(want: Want): void; | \@ohos.app.ability.ServiceExtensionAbility.d.ts | [onReconnect(want: Want): void;](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityonreconnect) | | diff --git a/en/application-dev/application-models/medialibrary-switch.md b/en/application-dev/application-models/medialibrary-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..29e9b10964d2b9c967960f6c2ad802a942aa0ac3 --- /dev/null +++ b/en/application-dev/application-models/medialibrary-switch.md @@ -0,0 +1,6 @@ +# mediaLibrary Switching + + + | API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| +| -------- | -------- | -------- | +| [getMediaLibrary(): MediaLibrary;](../reference/apis/js-apis-medialibrary.md#medialibrarygetmedialibrary) | \@ohos.multimedia.mediaLibrary.d.ts | [getMediaLibrary(context: Context): MediaLibrary;](../reference/apis/js-apis-medialibrary.md#medialibrarygetmedialibrary8) | diff --git a/en/application-dev/application-models/mission-management-fa.md b/en/application-dev/application-models/mission-management-fa.md new file mode 100644 index 0000000000000000000000000000000000000000..07641af7d736f298c99908805a5493cadadd4b00 --- /dev/null +++ b/en/application-dev/application-models/mission-management-fa.md @@ -0,0 +1,4 @@ +# Mission Management (FA Model) + + +For details, see [Mission Management](mission-management-overview.md) in the stage model. diff --git a/en/application-dev/application-models/mission-management-launch-type.md b/en/application-dev/application-models/mission-management-launch-type.md new file mode 100644 index 0000000000000000000000000000000000000000..7dbb3b5c8fa5a8dfab3f03ab0eb3b02ba4cb98d2 --- /dev/null +++ b/en/application-dev/application-models/mission-management-launch-type.md @@ -0,0 +1,34 @@ +# Mission Management and Launch Type + + +One UIAbility instance corresponds to one mission. The number of UIAbility instances is related to the UIAbility launch type, specified by **launchType**, which is configured in the **config.json** file in the FA model and the [module.json5](../quick-start/module-configuration-file.md) file in the stage model. + + +The following describes how the mission list manager manages the UIAbility instanced started in different modes. +- **singleton**: Only one UIAbility instance exists for an application. + + **Figure 1** Missions and singleton mode + ![mission-and-singleton](figures/mission-and-singleton.png) + +- **standard**: Each time **startAbility()** is called, a UIAbility instance is created in the application process. + + **Figure 2** Missions and standard mode + ![mission-and-standard](figures/mission-and-standard.png) + +- **specified**: The ([onAcceptWant](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)) method of [AbilityStage](abilitystage.md) determines whether to create an instance. + + **Figure 3** Missions and specified mode + ![mission-and-specified](figures/mission-and-specified.png) + + +Each UIAbility instance corresponds to a mission displayed in **Recents**. + + +Every mission retains a snapshot of the UIAbility instance. After the UIAbility instance is destroyed, the mission information (including the ability information and mission snapshot) is retained until the mission is deleted. + + +> **NOTE** +> +> The **specified** mode is supported in the stage model only. + + \ No newline at end of file diff --git a/en/application-dev/application-models/mission-management-overview.md b/en/application-dev/application-models/mission-management-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..b6f6668f7ce56a9de0b5a3d0182b14ec189703c9 --- /dev/null +++ b/en/application-dev/application-models/mission-management-overview.md @@ -0,0 +1,129 @@ +# Mission Management Scenarios + + +Before getting started with the development of mission management, be familiar with the following concepts related to mission management: + + +- AbilityRecord: minimum unit for the system service to manage a UIAbility instance. It corresponds to a UIAbility component instance of an application. + +- MissionRecord: minimum unit for mission management. One MissionRecord has only one AbilityRecord. In other words, a UIAbility component instance corresponds to a mission. + +- MissionList: a list of missions started from the home screen. It records the startup relationship between missions. In a MissionList, an above mission is started by the mission under it, and the mission at the bottom is started by the home screen. + +- MissionListManager: system mission management module that maintains all the MissionLists and is consistent with the list in **Recents**. + + **Figure 1** Mission management + ![mission-list-manager](figures/mission-list-manager.png) + + +Missions are managed by system applications (such as home screen), rather than third-party applications. Users interact with missions through **Recents**. After creating a mission, users can perform the following operations on **Recents**: + + +- Delete a mission. + +- Lock or unlock a mission. (Locked missions are not cleared when users attempt to clear all missions in **Recents**.) + +- Clear all missions in **Recents**. + +- Switch a mission to the foreground. + + +A UIAbility instance corresponds to an independent mission. Therefore, when an application calls the **startAbility()** method to start a UIAbility, a mission is created. + + +To call [missionManager](../reference/apis/js-apis-application-missionManager.md) to manage missions, the home screen application must request the **ohos.permission.MANAGE_MISSIONS** permission. For details about the configuration, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). + + +You can use **missionManager** to manage missions, for example, listening for mission changes, obtaining mission information or snapshots, and clearing, locking, or unlocking missions. The sample code is as follows: + +```ts +import missionManager from '@ohos.app.ability.missionManager' + +let listener = { + // Listen for mission creation. + onMissionCreated: function (mission) { + console.info("--------onMissionCreated-------") + }, + // Listen for mission destruction. + onMissionDestroyed: function (mission) { + console.info("--------onMissionDestroyed-------") + }, + // Listen for mission snapshot changes. + onMissionSnapshotChanged: function (mission) { + console.info("--------onMissionSnapshotChanged-------") + }, + // Listen for switching the mission to the foreground. + onMissionMovedToFront: function (mission) { + console.info("--------onMissionMovedToFront-------") + }, + // Listen for mission icon changes. + onMissionIconUpdated: function (mission, icon) { + console.info("--------onMissionIconUpdated-------") + }, + // Listen for mission name changes. + onMissionLabelUpdated: function (mission) { + console.info("--------onMissionLabelUpdated-------") + }, + // Listen for mission closure events. + onMissionClosed: function (mission) { + console.info("--------onMissionClosed-------") + } +}; + +// 1. Register a mission change listener. +let listenerId = missionManager.on('mission', listener); + +// 2. Obtain the latest 20 missions in the system. +missionManager.getMissionInfos("", 20, (error, missions) => { + console.info("getMissionInfos is called, error.code = " + error.code); + console.info("size = " + missions.length); + console.info("missions = " + JSON.stringify(missions)); +}); + +// 3. Obtain the detailed information about a mission. +let missionId = 11; // The mission ID 11 is only an example. +let mission = missionManager.getMissionInfo("", missionId).catch(function (err) { + console.info(err); +}); + +// 4. Obtain the mission snapshot. +missionManager.getMissionSnapShot("", missionId, (error, snapshot) => { + console.info("getMissionSnapShot is called, error.code = " + error.code); + console.info("bundleName = " + snapshot.ability.bundleName); +}) + +// 5. Obtain the low-resolution mission snapshot. +missionManager.getLowResolutionMissionSnapShot("", missionId, (error, snapshot) => { + console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code); + console.info("bundleName = " + snapshot.ability.bundleName); +}) + +// 6. Lock or unlock the mission. +missionManager.lockMission(missionId).then(() => { + console.info("lockMission is called "); +}); + +missionManager.unlockMission(missionId).then(() => { + console.info("unlockMission is called "); +}); + +// 7. Switch the mission to the foreground. +missionManager.moveMissionToFront(missionId).then(() => { + console.info("moveMissionToFront is called "); +}); + +// 8. Clear a single mission. +missionManager.clearMission(missionId).then(() => { + console.info("clearMission is called "); +}); + +// 9. Clear all missions. +missionManager.clearAllMissions().catch(function (err) { + console.info(err); +}); + +// 10. Deregister the mission change listener. +missionManager.off('mission', listenerId, (error) => { + console.info("unregisterMissionListener"); +}) +``` diff --git a/en/application-dev/application-models/model-switch-overview.md b/en/application-dev/application-models/model-switch-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..e42882ca59b33c65fe6591510954d95e2c49453b --- /dev/null +++ b/en/application-dev/application-models/model-switch-overview.md @@ -0,0 +1,23 @@ +# Model Switching Overview + + +Perform the following operations to switch a declarative paradigm-based application developed based on the FA model to the stage model. + + +- Project switch: Create an application project of the stage model. + ![model-switch-overview1](figures/model-switch-overview1.png) + +- [Configuration file switch](configuration-file-diff.md): Switch **config.json** to **app.json5** and **module.json5**. + ![model-switch-overview2](figures/model-switch-overview2.png) + +- [Component switch](pageability-switch.md): Switch the PageAbility, ServiceAbility, and DataAbility components of the FA model to the UIAbility and ExtensionAbility components of the stage model. The figure below shows only the switching from PageAbility to UIAbility. The left part is the FA model, and **app.ets** is the PageAbility component. The right part is the stage model, and **EntryAbility.ts** is the UIAbility component. + +![model-switch-overview3](figures/model-switch-overview3.png) + +- [Widget switch](widget-switch.md): Switch the FormAbility component of the FA model to the FormExtensionAbility component of the stage model. In the figure below, **Service Widget** is FormAbility in the FA model and FormExtensionAbility in the stage model. + ![model-switch-overview4](figures/model-switch-overview4.png) + + ![model-switch-overview5](figures/model-switch-overview5.png) + +- [API switch](api-switch-overview.md): Switch the APIs with the **FAModelOnly** tag used in the FA model to the recommended APIs in the stage model. + ![model-switch-overview6](figures/model-switch-overview6.png) diff --git a/en/application-dev/application-models/module-switch.md b/en/application-dev/application-models/module-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..a6e532e94827198880cb772c174725b2a89c469b --- /dev/null +++ b/en/application-dev/application-models/module-switch.md @@ -0,0 +1,75 @@ +# Switching of module + + +When switching an application from the FA model to the stage model, you must migrate the configurations under the **module** tag in the **config.json** file to the **module** tag in the **module.json5** file. + +### **Table 1** module comparison + +| Field Name in the FA Model| Field Description| Field Name in the Stage Model| Difference| +| -------- | -------- | -------- | -------- | +| mainAbility | Ability displayed on the Service Center icon. When the resident process is started, the **mainAbility** is started.| mainElement | The field name is changed, and the stage mode does not use the period (.) in ability names.| +| package | Package name of the HAP file, which must be unique in the application.| / | The stage model uses **name** to ensure application uniqueness. To ensure a successful switching from the FA model to the stage model, **name** in the stage model must be the same as **package** in the FA model.| +| name | Class name of the HAP file.| / | This configuration is not enabled in the FA model, and the stage model does not have such a field.| +| supportedModes | Modes supported by the application. Currently, only the **drive** mode is defined.| / | This configuration is deprecated in the stage model.| +| moduleName in the distro object| Name of the current HAP file.
moduleName in the distro object.| name | The field name is changed.| +| moduleType in the distro object| Type of the HAP file. The value can be **entry** or **feature**. For the HAR type, set this field to **har**.| type | The field name is changed.| +| installationFree in the distro object| Whether the HAP file supports the installation-free feature.| installationFree | The field name is changed.| +| deliveryWithInstall in the distro object| Whether the HAP file is installed with the application.| deliveryWithInstall | The field name is changed.| +| metaData | Metadata of the HAP file.| metadata | See [Table 2](#table-2-metadata-comparison).| +| abilities | All abilities in the current module.| abilities | See [Table 5](#table-5-abilities-comparison).| +| js | A set of JS modules developed using ArkUI. Each element in the set represents the information about a JS module.| pages | The stage model retains **pages** under the **module** tag. The window configuration is the lower level of **pages**.| +| shortcuts | Shortcuts of the application.| shortcut_config.json| In the stage model, the **shortcut_config.json** file is defined in **resources/base/profile** in the development view.| +| reqPermissions | Permissions that the application requests from the system when it is running.| requestPermissions | The field name is changed.| +| colorMode | Color mode of the application.| / | This configuration is not supported in the stage model.| +| distroFilter | Distribution rules of the application.| distroFilter_config.json| In the stage model, the **distroFilter_config.json** file is defined in **resources/base/profile** in the development view.| +| reqCapabilities | Device capabilities required for running the application.| / | This configuration is not supported in the stage model.| +| commonEvents | Common events.| common_event_config.json| In the stage model, the **common_event_config.json** file is defined in **resources/base/profile** in the development view.| +| entryTheme | Keyword of an OpenHarmony internal theme.| / | This configuration is not supported in the stage model.| + + +### Table 2 metaData comparison + +| Field Name Under metaData in the FA Model| Field Description| Field Name Under metaData in the Stage Model| Difference| +| -------- | -------- | -------- | -------- | +| parameters | Metadata of the parameters to be passed for calling the ability.| / | This configuration is not supported in the stage model.| +| results | Metadata of the ability return value.| / | This configuration is not supported in the stage model.| +| customizeData | Custom metadata of the parent component. **parameters** and **results** cannot be configured in **application**.| metadata | See [Table 3](#table-3-comparison-between-customizedata-under-metadata-in-the-fa-model-and-metadata-in-the-stage-model).| + +### Table 3 Comparison between customizeData under metaData in the FA model and metadata in the stage model + +| Field Name Under customizeData in metaData in the FA Model| Field Description| Field Name Under metaData in the Stage Model| Difference| +| -------- | -------- | -------- | -------- | +| name | Key name that identifies a data item. The value is a string with a maximum of 255 bytes.| name | None.| +| value | Value of the data item. The value is a string with a maximum of 255 bytes.| value | None.| +| extra | Format of the current custom data. The value is the resource value of **extra**.| resource | The field name is changed. For details, see [Table 4](#table 4-metadata-examples).| + + +### Table 4 metaData examples + +| Example in the FA Model| Example in the Stage Model| +| -------- | -------- | +| "meteData": {
"customizeDate": [{
"name": "label",
"value": "string",
"extra": "$string:label",
}]
} | "meteData": [{
"name": "label",
"value": "string",
"resource": "$string:label",
}] | + + +### Table 5 abilities comparison + +| Field Name Under abilities in the FA Model| Field Description| Field Name Under abilities in the Stage Model| Difference| +| -------- | -------- | -------- | -------- | +| process | Name of the process running the application or ability.| / | The stage model does not support configuration of **process** under **abilities**. The configuration of **process** is available under the **module** tag.| +| uri | URI of the ability.| / | This configuration is not supported in the stage model.| +| deviceCapability | Device capabilities required to run the ability.| / | This configuration is not supported in the stage model.| +| metaData | Metadata of the ability.| metadata | See [Table 2](#table-2-metadata-comparison).| +| type | Ability type.| / | This configuration is not supported in the stage model.| +| grantPermission | Whether permissions can be granted for any data in the ability.| / | The stage model does not support such a configuration under **abilities**.| +| readPermission | Permission required for reading data in the ability. This field applies only to the ability using the Data template.| / | In the stage model, this configuration is available under **extensionAbilities**, but not **abilities**.| +| writePermission | Permission required for writing data to the ability.| / | In the stage model, this configuration is available under **extensionAbilities**, but not **abilities**.| +| configChanges | System configurations that the ability concerns.| / | This configuration is not supported in the stage model.| +| mission | Mission stack of the ability.| / | This configuration is not supported in the stage model.| +| targetAbility | Target ability that this ability alias points to.| / | This configuration is not supported in the stage model.| +| multiUserShared | Whether the ability supports data sharing among multiple users. This field applies only to the ability using the Data template.| / | This configuration is not supported in the stage model.| +| supportPipMode | Whether the ability allows the user to enter the Picture in Picture (PiP) mode. The PiP mode enables the user to watch a video in a small window that hovers on top of a full screen window (main window).| / | This configuration is not supported in the stage model.| +| formsEnabled | Whether the ability can provide widgets.| / | This configuration is not supported in the stage model.| +| forms | Information about the widgets used by the ability. This field is valid only when **formsEnabled** is set to **true**.| form_config.json| In the stage model, the **form_config.json** file is defined in **resources/base/profile** in the development view.| +| srcLanguage | Programming language used to develop the ability.| / | This configuration is not supported in the stage model.| +| srcPath | Path of the JS component code corresponding to the ability.| srcEntrance | Path of the JS code corresponding to the ability.| +| uriPermission | Application data that the ability can access.| / | This configuration is not supported in the stage model.| diff --git a/en/application-dev/application-models/page-mission-stack.md b/en/application-dev/application-models/page-mission-stack.md new file mode 100644 index 0000000000000000000000000000000000000000..702cb9ba928d5266ce6720d10538df6109b0cbeb --- /dev/null +++ b/en/application-dev/application-models/page-mission-stack.md @@ -0,0 +1,51 @@ +# Page Stack and MissionList + + +## Page Stack + +A single UIAbility component can implement multiple pages and redirection between these pages. The redirection relationship inside the UIAbility component is called page stack, which is managed by the ArkUI framework. For example, Page1 -> Page2 -> Page3 of UIAbility1 and PageA -> PageB -> PageC of UIAbility2 in the figure below are two page stacks. + + **Figure 1** Page stack +![mission-record](figures/mission-record.png) + +- A page stack is formed as follows (Steps 2, 3, 5, and 6 are page redirection and managed by ArkUI): + 1. Touch the icon on the home screen. The [startAbility](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartability) method is called to start UIAbility1, whose initial page is Page1. + + 2. Touch a button on Page1. The [Navigator](../reference/arkui-ts/ts-container-navigator.md) method is called to redirect you to Page2. + + 3. Touch a button on Page2. The [Navigator](../reference/arkui-ts/ts-container-navigator.md) method is called to redirect you to Page3. + + 4. Touch a button on Page3. The [startAbility](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartability) method is called to start UIAbility2, whose initial page is PageA. + + 5. Touch a button on PageA. The [Navigator](../reference/arkui-ts/ts-container-navigator.md) method is called to redirect you to PageB. + + 6. Touch a button on PageB. The [Navigator](../reference/arkui-ts/ts-container-navigator.md) method is called to redirect you to PageC. + +- The page stack return is as follows (Steps 1, 2, 4, and 5 are page redirection and managed by ArkUI): + 1. Touch the **Back** button on PageC of UIAbility2 to return to PageB. + + 2. Touch the **Back** button on PageB of UIAbility2 to return to PageA. + + 3. Touch the **Back** button on PageA of UIAbility2 to return to Page3 of UIAbility1. + + 4. Touch the **Back** button on Page3 of UIAbility1 to return to Page2. + + 5. Touch the **Back** button on Page2 of UIAbility1 to return to Page1 of UIAbility1. + + 6. Touch the **Back** button on Page1 of UIAbility1 to return to the home screen. + + +## MissionList + +As described above, you can keep touching the **Back** button on the page of Ability2 to return to a page of Ability1. The MissionList records the startup relationship between missions. If Ability1 starts Ability2 through **startAbility()**, a MissionList is formed: Ability1 -> Ability2. Therefore, when you touch the **Back** button on the initial page of Ability2, a page of Ability1 is displayed. + +The mission startup relationship recorded by the MissionList may be broken in the following cases: + +- A user moves a mission in the middle of the MissionList to the foreground. + ![mission-chain1](figures/mission-chain1.png) + +- A user deletes a mission in the MissionList. + ![mission-chain2](figures/mission-chain2.png) + +- A UIAbility singleton is repeatedly started by different missions. For example, AbilityB in the figure below is a singleton. + ![mission-chain3](figures/mission-chain3.png) diff --git a/en/application-dev/application-models/pageability-configuration.md b/en/application-dev/application-models/pageability-configuration.md new file mode 100644 index 0000000000000000000000000000000000000000..c11e7b17554844d21e024228bbec51e621d6383d --- /dev/null +++ b/en/application-dev/application-models/pageability-configuration.md @@ -0,0 +1,12 @@ +# PageAbility Component Configuration + + +The PageAbility is configured in **abilities** under **module** in the **config.json** file. The **icon** field indicates the index of the ability icon resource file, and the **label** field indicates the ability name presented to users, and the **skills** field indicates the type of Want that is acceptable to the ability. + +**Table 1** PageAbility configuration items + +| Name| Description| Data Type| Initial Value Allowed| +| -------- | -------- | -------- | -------- | +| icon | Index to the ability icon file. Example value: **$media:ability_icon**. 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 of the ability is also used as the icon of the application. If multiple abilities address this condition, the icon of the first candidate ability is used as the application icon.
Note: The **icon** and **label** values of an application are visible to users. Ensure that at least one of them is different from any existing icons or labels.| String| Yes (initial value: left empty)| +| label | Ability name visible to users. The value can be a name string or a resource index to names 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 label of the ability is also used as the label of the application. If multiple abilities address this condition, the label of the first candidate ability is used as the application label.
Note: The **icon** and **label** values of an application are visible to users. Ensure that at least one of them is different from any existing icons or labels. The value can be a reference to a string defined in a resource file or a string enclosed in brackets ({}). The value can contain a maximum of 255 characters.| String| Yes (initial value: left empty)| +| skills | Types of the Want that can be accepted by the ability.| Object array| Yes (initial value: left empty)| diff --git a/en/application-dev/application-models/pageability-launch-type.md b/en/application-dev/application-models/pageability-launch-type.md new file mode 100644 index 0000000000000000000000000000000000000000..5241a7cabefbf3e68e6a3f413b8892ef5f6ff8d3 --- /dev/null +++ b/en/application-dev/application-models/pageability-launch-type.md @@ -0,0 +1,39 @@ +# PageAbility Launch Type + + +Depending on the launch type, the action performed when the PageAbility starts differs, as described in the table below. + +**Table 1** PageAbility launch types + +| Launch Type| Description| +| -------- | -------- | +| singleton | Each time **startAbility()** is called, if an ability instance of this type already exists in the application process, the instance is reused. There is only one ability instance of this type in **Recents**.
A typical scenario is as follows: When a user opens a video playback application and watches a video, returns to the home screen, and opens the video playback application again, the video that the user watched before returning to the home screen is still played.| +| standard | Default type. Each time **startAbility()** is called, a new ability instance is created in the application process. Multiple ability instances of this type are displayed in **Recents**.
A typical scenario is as follows: When a user opens a document application and touches **New**, a new document task is created. Multiple new document missions are displayed in **Recents**.| + + +You can set **launchType** in the **config.json** file to configure the launch type. The sample code is as follows: + +```json +{ + "module": { + // ... + "abilities": [ + { + // singleton mode. + // standard mode. + "launchType": "standard", + // ... + } + ] + } +} +``` + + +When the PageAbility is started for the first time (either in standard or singleton mode), the [PageAbility lifecycle callbacks](pageability-lifecycle.md#table13118194914476) are triggered. When it is not started for the first time in singleton mode, the **onNewWant()** callback (as described in the table below) is triggered, but the **onCreate()** callback is not. + +**Table 2** Callbacks specific to the singleton mode + +| API| Description| +| -------- | -------- | +| onNewWant(want: Want) | **onNewWant()** is triggered when the PageAbility is not started for the first time in singleton mode. You can obtain Want from this callback and perform further processing based on Want. For example, in the singleton PageAbility migration scenario, you can specify a page to start the PageAbility.| diff --git a/en/application-dev/application-models/pageability-lifecycle.md b/en/application-dev/application-models/pageability-lifecycle.md new file mode 100644 index 0000000000000000000000000000000000000000..3608346ec5403735a79fdf9a01478be9b86745d9 --- /dev/null +++ b/en/application-dev/application-models/pageability-lifecycle.md @@ -0,0 +1,45 @@ +# PageAbility Lifecycle + + +The PageAbility lifecycle defines all states of a PageAbility, such as **INACTIVE**, **ACTIVE**, and **BACKGROUND**. The figure below shows the lifecycle state transition. + +**Figure 1** PageAbility lifecycle + +![page-ability-lifecycle](figures/page-ability-lifecycle.png) + +**Table 1** PageAbility lifecycle states + +| State| Description| +| -------- | -------- | +| UNINITIALIZED | The PageAbility is not initialized. This is a temporary state, from which a PageAbility changes directly to the **INITIAL** state upon its creation.| +| INITIAL | The PageAbility is initialized but not running. The PageAbility enters the **INACTIVE** state after it is started.| +| INACTIVE | The PageAbility is visible but does not gain focus.| +| ACTIVE | The PageAbility runs in the foreground and has focus.| +| BACKGROUND | The PageAbility runs in the background. After being re-activated, the PageAbility enters the **ACTIVE** state. After being destroyed, it enters the **INITIAL** state.| + + +You can override the lifecycle callbacks (as described in the table below) in **app.js** or **app.ets**. + +**Table 2** PageAbility lifecycle callbacks + +| API| Description| +| -------- | -------- | +| onCreate() | Called when the ability is created for the first time. You can initialize the application in this callback.| +| onDestroy() | Called when the ability is destroyed. In this callback, you can make preparations for application exit, such as recycling resources and clearing the cache.| +| onActive() | Called when the ability is switched to the foreground and gains focus.| +| onInactive() | Called when the ability loses focus. An ability loses focus when it is about to enter the background state.| +| onShow() | Called when the ability is switched from the background to the foreground. In this case, the ability is visible to users.| +| onHide() | Called when the ability is switched from the foreground to the background. In this case, the ability is invisible to users.| + + +The following figure shows the relationship between lifecycle callbacks and lifecycle states of the PageAbility. + +Figure 2 Relationship between lifecycle callbacks and lifecycle states + +![fa-pageAbility-lifecycle](figures/fa-pageAbility-lifecycle.png) + + +> **NOTE** +> +> - The PageAbility lifecycle callbacks are synchronous. +> - The **app.js** file provides only the **onCreate** and **onDestroy** callbacks, and the **app.ets** file provides the full lifecycle callbacks. diff --git a/en/application-dev/application-models/pageability-overview.md b/en/application-dev/application-models/pageability-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..00370ca29056fcb8d23e93de54a38b2003bc6941 --- /dev/null +++ b/en/application-dev/application-models/pageability-overview.md @@ -0,0 +1,7 @@ +# PageAbility Component Overview + + +PageAbility is an application component that has the UI and supports user interaction. + + +When you create a PageAbility in DevEco Studio, DevEco Studio automatically creates template code. The capabilities related to the PageAbility are implemented through the **featureAbility** class, and the lifecycle callbacks are implemented through the callbacks in **app.js** or **app.ets**. diff --git a/en/application-dev/application-models/pageability-switch.md b/en/application-dev/application-models/pageability-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..1953c02c8067a38d1633ae9eb9f768dc60a87e0f --- /dev/null +++ b/en/application-dev/application-models/pageability-switch.md @@ -0,0 +1,56 @@ +# PageAbility Switching + + +The PageAbility component in the FA model corresponds to the UIAbility component in the stage model. To switch a PageAbility to a UIAbility, perform the following operations: + + +1. [Create a UIAbility](uiability-usage.md) in the stage model. + +2. Migrate the PageAbility code to the UIAbility. + +The PageAbility lifecycle is basically the same as the UIAbility lifecycle. The table below describes the details. + + | PageAbility| UIAbility| Mapping Description| + | -------- | -------- | -------- | + | onCreate(): void| onCreate(want: Want, param: AbilityConstant.LaunchParam): void | The two methods have the same meaning and invoking time. In the stage model, parameters are added to the callback so that you can obtain startup-related data during creation.| + | NA | onWindowStageCreate(windowStage: window.WindowStage): void| This method is available only in the stage model. The callback is invoked when a window is created.| + | onActive(): void | on(eventType: 'windowStageEvent', callback: Callback<WindowStageEventType>): void;
WindowStageEventType.ACTIVE | The two methods have the same meaning and invoking time. In the stage model, this method is moved to the window object.| + | onShow(): void | onForeground(): void | The two methods have the same meaning, invoking time, and parameters.| + | onNewWant(want: Want): void| onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void| The two methods have the same meaning and invoking time. In the stage model, the **LaunchParam** parameter is added to notify the application of the startup cause.| + | onInactive(): void| on(eventType: 'windowStageEvent', callback: Callback<WindowStageEventType>): void;
WindowStageEventType.INACTIVE | The two methods have the same meaning and invoking time. In the stage model, this method is moved to the window object.| + | onHide(): void | onBackground(): void | The two methods have the same meaning, invoking time, and parameters.| + | NA | onWindowStageDestroy(): void | This method is available only in the stage model. The callback is invoked when a window is destroyed.| +| onDestroy(): void | onDestroy(): void | The two methods have the same meaning, invoking time, and parameters.| + +![pageability-switch](figures/pageability-switch.png) + +3. Adjust the migrated code, since the methods of loading pages are different. + + - In the FA model, you can configure the page to be loaded by setting page information in **config.json**. + - In the stage model, you must call **windowStage.loadContent** in the **onWindowStageCreate** callback to load a page. + + For example, to load the **pages/Index** page after the ability is started, use the following code in the **config.json** file in the FA model: + + + ```json + "pages" : [ + "pages/Index" + ] + ``` + + In the stage model, implement the following method in **MainAbility**: + + + ```ts + import Window from '@ohos.window' + + onWindowStageCreate(windowStage: Window.WindowStage) { + // Main window is created. Set a main page for this ability. + windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + console.error("loadContent failed") + return; + } + }); + } + ``` diff --git a/en/application-dev/application-models/particleability-switch.md b/en/application-dev/application-models/particleability-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..21ecd96c9a24f1328c20da14abf5cc8f8d079b95 --- /dev/null +++ b/en/application-dev/application-models/particleability-switch.md @@ -0,0 +1,12 @@ +# particleAbility Switching + + + | API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| +| -------- | -------- | -------- | +| [startAbility(parameter: StartAbilityParameter, callback: AsyncCallback<number>): void;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitystartability)
[startAbility(parameter: StartAbilityParameter): Promise<number>;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitystartability-1) | application\ServiceExtensionContext.d.ts | [startAbility(want: Want, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartability)
[startAbility(want: Want, options: StartOptions, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartability-2)
[startAbility(want: Want, options?: StartOptions): Promise<void>;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartability-1)
[startServiceExtensionAbility(want: Want, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartserviceextensionability)
[startServiceExtensionAbility(want: Want): Promise<void>;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartserviceextensionability-1) | +| [terminateSelf(callback: AsyncCallback<void>): void;](../reference/apis/js-apis-ability-particleAbility.md#particleabilityterminateself)
[terminateSelf(): Promise<void>;](../reference/apis/js-apis-ability-particleAbility.md#particleabilityterminateself-1) | application\ServiceExtensionContext.d.ts | [terminateSelf(callback: AsyncCallback<void>): void;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself)
[terminateSelf(): Promise<void>;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself-1) | +| [connectAbility(request: Want, options:ConnectOptions ): number;](../reference/apis/js-apis-ability-particleAbility.md#particleabilityconnectability) | application\ServiceExtensionContext.d.ts | [connectAbility(want: Want, options: ConnectOptions): number;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextconnectserviceextensionability)
[connectServiceExtensionAbility(want: Want, options: ConnectOptions): number;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextconnectserviceextensionability) | +| [disconnectAbility(connection: number, callback:AsyncCallback<void>): void;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitydisconnectability)
[disconnectAbility(connection: number): Promise<void>;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitydisconnectability-1) | application\ServiceExtensionContext.d.ts | [disconnectAbility(connection: number, callback:AsyncCallback<void>): void; ](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextdisconnectserviceextensionability)
[disconnectAbility(connection: number): Promise<void>;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextdisconnectserviceextensionability-1)
[disconnectServiceExtensionAbility(connection: number, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextdisconnectserviceextensionability)
[disconnectServiceExtensionAbility(connection: number): Promise<void>;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextdisconnectserviceextensionability-1) | +| [acquireDataAbilityHelper(uri: string): DataAbilityHelper;](../reference/apis/js-apis-ability-particleAbility.md#particleabilityacquiredataabilityhelper) | \@ohos.data.dataShare.d.ts
[\@ohos.data.fileAccess.d.ts | [createDataShareHelper(context: Context, uri: string, callback: AsyncCallback<DataShareHelper>): void;](../reference/apis/js-apis-data-dataShare.md#datasharecreatedatasharehelper)
[createDataShareHelper(context: Context, uri: string): Promise<DataShareHelper>;](../reference/apis/js-apis-data-dataShare.md#datasharecreatedatasharehelper-1)
[createFileAccessHelper(context: Context): FileAccessHelper;](../reference/apis/js-apis-fileAccess.md#fileaccesscreatefileaccesshelper-1)
[createFileAccessHelper(context: Context, wants: Array<Want>): FileAccessHelper;](../reference/apis/js-apis-fileAccess.md#fileaccesscreatefileaccesshelper) | +| [startBackgroundRunning(id: number, request: NotificationRequest, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitystartbackgroundrunning)
[startBackgroundRunning(id: number, request: NotificationRequest): Promise<void>;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitystartbackgroundrunning-1) | \@ohos.resourceschedule.backgroundTaskManager.d.ts | [startBackgroundRunning(context: Context, bgMode: BackgroundMode, wantAgent: WantAgent, callback: AsyncCallback): void;](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagerstartbackgroundrunningcallback)
[startBackgroundRunning(context: Context, bgMode: BackgroundMode, wantAgent: WantAgent): Promise<void>;](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagerstartbackgroundrunningpromise) | +| [cancelBackgroundRunning(callback: AsyncCallback<void>): void;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitycancelbackgroundrunning)
[cancelBackgroundRunning(): Promise<void>;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitycancelbackgroundrunning-1) | \@ohos.resourceschedule.backgroundTaskManager.d.ts | [stopBackgroundRunning(context: Context, callback: AsyncCallback): void;](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagerstopbackgroundrunningcallback)
[stopBackgroundRunning(context: Context): Promise<void>;](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagerstopbackgroundrunningpromise) | diff --git a/en/application-dev/application-models/process-model-fa.md b/en/application-dev/application-models/process-model-fa.md new file mode 100644 index 0000000000000000000000000000000000000000..699643031121521fbf95d26a949df906fa175a18 --- /dev/null +++ b/en/application-dev/application-models/process-model-fa.md @@ -0,0 +1,22 @@ +# Process Model (FA Model) + + +The OpenHarmony process model is shown below. + + +- All PageAbility, ServiceAbility, DataAbility, and FormAbility components of an application (with the same bundle name) run in an independent process, which is **Main process** in green in the figure. + +- WebView has an independent rendering process, which is **Render process** in yellow in the figure. + + **Figure 1** Process model + + ![process-model-fa](figures/process-model-fa.png) + + +OpenHarmony provides two inter-process communication (IPC) mechanisms. + + +- [Common Events](common-event-fa.md): This mechanism is used in one-to-many communication scenarios. Multiple subscribers may receive events at the same time. + +- [Background Services](rpc.md): This mechanism is implemented through [ServiceAbility](serviceability-overview.md). + diff --git a/en/application-dev/application-models/process-model-stage.md b/en/application-dev/application-models/process-model-stage.md new file mode 100644 index 0000000000000000000000000000000000000000..bbfa0602aecb127c5e484f0ebbdcb166f81310f7 --- /dev/null +++ b/en/application-dev/application-models/process-model-stage.md @@ -0,0 +1,31 @@ +# Process Model (Stage Model) + + +The OpenHarmony process model is shown below. + + +- All UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility components of an application (with the same bundle name) run in an independent process, which is **Main process** in green in the figure. + +- The ExtensionAbility components of the same type (except ServiceExtensionAbility and DataShareExtensionAbility) of an application (with the same bundle name) run in an independent process, which is **FormExtensionAbility process**, **InputMethodExtensionAbility process**, and other **ExtensionAbility process** in blue in the figure. + +- WebView has an independent rendering process, which is **Render process** in yellow in the figure. + + **Figure 1** Process model +![process-model](figures/process-model.png) + +> NOTE +> +> You can create ServiceExtensionAbility and DataShareExtensionAbility only for system applications. + +A system application can apply for multi-process permissions (as shown in the following figure) and configure a custom process for an HAP. UIAbility, DataShareExtensionAbility, and ServiceExtensionAbility in the HAP run in the custom process. Different HAPs run in different processes by configuring different process names. + +**Figure 2** Multi-process +![multi-process](figures/multi-process.png) + + +OpenHarmony provides two inter-process communication (IPC) mechanisms. + + +- [Common Events](common-event-overview.md): This mechanism is used in one-to-many communication scenarios. Multiple subscribers may receive events at the same time. + +- [Background Services](background-services.md): This mechanism is implemented through [ServiceExtensionAbility](serviceextensionability.md). diff --git a/en/application-dev/application-models/public_sys-resources/icon-caution.gif b/en/application-dev/application-models/public_sys-resources/icon-caution.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/en/application-dev/application-models/public_sys-resources/icon-caution.gif differ diff --git a/en/application-dev/application-models/public_sys-resources/icon-danger.gif b/en/application-dev/application-models/public_sys-resources/icon-danger.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/en/application-dev/application-models/public_sys-resources/icon-danger.gif differ diff --git a/en/application-dev/application-models/public_sys-resources/icon-note.gif b/en/application-dev/application-models/public_sys-resources/icon-note.gif new file mode 100644 index 0000000000000000000000000000000000000000..6314297e45c1de184204098efd4814d6dc8b1cda Binary files /dev/null and b/en/application-dev/application-models/public_sys-resources/icon-note.gif differ diff --git a/en/application-dev/application-models/public_sys-resources/icon-notice.gif b/en/application-dev/application-models/public_sys-resources/icon-notice.gif new file mode 100644 index 0000000000000000000000000000000000000000..86024f61b691400bea99e5b1f506d9d9aef36e27 Binary files /dev/null and b/en/application-dev/application-models/public_sys-resources/icon-notice.gif differ diff --git a/en/application-dev/application-models/public_sys-resources/icon-tip.gif b/en/application-dev/application-models/public_sys-resources/icon-tip.gif new file mode 100644 index 0000000000000000000000000000000000000000..93aa72053b510e456b149f36a0972703ea9999b7 Binary files /dev/null and b/en/application-dev/application-models/public_sys-resources/icon-tip.gif differ diff --git a/en/application-dev/application-models/public_sys-resources/icon-warning.gif b/en/application-dev/application-models/public_sys-resources/icon-warning.gif new file mode 100644 index 0000000000000000000000000000000000000000..6e90d7cfc2193e39e10bb58c38d01a23f045d571 Binary files /dev/null and b/en/application-dev/application-models/public_sys-resources/icon-warning.gif differ diff --git a/en/application-dev/application-models/redirection-rules.md b/en/application-dev/application-models/redirection-rules.md new file mode 100644 index 0000000000000000000000000000000000000000..c5c9987c261364f87dadc0333b310744fe12f971 --- /dev/null +++ b/en/application-dev/application-models/redirection-rules.md @@ -0,0 +1,36 @@ +# Redirection Rules + + +Generally, UI redirection within an application is triggered by users. However, an application can call **startAbility()** to implement UI redirection. + + +The PageAbility has a UI. It can use **startAbility()** to start an ability that has a UI and is visible to users. + + +The **visible** field under **abilities** in the **config.json** file specifies whether an ability can be started by other application components. + +**Table 1** Description of visible + +| Name| Description| Initial Value Allowed| +| -------- | -------- | -------- | +| visible | Whether the ability can be called by other applications.
**true**: The ability can be called by any application.
**false**: The ability can be called only by other components of the same application.| Yes (initial value: **false**)| + + +To enable an ability to be called by any application, configure the **config.json** file as follows: + +```ts +{ + "module": { + // ... + "abilities": [ + { + "visible": "true", + // ... + } + ] + } +} +``` + + +If the ability contains **skills**, you are advised to set **visible** to **true** so that the ability can be [implicitly started](explicit-implicit-want-mappings.md#interpretation-of-implicit-want-matching-rules) by other applications. If this attribute is set to **false**, the system returns **PERMISSION_DENIED** when other applications attempt to start the ability. In this case, a system application can request the [START_INVISIBLE_ABILITY](../security/permission-list.md) permission to start the ability. Example abilities with **visible** set to **false** are home screen, voice assistant, or search assistant. diff --git a/en/application-dev/application-models/request-permissions.md b/en/application-dev/application-models/request-permissions.md new file mode 100644 index 0000000000000000000000000000000000000000..670860d87dbb56adceb02f4ca350c24b61260d30 --- /dev/null +++ b/en/application-dev/application-models/request-permissions.md @@ -0,0 +1,45 @@ +# 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 users. + + +During application development, you must declare the required permission in the **config.json** file and call **requestPermissionsFromUser** to request the permission from users in the form of a dialog box. + + +To declare a permission in **config.json**, add **reqPermissions** under **module** and list the permission. + + +For example, to declare the permission to access the calendar, request the **ohos.permission.READ_CALENDAR** permission. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). + + +The sample code in the **config.json** file is as follows: + +```json +{ + "module": { + // ... + "reqPermissions": [ + { + "name": "ohos.permission.READ_CALENDAR" + // ... + } + ] + } +} +``` + + +Request the permission from uses in the form of a dialog box: + +```ts +import featureAbility from '@ohos.ability.featureAbility'; + +let context = featureAbility.getContext(); +let permissions: Array = ['ohos.permission.READ_CALENDAR'] +context.requestPermissionsFromUser(permissions, 1).then((data) => { + console.info("Succeed to request permission from user with data: " + JSON.stringify(data)) +}).catch((error) => { + console.info("Failed to request permission from user with error: " + JSON.stringify(error)) +}) +``` diff --git a/en/application-dev/application-models/request-switch.md b/en/application-dev/application-models/request-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..5c9e2f49d48aaba203a6207de37992823ab5ae97 --- /dev/null +++ b/en/application-dev/application-models/request-switch.md @@ -0,0 +1,7 @@ +# request Switching + + + | API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| +| -------- | -------- | -------- | +| [download(config: DownloadConfig, callback: AsyncCallback<DownloadTask>): void;](../reference/apis//js-apis-request.md#requestdownload-1)
[download(config: DownloadConfig): Promise<DownloadTask>;](../reference/apis/js-apis-request.md#requestdownload) | \@ohos.request.d.ts | [downloadFile(context: BaseContext, config: DownloadConfig, callback: AsyncCallback<DownloadTask>): void;](../reference/apis/js-apis-request.md#requestdownloadfile9-1)
[downloadFile(context: BaseContext, config: DownloadConfig): Promise<DownloadTask>;](../reference/apis/js-apis-request.md#requestdownloadfile9) | +| [upload(config: UploadConfig, callback: AsyncCallback<UploadTask>): void;](../reference/apis/js-apis-request.md#requestupload-1)
[upload(config: UploadConfig): Promise<UploadTask>;](../reference/apis/js-apis-request.md#requestupload) | \@ohos.request.d.ts | [uploadFile(context: BaseContext, config: UploadConfig, callback: AsyncCallback<UploadTask>): void;](../reference/apis/js-apis-request.md#requestuploadfile9-1)
[uploadFile(context: BaseContext, config: UploadConfig): Promise<UploadTask>;](../reference/apis/js-apis-request.md#requestuploadfile9) | diff --git a/en/application-dev/application-models/resourcemanager-switch.md b/en/application-dev/application-models/resourcemanager-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..34eedb16597e30c76ccaed2c01a3b4c7206c0dfd --- /dev/null +++ b/en/application-dev/application-models/resourcemanager-switch.md @@ -0,0 +1,6 @@ +# resourceManager Switching + + + | API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding Field in the Stage Model| +| -------- | -------- | -------- | +| [getResourceManager(callback: AsyncCallback<ResourceManager>): void;](../reference/apis/js-apis-resource-manager.md#resourcemanagergetresourcemanager)
[getResourceManager(bundleName: string, callback: AsyncCallback<ResourceManager>): void;](../reference/apis/js-apis-resource-manager.md#resourcemanagergetresourcemanager-1)
[getResourceManager(): Promise<ResourceManager>;](../reference/apis/js-apis-resource-manager.md#resourcemanagergetresourcemanager-2)
[getResourceManager(bundleName: string): Promise<ResourceManager>;](../reference/apis/js-apis-resource-manager.md#resourcemanagergetresourcemanager-3) | application\Context.d.ts | [resourceManager: resmgr.ResourceManager;](../reference/apis/js-apis-inner-application-context.md#attributes)| diff --git a/en/application-dev/application-models/rpc.md b/en/application-dev/application-models/rpc.md new file mode 100644 index 0000000000000000000000000000000000000000..69fd10c315c9f3ec007358dad86fef71c4363d53 --- /dev/null +++ b/en/application-dev/application-models/rpc.md @@ -0,0 +1,4 @@ +# Background Services (FA Model) + + +For details, see [Background Services](background-services.md) in the stage model. diff --git a/en/application-dev/application-models/serviceability-configuration.md b/en/application-dev/application-models/serviceability-configuration.md new file mode 100644 index 0000000000000000000000000000000000000000..a0bf139c2ec08382b73e1bce7bb87882a2306def --- /dev/null +++ b/en/application-dev/application-models/serviceability-configuration.md @@ -0,0 +1,17 @@ +# ServiceAbility Component Configuration + + +Similar to a PageAbility, a ServiceAbility is configured in **abilities** under **module** of the **config.json** file. The difference between a ServiceAbility and PageAbility lies in the **type** and **backgroundModes** fields. + + + **Table 1** ServiceAbility configuration items + +| Name| Description| Data Type| Initial Value Allowed| +| -------- | -------- | -------- | -------- | +| type | Type of the ability. The value **service** indicates that the ability is developed based on the Service template.| String| No| +| backgroundModes | Background service type of the ability. You can assign multiple background service types to a specific ability. This field applies only to the ability using the Service template. The value can be:
**dataTransfer**: service for downloading, backing up, sharing, or transferring data from the network or peer devices.
**audioPlayback**: audio playback service.
**audioRecording**: audio recording service.
**pictureInPicture**: picture in picture (PiP) and small-window video playback services.
**voip**: voice/video call and VoIP services.
**location**: location and navigation services.
**bluetoothInteraction**: Bluetooth scanning, connection, and transmission services.
**wifiInteraction**: WLAN scanning, connection, and transmission services.
**screenFetch**: screen recording and screenshot services.
**multiDeviceConnection**: multi-device interconnection service.| String array| Yes (initial value: left empty)| + + +For details about the configuration items, see [Internal Structure of module](../quick-start/module-structure.md). + + \ No newline at end of file diff --git a/en/application-dev/application-models/serviceability-lifecycle.md b/en/application-dev/application-models/serviceability-lifecycle.md new file mode 100644 index 0000000000000000000000000000000000000000..cc541c77ea0bec412eee09b7b7b3fe4e7e1008d0 --- /dev/null +++ b/en/application-dev/application-models/serviceability-lifecycle.md @@ -0,0 +1,15 @@ +# ServiceAbility Lifecycle + + +You can override lifecycle callbacks (described in the table below) for ServiceAbility based on service requirements. + + + **Table 1** ServiceAbility lifecycle callbacks + +| API| Description| +| -------- | -------- | +| onStart(): void | Called to initialize a ServiceAbility when the ServiceAbility is being created. This callback is invoked only once in the entire lifecycle of a ServiceAbility.| +| onCommand(want: Want, startId: number): void | Called every time a ServiceAbility is started on the client. You can collect calling statistics and perform initialization operations in this callback.| +| onConnect(want: Want): rpc.RemoteObject | Called when the ServiceAbility is connected.| +| onDisconnect(want: Want): void | Called when the connection to the ServiceAbility is disconnected.| +| onStop(): void | Called when the ServiceAbility is being destroyed. You should override this callback for your ServiceAbility to clear its resources, such as threads and registered listeners.| diff --git a/en/application-dev/application-models/serviceability-overview.md b/en/application-dev/application-models/serviceability-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..ba57633f7bd489dd75ddba4cf8d7e829fa97dae4 --- /dev/null +++ b/en/application-dev/application-models/serviceability-overview.md @@ -0,0 +1,4 @@ +# ServiceAbility Component Overview + + +An ability using the Service template (ServiceAbility for short) is used to run tasks in the background, such as playing music or downloading files. It does not provide a UI for user interaction. A ServiceAbility can be started by another application or a PageAbility. It remains to run in the background even after the user switches to another application. diff --git a/en/application-dev/application-models/serviceability-switch.md b/en/application-dev/application-models/serviceability-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..9752a4a11be4982ab65b4fc17262a39b6190b00b --- /dev/null +++ b/en/application-dev/application-models/serviceability-switch.md @@ -0,0 +1,35 @@ +# ServiceAbility Switching + + +The ServiceAbility component in the FA model corresponds to the ServiceExtensionAbility component in the stage model. The ServiceExtensionAbility class provides system APIs. Only system applications can create ServiceExtensionAbility instances. Therefore, ServiceAbility switching adopts different policies for system applications and third-party applications. + + +## Switching a ServiceAbility of a System Application + +The procedure for switching a ServiceAbility of a system application is similar to the procedure of PageAbility switching. + +1. [Create a ServiceExtensionAbility](serviceextensionability.md) in the stage model. + +2. Migrate the ServiceAbility code to the ServiceExtensionAbility. + +The table below describes the lifecycle comparison of the ServiceAbility and ServiceExtensionAbility. + + | ServiceAbility| ServiceExtensionAbility| Comparison Description| + | -------- | -------- | -------- | + | onStart(): void | onCreate(want: Want): void | The two methods have the same invoking time. In the stage model, the **want** parameter is added so that you can obtain parameters during creation.| + | onCommand(want: Want, startId: number): void | onRequest(want: Want, startId: number): void | The two methods have the same meaning, invoking time, and parameters.| + | onConnect(want: Want): rpc.RemoteObject | onConnect(want: Want): rpc.RemoteObject | The two methods have the same meaning, invoking time, and parameters.| + | onDisconnect(want: Want): void | onDisconnect(want: Want): void | The two methods have the same meaning, invoking time, and parameters.| + | onReconnect(want: Want): void| onReconnect(want: Want): void| The two methods have the same meaning, invoking time, and parameters.| + | onStop(): void | onDestroy(): void | The two methods have the same meaning, invoking time, and parameters.| + + +## Switching a ServiceAbility of a Third-Party Application + +In the stage model, third-party applications cannot provide services for other third-party applications. You can select a switching solution based on your service requirements. + +| Service Type| Switching Solution| +| -------- | -------- | +| Providing services for other third-party applications| Match a scenario-specific [ExtensionAbility](extensionability-overview.md).| +| In-application: providing public use when it is running in the foreground| Extract the component code as a common module for other components to use.| +| In-application: continuing running when it switches to the background| Switch the service to [a background service](serviceextensionability.md).| diff --git a/en/application-dev/application-models/serviceextensionability.md b/en/application-dev/application-models/serviceextensionability.md new file mode 100644 index 0000000000000000000000000000000000000000..6626bf66592f4fabb9abf890b163b9b392f04955 --- /dev/null +++ b/en/application-dev/application-models/serviceextensionability.md @@ -0,0 +1,296 @@ +# ServiceExtensionAbility + +[ServiceExtensionAbility](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md) is an ExtensionAbility component of the service type that provides extension capabilities related to background services. + + +ServiceExtensionAbility can be started or connected by other application components to process transactions in the background based on the request of the caller. System applications can call the [startServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartserviceextensionability) method to start background services or call the [connectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextconnectserviceextensionability) method to connect to background services. Third-party applications can call only **connectServiceExtensionAbility()** to connect to background services. The differences between starting and connecting to background services are as follows: + + +- In the case that AbilityA starts ServiceB, they are weakly associated. After AbilityA exits, ServiceB can still exist. + +- In the case that AbilityA connects to ServiceB, they are strongly associated. After AbilityA exits, ServiceB also exits. + + +Each type of ExtensionAbility has its own context. ServiceExtensionAbility has [ServiceExtensionContext](../reference/apis/js-apis-inner-application-serviceExtensionContext.md). In this document, the started ServiceExtensionAbility component is called the server, and the component that starts ServiceExtensionAbility is called the client. + + +This topic describes how to use ServiceExtensionAbility in the following scenarios: + + +- [Implementing a Background Service](#implementing-a-background-service) + +- [Starting a Background Service](#starting-a-background-service) + +- [Connecting to a Background Service](#connecting-to-a-background-service) + + +> **NOTE** +> - OpenHarmony does not support third-party applications in implementing ServiceExtensionAbility. If you want to implement transaction processing in the background, use background tasks. For details, see [Background Task](../task-management/background-task-overview.md). +> +> - UIAbility of a third-party application can connect to ServiceExtensionAbility provided by the system through the context. +> +> - Third-party applications can connect to ServiceExtensionAbility provided by the system only when they gain focus in the foreground. + + +## Implementing a Background Service + +This feature applies only to system applications. [ServiceExtensionAbility](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md) provides the callbacks **onCreate()**, **onRequest()**, **onConnect()**, **onDisconnect()**, and **onDestory()**. Override them as required. The following figure shows the lifecycle of ServiceExtensionAbility. + + **Figure 1** ServiceExtensionAbility lifecycle +![ServiceExtensionAbility-lifecycle](figures/ServiceExtensionAbility-lifecycle.png) + +- **onCreate** + + +This callback is triggered when a service is created for the first time. You can perform initialization operations, for example, registering a common event listener. + + > **NOTE** +> + > If a service has been created, starting it again does not trigger the **onCreate()** callback. + +- **onRequest** + + +This callback is triggered when another component calls the **startServiceExtensionAbility()** method to start the service. After being started, the service runs in the background. + +- **onConnect** + + +This callback is triggered when another component calls the **connectServiceExtensionAbility()** method to connect to the service. In this method, a remote proxy object (IRemoteObject) is returned, through which the client communicates with the server by means of RPC. + +- **onDisconnect** + + +This callback is triggered when a component calls the **disconnectServiceExtensionAbility()** method to disconnect from the service. + +- **onDestroy** + + This callback is triggered when the service is no longer used and the instance is ready for destruction. You can clear resources in this callback, for example, deregister the listener. + + +## How to Develop + +To implement a background service, manually create a ServiceExtensionAbility component in DevEco Studio. 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 **serviceextability**. + +2. In the **serviceextability** directory, right-click and choose **New > TypeScript File** to create a file named **ServiceExtAbility.ts**. + +3. Open the **ServiceExtAbility.ts** file, import the [RPC module](../reference/apis/js-apis-rpc.md), and reload the **onRemoteMessageRequest()** method to receive messages from the client and return the processing result to the client. **REQUEST_VALUE** is used to verify the service request code sent by the client. + + ```ts + import rpc from '@ohos.rpc'; + + const REQUEST_CODE = 99; + + class StubTest extends rpc.RemoteObject { + constructor(des) { + super(des); + } + + // Receive a message from the client and return the processing result to the client. + onRemoteMessageRequest(code, data, reply, option) { + if (code === REQUEST_CODE) { + // Receive data from the client. + // If the client calls data.writeInt() multiple times to write multiple pieces of data, the server can call data.readInt() multiple times to receive all the data. + let optFir = data.readInt(); + let optSec = data.readInt(); + // The server returns the data processing result to the client. + // In the example, the server receives two pieces of data and returns the sum of the two pieces of data to the client. + reply.writeInt(optFir + optSec); + } + return true; + } + + // Send messages to the client in synchronous or asynchronous mode. + sendRequest(code, data, reply, options) { + return null; + } + } + ``` + +4. In the **ServiceExtAbility.ts** file, add the dependency package for importing ServiceExtensionAbility. Customize a class that inherits from ServiceExtensionAbility and add the required lifecycle callbacks. + + ```ts + import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility'; + import rpc from '@ohos.rpc'; + + const TAG: string = "[Example].[Entry].[ServiceExtAbility]"; + const REQUEST_CODE = 99; + + class StubTest extends rpc.RemoteObject { + // ... + } + + export default class ServiceExtAbility extends ServiceExtensionAbility { + onCreate(want) { + console.info(TAG, `onCreate, want: ${want.abilityName}`); + } + + onRequest(want, startId) { + console.info(TAG, `onRequest, want: ${want.abilityName}`); + } + + onConnect(want) { + console.info(TAG, `onConnect, want: ${want.abilityName}`); + return new StubTest("test"); + } + + onDisconnect(want) { + console.info(TAG, `onDisconnect, want: ${want.abilityName}`); + } + + onDestroy() { + console.info(TAG, `onDestroy`); + } + } + ``` + +5. Register ServiceExtensionAbility in the [module.json5 file](../quick-start/module-configuration-file.md) corresponding to the **Module** project. Set **type** to **"service"** and **srcEntrance** to the code path of the ExtensionAbility component. + + ```json + { + "module": { + // ... + "extensionAbilities": [ + { + "name": "ServiceExtAbility", + "icon": "$media:icon", + "description": "service", + "type": "service", + "visible": true, + "srcEntrance": "./ets/serviceextability/ServiceExtAbility.ts" + } + ] + } + } + ``` + + +## Starting a Background Service + +This feature applies only to system applications. A system application uses the [startServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartserviceextensionability) method to start a background service. The [onRequest()](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityonrequest) callback is invoked, and the **Want** object passed by the caller is received through the callback. After the background service is started, its lifecycle is independent of that of the client. In other words, even if the client is destroyed, the background service can still run. Therefore, the background service must be stopped by calling [terminateSelf()](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself) when its work is complete. Alternatively, another component can call [stopServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstopserviceextensionability) to stop the background service. + +> **NOTE** +> +> [startServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartserviceextensionability), [stopServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstopserviceextensionability), and [terminateSelf()](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself) of ServiceExtensionContext are system APIs and cannot be called by third-party applications. + +1. Start a new ServiceExtensionAbility in a system application. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). + + ```ts + let want = { + "deviceId": "", + "bundleName": "com.example.myapplication", + "abilityName": "ServiceExtAbility" + }; + this.context.startServiceExtensionAbility(want).then(() => { + console.info('startServiceExtensionAbility success'); + }).catch((error) => { + console.info('startServiceExtensionAbility failed'); + }) + ``` + +2. Stop ServiceExtensionAbility in the system application. + + ```ts + let want = { + "deviceId": "", + "bundleName": "com.example.myapplication", + "abilityName": "ServiceExtAbility" + }; + this.context.stopServiceExtensionAbility(want).then(() => { + console.info('stopServiceExtensionAbility success'); + }).catch((error) => { + console.info('stopServiceExtensionAbility failed'); + }) + ``` + +3. ServiceExtensionAbility stops itself. + + ```ts + // this is the current ServiceExtensionAbility component. + this.context.terminateSelf().then(() => { + console.info('terminateSelf success'); + }).catch((error) => { + console.info('terminateSelf failed'); + }) + ``` + + +> **NOTE** +> +> Background services can run in the background for a long time. To minimize resource usage, destroy it in time when a background service finishes the task of the requester. A background service can be stopped in either of the following ways: +> +> - The background service calls the [terminateSelf()](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself) method to automatically stop itself. +> +> - Another component calls the [stopServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstopserviceextensionability) method to stop the background service. +> +> After either method is called, the system destroys the background service. + + +## Connecting to a Background Service + +Either a system application or a third-party application can connect to a service (service specified in the **Want** object) through [connectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextconnectserviceextensionability). The [onConnect()](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityonconnect) callback is invoked, and the **Want** object passed by the caller is received through the callback. In this way, a persistent connection is established. + +The ServiceExtensionAbility component returns an IRemoteObject in the **onConnect()** callback. Through this IRemoteObject, you can define communication interfaces for RPC interaction between the client and server. Multiple clients can connect to the same background service at the same time. After a client finishes the interaction, it must call [disconnectServiceExtensionAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextdisconnectserviceextensionability) to disconnect from the service. If all clients connected to a background service are disconnected, the system destroys the service. + +- Call **connectServiceExtensionAbility()** to establish a connection to a background service. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). + + ```ts + import rpc from '@ohos.rpc'; + + const REQUEST_CODE = 99; + let want = { + "deviceId": "", + "bundleName": "com.example.myapplication", + "abilityName": "ServiceExtAbility" + }; + let options = { + onConnect(elementName, remote) { + console.info('onConnect callback'); + if (remote === null) { + console.info(`onConnect remote is null`); + return; + } + let option = new rpc.MessageOption(); + let data = new rpc.MessageParcel(); + let reply = new rpc.MessageParcel(); + data.writeInt(100); + data.writeInt(200); + + // @param code Indicates the service request code sent by the client. + // @param data Indicates the {@link MessageParcel} object sent by the client. + // @param reply Indicates the response message object sent by the remote service. + // @param options Specifies whether the operation is synchronous or asynchronous. + // + // @return Returns {@code true} if the operation is successful; returns {@code false} otherwise. + remote.sendRequest(REQUEST_CODE, data, reply, option).then((ret) => { + let msg = reply.readInt(); + console.info(`sendRequest ret:${ret} msg:${msg}`); + }).catch((error) => { + console.info('sendRequest failed'); + }); + }, + onDisconnect(elementName) { + console.info('onDisconnect callback') + }, + onFailed(code) { + console.info('onFailed callback') + } + } + // The ID returned after the connection is set up must be saved. The ID will be passed for service disconnection. + let connectionId = this.context.connectServiceExtensionAbility(want, options); + ``` + +- Use **disconnectServiceExtensionAbility()** to disconnect from the background service. + + ```ts + let connectionId = 1 // ID returned when the service is connected through connectServiceExtensionAbility. + this.context.disconnectServiceExtensionAbility(connectionId).then((data) => { + console.info('disconnectServiceExtensionAbility success'); + }).catch((error) => { + console.error('disconnectServiceExtensionAbility failed'); + }) + ``` + + \ No newline at end of file diff --git a/en/application-dev/application-models/stage-model-development-overview.md b/en/application-dev/application-models/stage-model-development-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..139a27e2151cd3141bd7a0dd3a93c3c90929bf2a --- /dev/null +++ b/en/application-dev/application-models/stage-model-development-overview.md @@ -0,0 +1,43 @@ +# Stage Model Development Overview + + +## Basic Concepts + +The following figure shows the basic concepts used in the stage model. + +**Figure 1** Concepts used in the stage model +![stage-concepts](figures/stage-concepts.png) + +- [UIAbility component](uiability-overview.md) and [ExtensionAbility component](extensionability-overview.md) + + The stage model provides two types of application components: UIAbility and ExtensionAbility. Both have specific classes and support object-oriented development. They are the specific implementation of the abstract ability concept on the stage model. They are also units scheduled by the Ability Manager Service (AMS), which schedules their lifecycles as well. + + - UIAbility has the UI and is mainly used for user interaction. For example, with UIAbility, the Gallery application can display images in the liquid layout. After a user selects an image, it uses a new UI to display the image details. The user can touch the **Back** button to return to the liquid layout. The lifecycle of the UIAbility component contains the creation, destruction, foreground, and background states. Display-related states are exposed through WindowStage events. + + - ExtensionAbility is oriented to specific scenarios. You cannot derive directly from ExtensionAbility. Instead, use the derived classes of ExtensionAbility for your scenarios, such as FormExtensionAbility for widget scenarios, InputMethodExtensionAbility for input method scenarios, and WorkSchedulerExtensionAbility for Work Scheduled task scenarios. For example, to enable a user to create an application widget on the home screen, you must derive FormExtensionAbility, implement the callback functions, and configure the capability in the configuration file. The derived class instances are created by developers and their lifecycles are managed by the system. In the stage model, you must use the derived classes of ExtensionAbility to develop custom services based on your service scenarios. +- [WindowStage](../windowmanager/application-window-stage.md) + + Each UIAbility class instance is bound to a WindowStage class instance, which functions as the window manager in the application process. The WindowStage class instance contains a main window. That is, UIAbility holds a window through WindowStage, and this window provides an area for ArkUI to render. + +- [Context](application-context-stage.md) + + In the stage model, Context and its derived classes provide a variety of capabilities that can be called during the runtime. The UIAbility component and ExtensionAbility derived classes have different Context classes. These classes, which all inherit from the base class Context, provide different capabilities. + +- [AbilityStage](abilitystage.md) + + Each HAP of the Entry or Feature type has an AbilityStage class instance during the runtime. When the code in the HAP is loaded to the process for the first time, the system creates an AbilityStage class instance first. Each UIAbility class defined in the HAP is associated with this class instance after instantiation. Through this class instance, you can obtain the runtime information of the UIAbility instances in the HAP. + + +## How to Develop + +During application development based on the stage model, the following tasks are involved in the application model. + + **Table 1** Stage model development process + +| Task| Introduction| Guide| +| -------- | -------- | -------- | +| Application component development| Use the UIAbility and ExtensionAbility components of the stage model to develop applications.| - [Application- or Component-Level Configuration](application-component-configuration-stage.md)
- [UIAbility Component](uiability-overview.md)
- [ExtensionAbility Component](extensionability-overview.md)
- [AbilityStage Container Component](abilitystage.md)
- [Context](application-context-stage.md)
- [Component Startup Rules](component-startup-rules.md) | +| Inter-process communication (IPC)| Learn the process model and common IPC modes of the stage model.| - [Common Events](common-event-overview.md)
- [Background Services](background-services.md)| +| Inter-thread communication| Learn the thread model and common inter-thread communication modes of the stage model.| - [Emitter](itc-with-emitter.md)
- [Worker](itc-with-worker.md)| +| Mission management| Learn the basic concepts and typical scenarios of mission management in the stage model.| - [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) | +| Application configuration file| Learn the requirements for developing application configuration files in the stage model.| [Application Configuration File](config-file-stage.md) | diff --git a/en/application-dev/application-models/start-dataability.md b/en/application-dev/application-models/start-dataability.md new file mode 100644 index 0000000000000000000000000000000000000000..786a14f91007672e395ed5b754fbaeccb55b3770 --- /dev/null +++ b/en/application-dev/application-models/start-dataability.md @@ -0,0 +1,12 @@ +# Starting a DataAbility + + +When a DataAbility is started, a **DataAbilityHelper** object is obtained. The sample code for starting a DataAbility is as follows: + +```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' + +let urivar = "dataability:///com.ix.DataAbility" +let DAHelper = featureAbility.acquireDataAbilityHelper(urivar); +``` diff --git a/en/application-dev/application-models/start-local-pageability.md b/en/application-dev/application-models/start-local-pageability.md new file mode 100644 index 0000000000000000000000000000000000000000..d8344820078bcdd52c2d92b1b406dfabf9253a35 --- /dev/null +++ b/en/application-dev/application-models/start-local-pageability.md @@ -0,0 +1,35 @@ +# Starting a Local PageAbility + + +The capabilities related to the PageAbility are provided through the **featureAbility** class. For example, **startAbility()** in **featureAbility** is used to the PageAbility. + +**Table 1** featureAbility APIs + +| API| Description| +| -------- | -------- | +| startAbility(parameter: StartAbilityParameter) | Starts an ability.| +| startAbilityForResult(parameter: StartAbilityParameter) | Starts an ability and returns the execution result when the ability is terminated.| + + +The following code snippet shows how to explicitly start a PageAbility through **startAbility()**. The parameters passed in for starting an ability include **want**. For details about the **want** parameter as well as implicit startup and explicit startup, see [Want](want-fa.md). + +```ts +import featureAbility from '@ohos.ability.featureAbility' +(async () => { + try { + console.info('Begin to start ability') + let param = { + want: { + bundleName: "com.example.myapplication", + moduleName: "entry", + abilityName: "com.example.myapplication.MainAbility" + } + } + await featureAbility.startAbility(param) + console.info(`Start ability succeed`) + } + catch (error) { + console.error('Start ability failed with ' + error) + } +})() +``` diff --git a/en/application-dev/application-models/start-page.md b/en/application-dev/application-models/start-page.md new file mode 100644 index 0000000000000000000000000000000000000000..adf814355974157f579b809be6583d9b7a713d70 --- /dev/null +++ b/en/application-dev/application-models/start-page.md @@ -0,0 +1,142 @@ +# Starting a Specified Page + + +When the launch type of a PageAbility is set to **singleton** (default), the **onNewWant()** callback is triggered if the PageAbility is not started for the first time. For details about the launch type, see [PageAbility Launch Type](pageability-launch-type.md). In this case, you can use the **want** parameter to transfer startup information. For example, if you want to start a PageAbility with a specified page, pass the pages information in **parameters** of **want**. + + +In **app.ets** or **page** of the caller PageAbility, use **startAbility()** to start the PageAbility again, with the page information passed in the **uri** parameter in **want**. + +```ts +import featureAbility from '@ohos.ability.featureAbility'; + +async function restartAbility() { + let wantInfo = { + bundleName: "com.sample.MyApplication", + abilityName: "MainAbility", + parameters: { + page: "pages/second" + } + }; + featureAbility.startAbility({ + want: wantInfo + }).then((data) => { + console.info('restartAbility success.'); + }); +} +``` + + +Obtain the **want** parameter that contains the page information from the **onNewWant()** callback of the target PageAbility. + +```ts +export default { + onNewWant(want) { + globalThis.newWant = want + } +} +``` + + +Obtain the **want** parameter that contains the page information from the custom component of the target PageAbility and process the route based on the URI. + +```ts +import router from '@ohos.router' +@Entry +@Component +struct Index { + @State message: string = 'Router Page' + newWant = undefined + onPageShow() { + console.info('Index onPageShow') + let newWant = globalThis.newWant + if (newWant.hasOwnProperty("page")) { + router.push({ url: newWant.page }); + globalThis.newWant = undefined + } + } + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } +} +``` + + +When the launch type of a PageAbility is set to **standard** or when the PageAbility with the launch type set to **singleton** is started for the first time, you can use the **parameters** parameter in **want** to transfer the pages information and use the **startAbility()** method to start the PageAbility. For details about the launch type, see [PageAbility Launch Type](pageability-launch-type.md). The target PageAbility can use the **featureAbility.getWant()** method in **onCreate** to obtain the **want** parameter, and then call **router.push** to start a specified page. + + +When a user touches the button on the page of the caller PageAbility, the **startAbility()** method is called to start the target PageAbility. The **want** parameter in **startAbility()** carries the specified page information. + +```ts +import featureAbility from '@ohos.ability.featureAbility' +@Entry +@Component +struct Index { + @State message: string = 'Hello World' + + build() { + // ... + Button("startAbility") + .onClick(() => { + featureAbility.startAbility({ + want: { + bundleName: "com.exm.myapplication", + abilityName: "com.exm.myapplication.MainAbility", + parameters: { page: "pages/page1" } + } + }).then((data) => { + console.info("startAbility finish"); + }).catch((err) => { + console.info("startAbility failed errcode:" + err.code) + }) + }) + // ... + Button("page2") + .onClick(() => { + featureAbility.startAbility({ + want: { + bundleName: "com.exm.myapplication", + abilityName: "com.exm.myapplication.MainAbility", + parameters: { page: "pages/page2" } + } + }).then((data) => { + console.info("startAbility finish"); + }).catch((err) => { + console.info("startAbility failed errcode:" + err.code) + }) + }) + // ... + } +} +``` + + +In the **onCreate()** callback of the target PageAbility, use the **featureAbility.getWant()** method to obtain the **want** parameter, parse the parameter, and start the specified page. + +```ts +import featureAbility from '@ohos.ability.featureAbility'; +import router from '@ohos.router'; + +export default { + onCreate() { + featureAbility.getWant().then((want) => { + if (want.parameters.page) { + router.push({ + url: want.parameters.page + }) + } + }) + }, + onDestroy() { + // ... + }, +} +``` diff --git a/en/application-dev/application-models/start-pageability-from-stage.md b/en/application-dev/application-models/start-pageability-from-stage.md new file mode 100644 index 0000000000000000000000000000000000000000..f3a09f4af4613e2ad963b8e0aba1596ba6903c67 --- /dev/null +++ b/en/application-dev/application-models/start-pageability-from-stage.md @@ -0,0 +1,122 @@ +# Starting a PageAbility from the Stage Model + + +This topic describes how the two application components of the stage model start the PageAbility component of the FA model. + + +## UIAbility Starting a PageAbility + +A UIAbility starts a PageAbility in the same way as it starts another UIAbility. + +```ts +import UIAbility from '@ohos.app.ability.UIAbility' + +export default class MainAbility extends UIAbility { + onCreate(want, launchParam) { + console.info("MainAbility onCreate") + } + onDestroy() { + console.info("MainAbility onDestroy") + } + onWindowStageCreate(windowStage) { + console.info("MainAbility onWindowStageCreate") + windowStage.loadContent('pages/Index', (err, data) => { + // ... + }); + let want = { + bundleName: "com.ohos.fa", + abilityName: "MainAbility", + }; + this.context.startAbility(want).then(() => { + console.info('Start Ability successfully.'); + }).catch((error) => { + console.error("Ability failed: " + JSON.stringify(error)); + }); + } + onWindowStageDestroy() { + console.info("MainAbility onWindowStageDestroy") + } + onForeground() { + console.info("MainAbility onForeground") + } + onBackground() { + console.info("MainAbility onBackground") + } +} +``` + + +## UIAbility Accessing a PageAbility (startAbilityForResult) + +Different from **startAbility()**, **startAbilityForResult()** obtains the execution result when the PageAbility is destroyed. + +A UIAbility starts a PageAbility through **startAbilityForResult()** in the same way as it starts another UIAbility through **startAbilityForResult()**. + + +```ts +import UIAbility from '@ohos.app.ability.UIAbility' + +export default class MainAbility extends UIAbility { + onCreate(want, launchParam) { + console.info("MainAbility onCreate") + } + onDestroy() { + console.info("MainAbility onDestroy") + } + onWindowStageCreate(windowStage) { + console.info("MainAbility onWindowStageCreate") + windowStage.loadContent('pages/Index', (err, data) => { + // ... + }); + let want = { + bundleName: "com.ohos.fa", + abilityName: "MainAbility", + }; + this.context.startAbilityForResult(want).then((result) => { + console.info('Ability verify result: ' + JSON.stringify(result)); + }).catch((error) => { + console.error("Ability failed: " + JSON.stringify(error)); + }); + } + onWindowStageDestroy() { + console.info("MainAbility onWindowStageDestroy") + } + onForeground() { + console.info("MainAbility onForeground") + } + onBackground() { + console.info("MainAbility onBackground") + } +} +``` + + +## ExtensionAbility Starting a PageAbility + +The following uses the ServiceExtensionAbility component as an example to describe how an ExtensionAbility starts a PageAbility. A ServiceExtensionAbility starts a PageAbility in the same way as it starts a UIAbility. + + +```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: "MainAbility", + }; + this.context.startAbility(wantFA).then(() => { + console.info('Start Ability successfully.'); + }).catch((error) => { + console.error("Ability failed: " + JSON.stringify(error)); + }); + } +} +``` diff --git a/en/application-dev/application-models/start-remote-pageability.md b/en/application-dev/application-models/start-remote-pageability.md new file mode 100644 index 0000000000000000000000000000000000000000..54f370aa454019d3568c6048649d5fca4003d777 --- /dev/null +++ b/en/application-dev/application-models/start-remote-pageability.md @@ -0,0 +1,136 @@ +# Starting a Remote PageAbility + + +This feature applies only to system applications. The **startAbility()** method in the **featureAbility** class is used to start a remote PageAbility. + + +In addition to **'\@ohos.ability.featureAbility'**, you must import **'\@ohos.distributedHardware.deviceManager'**, which provides account-independent distributed device networking capabilities. Then you can use **getTrustedDeviceListSync** of the **DeviceManager** module to obtain the remote device ID and pass the remote device ID in the **want** parameter for starting the remote PageAbility. + + +The **getTrustedDeviceListSync** method is available only for system applications. Therefore, non-system applications cannot obtain remote device information or start a remote ability. + +**Table 1** featureAbility APIs + +| API| Description| +| -------- | -------- | +| startAbility(parameter: StartAbilityParameter)| Starts an ability.| +| startAbilityForResult(parameter: StartAbilityParameter)| Starts an ability and returns the execution result when the ability is terminated.| + +**Table 2** deviceManager APIs + +| API| Description| +| -------- | -------- | +| getTrustedDeviceListSync(): Array<DeviceInfo> | Obtains all trusted devices synchronously.| + + +In the cross-device scenario, before starting a remote PageAbility, you must request the data synchronization permission. The related APIs are described in the table below. + +**Table 3** AtManager APIs + +| API| Description| +| -------- | -------- | +| checkAccessToken(tokenID: number, permissionName: string): Promise<GrantStatus> | Verifies whether a permission is granted to an application. This API uses a promise to return the result **GrantStatus**. You are advised to use **checkAccessToken** instead of **verifyAccessToken**, which is deprecated since API version 9.| + +**Table 4** context APIs + +| API| Description| +| -------- | -------- | +| requestPermissionsFromUser(permissions: Array<string>, requestCode: number, resultCallback: AsyncCallback< PermissionRequestResult>): void | Requests permissions from the system. This API uses an asynchronous callback to return the result. For details, see [API Reference](../reference/apis/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7-1).| + + +The following sample code shows how to request the data synchronization permission from users: + +```ts +import abilityAccessCtrl from "@ohos.abilityAccessCtrl"; +import featureAbility from '@ohos.ability.featureAbility'; +import bundle from '@ohos.bundle.bundleManager'; +async function RequestPermission() { + console.info('RequestPermission begin'); + let array: Array = ["ohos.permission.DISTRIBUTED_DATASYNC"]; + let bundleFlag = 0; + let tokenID = undefined; + let userID = 100; + let appInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', bundleFlag, userID); + tokenID = appInfo.accessTokenId; + let atManager = abilityAccessCtrl.createAtManager(); + let requestPermissions: Array = []; + for (let i = 0;i < array.length; i++) { + let result = await atManager.verifyAccessToken(tokenID, array[i]); + console.info("checkAccessToken result:" + JSON.stringify(result)); + if (result != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { + requestPermissions.push(array[i]); + } + } + console.info("requestPermissions:" + JSON.stringify(requestPermissions)); + if (requestPermissions.length == 0 || requestPermissions == []) { + return; + } + let context = featureAbility.getContext(); + context.requestPermissionsFromUser(requestPermissions, 1, (error, data)=>{ + console.info("data:" + JSON.stringify(data)); + console.info("data requestCode:" + data.requestCode); + console.info("data permissions:" + data.permissions); + console.info("data authResults:" + data.authResults); + }); + console.info('RequestPermission end'); +} +``` + + +After obtaining the data synchronization permission, obtain the trusted device list for device selection. + + +The following sample code shows how to use **getTrustedDeviceListSync()** to obtain the trusted device list. + +```ts +import deviceManager from '@ohos.distributedHardware.deviceManager'; +let dmClass; +function getDeviceManager() { + deviceManager.createDeviceManager('ohos.example.distributedService', (error, dm) => { + if (error) { + console.info('create device manager failed with ' + error) + } + dmClass = dm; + }) +} +function getRemoteDeviceId() { + if (typeof dmClass === 'object' && dmClass != null) { + let list = dmClass.getTrustedDeviceListSync(); + if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') { + console.info("MainAbility onButtonClick getRemoteDeviceId err: list is null"); + return; + } + console.info("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId); + return list[0].deviceId; + } else { + console.info("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null"); + } +} +``` + + +After a device is selected, call **startAbility()** to explicitly start the remote PageAbility. + + +The following sample code shows how to explicitly start a remote PageAbility through **startAbility()**. + +```ts +import featureAbility from '@ohos.ability.featureAbility'; +function onStartRemoteAbility() { + console.info('onStartRemoteAbility begin'); + let params; + let wantValue = { + bundleName: 'ohos.samples.etsDemo', + abilityName: 'ohos.samples.etsDemo.RemoteAbility', + deviceId: getRemoteDeviceId(), // getRemoteDeviceId is defined in the preceding sample code. + parameters: params + }; + console.info('onStartRemoteAbility want=' + JSON.stringify(wantValue)); + featureAbility.startAbility({ + want: wantValue + }).then((data) => { + console.info('onStartRemoteAbility finished, ' + JSON.stringify(data)); + }); + console.info('onStartRemoteAbility end'); +} +``` diff --git a/en/application-dev/application-models/start-serviceability.md b/en/application-dev/application-models/start-serviceability.md new file mode 100644 index 0000000000000000000000000000000000000000..f3b0f6aeabc8a3ea35c1f6c390ec53239730443c --- /dev/null +++ b/en/application-dev/application-models/start-serviceability.md @@ -0,0 +1,35 @@ +# Starting a ServiceAbility + + +A ServiceAbility is started in the same way other abilities. You can start a ServiceAbility by calling **featureAbility.startAbility()** in the PageAbility or calling **particleAbility.startAbility()** in another ServiceAbility. For details about the startup rules, see [Component Startup Rules](component-startup-rules.md). + + +The following example shows how to use **startAbility()** to start the ServiceAbility whose **bundleName** is **com.example.myapplication** and **abilityName** is **ServiceAbility** in a PageAbility. When starting the ServiceAbility, concatenate the **bundleName** string before **abilityName**. + +```ts +import featureAbility from '@ohos.ability.featureAbility' + +async function startServiceAbility() { + try { + console.info('Begin to start ability') + let param = { + want: { + bundleName: "com.example.myapplication", + abilityName: "com.example.myapplication.ServiceAbility" + } + } + await featureAbility.startAbility(param) + console.info(`Start ability succeed`) + } catch (error) { + console.error('Start ability failed with ' + error) + } +} +``` + + +In the preceding code, **startAbility()** is used to start the ServiceAbility. + + +- If the ServiceAbility is not running, the system calls **onStart()** to initialize the ServiceAbility, and then calls **onCommand()** on the ServiceAbility. + +- If the ServiceAbility is running, the system directly calls **onCommand()** on the ServiceAbility. diff --git a/en/application-dev/application-models/start-uiability-from-fa.md b/en/application-dev/application-models/start-uiability-from-fa.md new file mode 100644 index 0000000000000000000000000000000000000000..fd2328f6471e045171312ea3909e652f68831c24 --- /dev/null +++ b/en/application-dev/application-models/start-uiability-from-fa.md @@ -0,0 +1,71 @@ +# Starting a UIAbility from the FA Model + + +This topic describes how the three application components of the FA model start the UIAbility component of the stage model. + + +## PageAbility Starting a UIAbility + +A PageAbility starts a UIAbility in the same way as it starts another PageAbility. + +```ts +import featureAbility from '@ohos.ability.featureAbility'; + +let parameter = { + "want": { + bundleName: "com.ohos.stage", + abilityName: "com.ohos.stage.MainAbility" + } +}; +featureAbility.startAbility(parameter).then((code) => { + console.info('Ability verify code: ' + JSON.stringify(code)); +}).catch((error) => { + console.error("Ability failed: " + JSON.stringify(error)); +}); +``` + + +## PageAbility Accessing a UIAbility (startAbilityForResult) + +Different from **startAbility()**, **startAbilityForResult()** obtains the execution result when the UIAbility is destroyed. + +A PageAbility starts a UIAbility through **startAbilityForResult()** in the same way as it starts another PageAbility through **startAbilityForResult()**. + + +```ts +import featureAbility from '@ohos.ability.featureAbility'; + +let parameter = { + "want": { + bundleName: "com.ohos.stage", + abilityName: "com.ohos.stage.MainAbility" + } +}; +featureAbility.startAbilityForResult(parameter).then((result) => { + console.info('Ability verify result: ' + JSON.stringify(result)); +}).catch((error) => { + console.error("Ability failed: " + JSON.stringify(error)); +}); +``` + + +## ServiceAbility or DataAbility Starting a UIAbility + +A ServiceAbility or DataAbility starts a UIAbility in the same way as it starts a PageAbility. + + +```ts +import particleAbility from '@ohos.ability.particleAbility'; + +let parameter = { + "want": { + bundleName: "com.ohos.stage", + abilityName: "com.ohos.stage.MainAbility" + } +}; +particleAbility.startAbility(parameter).then(() => { + console.info('Start Ability successfully.'); +}).catch((error) => { + console.error("Ability failed: " + JSON.stringify(error)); +}); +``` diff --git a/en/application-dev/application-models/stop-pageability.md b/en/application-dev/application-models/stop-pageability.md new file mode 100644 index 0000000000000000000000000000000000000000..7258a6b9e1311bcac602209c31710136a90dfb17 --- /dev/null +++ b/en/application-dev/application-models/stop-pageability.md @@ -0,0 +1,29 @@ +# Stopping a PageAbility + + +The **terminateSelf()** method in the **featureAbility** class is used to stop a PageAbility. + +**Table 1** featureAbility APIs + +| API| Description| +| -------- | -------- | +| terminateSelf() | Terminates this ability.| +| terminateSelfWithResult(parameter: AbilityResult) | Terminates this ability and returns the execution result.| + + +The following code snippet shows how to stop an ability. + +```ts +import featureAbility from '@ohos.ability.featureAbility' + +(async () => { + try { + console.info('Begin to terminateSelf') + await featureAbility.terminateSelf() + console.info('terminateSelf succeed') + } + catch (error) { + console.error('terminateSelf failed with ' + error) + } +})() +``` diff --git a/en/application-dev/application-models/storage-switch.md b/en/application-dev/application-models/storage-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..63486fe56fdf3605121711bee423066d9ac6e116 --- /dev/null +++ b/en/application-dev/application-models/storage-switch.md @@ -0,0 +1,13 @@ +# Storage Switching + + + | API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| +| -------- | -------- | -------- | +| GetStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Prefereces** to replace **Storage** and has redesigned the input parameters.| +| SetStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Prefereces** to replace **Storage** and has redesigned the input parameters.| +| ClearStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Prefereces** to replace **Storage** and has redesigned the input parameters.| +| DeleteStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Prefereces** to replace **Storage** and has redesigned the input parameters.| +| [static get(options: GetStorageOptions): void;](../reference/apis/js-apis-system-storage.md#storageget) | \@ohos.data.preferences.d.ts | [get(key: string, defValue: ValueType, callback: AsyncCallback<ValueType>): void;](../reference/apis/js-apis-data-preferences.md#get)
[get(key: string, defValue: ValueType): Promise<ValueType>;](../reference/apis/js-apis-data-preferences.md#get-1) | +| [static set(options: SetStorageOptions): void;](../reference/apis/js-apis-system-storage.md#storageset) | \@ohos.data.preferences.d.ts | [put(key: string, value: ValueType, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-data-preferences.md#put)
[put(key: string, value: ValueType): Promise<void>;](../reference/apis/js-apis-data-preferences.md#put-1) | +| [static clear(options?: ClearStorageOptions): void;](../reference/apis/js-apis-system-storage.md#storageclear) | \@ohos.data.preferences.d.ts | [clear(callback: AsyncCallback<void>): void;](../reference/apis/js-apis-data-preferences.md#clear)
[clear(): Promise<void>;](../reference/apis/js-apis-data-preferences.md#clear-1) | +| [static delete(options: DeleteStorageOptions): void;](../reference/apis/js-apis-system-storage.md#storagedelete) | \@ohos.data.preferences.d.ts | [delete(key: string, callback: AsyncCallback<void>): void;](../reference/apis/js-apis-data-preferences.md#delete)
[delete(key: string): Promise<void>;](../reference/apis/js-apis-data-preferences.md#delete-1) | diff --git a/en/application-dev/application-models/thread-model-fa.md b/en/application-dev/application-models/thread-model-fa.md new file mode 100644 index 0000000000000000000000000000000000000000..75401be69cba994ac631b6da997fb6ce2ea35a2f --- /dev/null +++ b/en/application-dev/application-models/thread-model-fa.md @@ -0,0 +1,28 @@ +# Thread Model (FA Model) + + +There are three types of threads in the FA model: + + +- Main thread + +Manages other threads. + +- Ability thread + - One ability thread for each ability. + - Distributes input events. + - Draws the UI. + - Invokes application code callbacks (event processing and lifecycle callbacks). + - Receives messages sent by the worker thread. + +- Worker thread + + Performs time-consuming operations + + +Based on the OpenHarmony thread model, different services run on different threads. Service interaction requires inter-thread communication. Threads can communicate with each other in Emitter or Worker mode. Emitter is mainly used for event synchronization between threads, and Worker is mainly used to execute time-consuming tasks. + + +> **NOTE** +> +> The FA model provides an independent thread for each ability. Emitter is mainly used for event synchronization within the ability thread, between a pair of ability threads, or between the ability thread and worker thread. diff --git a/en/application-dev/application-models/thread-model-stage.md b/en/application-dev/application-models/thread-model-stage.md new file mode 100644 index 0000000000000000000000000000000000000000..deaab60b7bd7549dcb96bc00d7896d5c67e5c5d2 --- /dev/null +++ b/en/application-dev/application-models/thread-model-stage.md @@ -0,0 +1,25 @@ +# Thread Model (Stage Model) + +For an OpenHarmony application, each process has a main thread to provide the following functionalities: + +- Manage other threads. + +- Enable multiple UIAbility components of the same application to share the same main thread. + +- Distribute input events. + +- Draw the UI. + +- Invoke application code callbacks (event processing and lifecycle callbacks). + +- Receive messages sent by the worker thread. + +In addition to the main thread, there is an independent thread, named worker. The worker thread is mainly used to perform time-consuming operations. It cannot directly operate the UI. The worker thread is created in the main thread and is independent of the main thread. A maximum of seven worker threads can be created. + +![thread-model-stage](figures/thread-model-stage.png) + +Based on the OpenHarmony thread model, different services run on different threads. Service interaction requires inter-thread communication. In the same process, threads can communicate with each other in Emitter or Worker mode. Emitter is mainly used for event synchronization between threads, and Worker is mainly used to execute time-consuming tasks. + +> **NOTE** +> +> The stage model provides only the main thread and worker thread. Emitter is mainly used for event synchronization within the main thread or between the main thread and worker thread. diff --git a/en/application-dev/application-models/uiability-data-sync-with-ui.md b/en/application-dev/application-models/uiability-data-sync-with-ui.md new file mode 100644 index 0000000000000000000000000000000000000000..981a9212892a8bc1a920ac929608685c3eafeb00 --- /dev/null +++ b/en/application-dev/application-models/uiability-data-sync-with-ui.md @@ -0,0 +1,320 @@ +# Data Synchronization Between UIAbility and UI + + +Based on the OpenHarmony application model, you can use any of the following ways to implement data synchronization between the UIAbility component and UI: + +- EventHub: The [base class Context](application-context-stage.md) provides the EventHub capability. It is implemented based on the publish/subscribe (pub/sub) pattern. Your application subscribes to an event and when the event occurs, receives a notification. + +- globalThis: It is a global object accessible in the ArkTS engine instance. +- LocalStorage/AppStorage: See [State Management of Application-Level Variables](../quick-start/arkts-state-mgmt-application-level.md). + + +## Using EventHub for Data Synchronization + +[EventHub](../reference/apis/js-apis-inner-application-eventHub.md) provides an event mechanism at the UIAbility or ExtensionAbility component level. Centered on the UIAbility or ExtensionAbility component, EventHub provides data communication capabilities for subscribing to, unsubscribing from, and triggering events. + +Before using EventHub, you must obtain an EventHub object, which is provided by the [base class Context](application-context-stage.md). This section uses EventHub as an example to describe how to implement data synchronization between the UIAbility component and the UI. + +1. Call [eventHub.on()](../reference/apis/js-apis-inner-application-eventHub.md#eventhubon) in the UIAbility in either of the following ways to register a custom event **event1**. + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility'; + + const TAG: string = '[Example].[Entry].[EntryAbility]'; + + export default class EntryAbility extends UIAbility { + func1(...data) { + // Trigger the event to complete the service operation. + console.info(TAG, '1. ' + JSON.stringify(data)); + } + + onCreate(want, launch) { + // Obtain an eventHub object. + let eventhub = this.context.eventHub; + // Subscribe to the event. + eventhub.on('event1', this.func1); + eventhub.on('event1', (...data) => { + // Trigger the event to complete the service operation. + console.info(TAG, '2. ' + JSON.stringify(data)); + }); + } + } + ``` + +2. Call [eventHub.emit()](../reference/apis/js-apis-inner-application-eventHub.md#eventhubemit) on the UI to trigger the event, and pass the parameters as required. + + ```ts + import common from '@ohos.app.ability.common'; + + @Entry + @Component + struct Index { + private context = getContext(this) as common.UIAbilityContext; + + eventHubFunc() { + // Trigger the event without parameters. + this.context.eventHub.emit('event1'); + // Trigger the event with one parameter. + this.context.eventHub.emit('event1', 1); + // Trigger the event with two parameters. + this.context.eventHub.emit('event1', 2, 'test'); + // You can design the parameters based on your service requirements. + } + + // Page display. + build() { + // ... + } + } + ``` + +3. Obtain the event trigger result from the subscription callback of UIAbility. The run log result is as follows: + + ```ts + [] + + [1] + + [2,'test'] + ``` + +4. After **event1** is used, you can call [eventHub.off()](../reference/apis/js-apis-inner-application-eventHub.md#eventhuboff) to unsubscribe from the event. + + ```ts + // context is the ability context of the UIAbility instance. + this.context.eventHub.off('event1'); + ``` + + +## Using globalThis for Data Synchronization + + +**globalThis** is a global object inside the [ArkTS engine instance](thread-model-stage.md) and can be used by UIAbility, ExtensionAbility, and Page inside the engine. Therefore, you can use **globalThis** for data synchronization. + + **Figure 1** Using globalThis for data synchronization +globalThis1 + + +The following describes how to use **globalThis** in three scenarios. Precautions are provided as well. + +- [Using globalThis Between UIAbility and Page](#using-globalthis-between-uiability-and-page) +- [Using globalThis Between UIAbility and UIAbility](##using-globalthis-between-uiability-and-uiability) +- [Use globalThis Between UIAbility and ExtensionAbility](#using-globalthis-between-uiability-and-extensionability) +- [Precautions for Using globalThis](#precautions-for-using-globalthis) + +### Using globalThis Between UIAbility and Page + +You can use **globalThis** to bind attributes or methods to implement data synchronization between the UIAbility component and UI. For example, if you bind the **want** parameter in the UIAbility component, you can use the **want** parameter information on the UI corresponding to the UIAbility component. + +1. When **startAbility()** is called to start a UIAbility instance, the **onCreate()** callback is invoked, and the **want** parameter can be passed in the callback. Therefore, you can bind the **want** parameter to **globalThis**. + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility' + + export default class EntryAbility extends UIAbility { + onCreate(want, launch) { + globalThis.entryAbilityWant = want; + // ... + } + + // ... + } + ``` + +2. Use **globalThis** on the UI to obtain the **want** parameter information. + + ```ts + let entryAbilityWant; + + @Entry + @Component + struct Index { + aboutToAppear() { + entryAbilityWant = globalThis.entryAbilityWant; + } + + // Page display. + build() { + // ... + } + } + ``` + + +### Using globalThis Between UIAbility and UIAbility + +To implement data synchronization between two UIAbility components in the same application, you can bind data to **globalThis**. For example, you can save data in **globalThis** in AbilityA and obtain the data from AbilityB. + +1. AbilityA stores a string and binds it to globalThis. + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility' + + export default class AbilityA extends UIAbility { + onCreate(want, launch) { + globalThis.entryAbilityStr = 'AbilityA'; // AbilityA stores the string "AbilityA" to globalThis. + // ... + } + } + ``` + +2. Obtain the data from AbilityB. + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility' + + export default class AbilityB extends UIAbility { + onCreate(want, launch) { + // AbilityB reads the name from globalThis and outputs it. + console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr); + // ... + } + } + ``` + + +### Using globalThis Between UIAbility and ExtensionAbility + +To implement data synchronization between the UIAbility and ExtensionAbility components in the same application, you can bind data to **globalThis**. For example, you can save data in **globalThis** in AbilityA and obtain the data from ServiceExtensionAbility. + +1. AbilityA stores a string and binds it to globalThis. + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility' + + export default class AbilityA extends UIAbility { + onCreate(want, launch) { + // AbilityA stores the string "AbilityA" to globalThis. + globalThis.entryAbilityStr = 'AbilityA'; + // ... + } + } + ``` + +2. Obtain the data from ExtensionAbility. + + ```ts + import Extension from '@ohos.app.ability.ServiceExtensionAbility' + + export default class ServiceExtAbility extends Extension { + onCreate(want) { + / / ServiceExtAbility reads name from globalThis and outputs it. + console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr); + // ... + } + } + ``` + + +### Precautions for Using globalThis + + **Figure 2** Precautions for globalThis +![globalThis2](figures/globalThis2.png) + +- In the stage model, all the UIAbility components in a process share one ArkTS engine instance. When using **globalThis**, do not store objects with the same name. For example, if AbilityA and AbilityB use **globalThis** to store two objects with the same name, the object stored earlier will be overwritten. + +- This problem does not occur in the FA model because each UIAbility component uses an independent engine. + +- The lifecycle of an object bound to **globalThis** is the same as that of the ArkTS engine instance. You are advised to assign the value **null** after using the object to minimize memory usage. + +The following provides an example to describe the object overwritten problem in the stage model. + +1. In the AbilityA file, [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) is stored in **globalThis**. + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility' + + export default class AbilityA extends UIAbility { + onCreate(want, launch) { + globalThis.context = this.context; // AbilityA stores the context in globalThis. + // ... + } + } + ``` + +2. Obtain and use [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) on the page of Ability A. After the AbilityA instance is used, switch it to the background. + + ```ts + @Entry + @Component + struct Index { + onPageShow() { + let ctx = globalThis.context; // Obtain the context from globalThis and use it. + let permissions = ['com.example.permission'] + ctx.requestPermissionsFromUser(permissions,(result) => { + // ... + }); + } + // Page display. + build() { + // ... + } + } + ``` + +3. In the AbilityB file, [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) is stored in **globalThis** and has the same name as that in the AbilityA file. + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility' + + export default class AbilityB extends UIAbility { + onCreate(want, launch) { + // AbilityB overwrites the context stored by AbilityA in globalThis. + globalThis.context = this.context; + // ... + } + } + ``` + +4. Obtain and use [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) on the page of Ability B. The obtained **globalThis.context** is the value of [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) in AbilityB. + + ```ts + @Entry + @Component + struct Index { + onPageShow() { + let ctx = globalThis.context; // Obtain the context from globalThis and use it. + let permissions = ['com.example.permission'] + ctx.requestPermissionsFromUser(permissions,(result) => { + console.info('requestPermissionsFromUser result:' + JSON.stringify(result)); + }); + } + // Page display. + build() { + // ... + } + } + ``` + +5. Switch the AbilityB instance to the background and switch the AbilityA instance to the foreground. In this case, AbilityA will not enter the **onCreate()** lifecycle again. + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility' + + export default class AbilityA extends UIAbility { + onCreate(want, launch) { // AbilityA will not enter this lifecycle. + globalThis.context = this.context; + // ... + } + } + ``` + +6. When the page of AbilityA is displayed, the obtained **globalThis.context** is [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) of AbilityB instead of AbilityA. An error occurs. + + ```ts + @Entry + @Component + struct Index { + onPageShow() { + let ctx = globalThis.context; // The context in globalThis is the context of AbilityB. + let permissions=['com.example.permission']; + ctx.requestPermissionsFromUser(permissions,(result) => { // Using this object causes a process breakdown. + console.info('requestPermissionsFromUser result:' + JSON.stringify(result)); + }); + } + // Page display. + build() { + // ... + } + } + ``` diff --git a/en/application-dev/application-models/uiability-intra-device-interaction.md b/en/application-dev/application-models/uiability-intra-device-interaction.md new file mode 100644 index 0000000000000000000000000000000000000000..db85dfdffb0a7d9e60e78151d6654fcdd4a973aa --- /dev/null +++ b/en/application-dev/application-models/uiability-intra-device-interaction.md @@ -0,0 +1,630 @@ +# Interaction Intra-Device Between UIAbility Components + + +UIAbility is the minimum unit that can be scheduled by the system. Jumping between functional modules in a device involves starting of specific UIAbility components, which belong to the same or a different application (for example, starting UIAbility of a third-party payment application). + + +This topic describes the UIAbility interaction modes in the following scenarios. For details about cross-device application component interaction, see [Inter-Device Application Component Interaction (Continuation)](inter-device-interaction-hop-overview.md). + + +- [Starting UIAbility in the Same Application](#starting-uiability-in-the-same-application) + +- [Starting UIAbility in the Same Application and Obtaining the Return Result](#starting-uiability-in-the-same-application-and-obtaining-the-return-result) + +- [Starting UIAbility of Another Application](#starting-uiability-of-another-application) + +- [Starting UIAbility of Another Application and Obtaining the Return Result](#starting-uiability-of-another-application-and-obtaining-the-return-result) + +- [Starting a Specified Page of UIAbility](#starting-a-specified-page-of-uiability) + +- [Using Ability Call to Implement UIAbility Interaction](#using-ability-call-to-implement-uiability-interaction) + + +## Starting UIAbility in the Same Application + +This scenario is possible when an application contains multiple UIAbility components. For example, in a payment application, you may need to start the payment UIAbility from the entry UIAbility. + +Assume that your application has two UIAbility components: EntryAbility and FuncAbility, either in the same module or different modules. You are required to start FuncAbility from EntryAbility. + +1. In EntryAbility, call **startAbility()** to start UIAbility. The [want](../reference/apis/js-apis-app-ability-want.md) parameter is the entry parameter for starting the UIAbility instance. In the **want** parameter, **bundleName** indicates the bundle name of the application to start; **abilityName** indicates the name of the UIAbility to start; **moduleName** is required only when the target UIAbility belongs to a different module; **parameters** is used to carry custom information. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). + + ```ts + let wantInfo = { + deviceId: '', // An empty deviceId indicates the local device. + bundleName: 'com.example.myapplication', + abilityName: 'FuncAbility', + moduleName: 'module1', // moduleName is optional. + parameters: {// Custom information. + info: 'From the Index page of EntryAbility', + }, + } + // context is the ability-level context of the initiator UIAbility. + this.context.startAbility(wantInfo).then(() => { + // ... + }).catch((err) => { + // ... + }) + ``` + +2. Use the FuncAbility lifecycle callback to receive the parameters passed from EntryAbility. + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility'; + import Window from '@ohos.window'; + + export default class FuncAbility extends UIAbility { + onCreate(want, launchParam) { + // Receive the parameters passed by the caller UIAbility. + let funcAbilityWant = want; + let info = funcAbilityWant?.parameters?.info; + // ... + } + } + ``` + +3. To stop the **UIAbility** instance after the FuncAbility service is complete, call **terminateSelf()** in FuncAbility. + + ```ts + // context is the ability context of the UIAbility instance to stop. + this.context.terminateSelf((err) => { + // ... + }); + ``` + + +## Starting UIAbility in the Same Application and Obtaining the Return Result + +When starting FuncAbility from EntryAbility, you want the result to be returned after the FuncAbility service is finished. For example, your application uses two independent UIAbility components to carry the entry and sign-in functionalities. After the sign-in operation is finished in the sign-in UIAbility, the sign-in result needs to be returned to the entry UIAbility. + +1. In EntryAbility, call **startAbilityForResult()** to start FuncAbility. Use **data** in the asynchronous callback to receive information returned after FuncAbility stops itself. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). + + ```ts + let wantInfo = { + deviceId: '', // An empty deviceId indicates the local device. + bundleName: 'com.example.myapplication', + abilityName: 'FuncAbility', + moduleName: 'module1', // moduleName is optional. + parameters: {// Custom information. + info: 'From the Index page of EntryAbility', + }, + } + // context is the ability-level context of the initiator UIAbility. + this.context.startAbilityForResult(wantInfo).then((data) => { + // ... + }).catch((err) => { + // ... + }) + ``` + +2. Call **terminateSelfWithResult()** to stop FuncAbility. Use the input parameter **abilityResult** to carry the information that FuncAbility needs to return to EntryAbility. + + ```ts + const RESULT_CODE: number = 1001; + let abilityResult = { + resultCode: RESULT_CODE, + want: { + bundleName: 'com.example.myapplication', + abilityName: 'FuncAbility', + moduleName: 'module1', + parameters: { + info: 'From the Index page of FuncAbility', + }, + }, + } + // context is the ability context of the callee UIAbility. + this.context.terminateSelfWithResult(abilityResult, (err) => { + // ... + }); + ``` + +3. After FuncAbility stops itself, EntryAbility uses the **startAbilityForResult()** method to receive the information returned by FuncAbility. The value of **RESULT_CODE** must be the same as the preceding value. + + ```ts + const RESULT_CODE: number = 1001; + + // ... + + // context is the ability-level context of the initiator UIAbility. + this.context.startAbilityForResult(want).then((data) => { + if (data?.resultCode === RESULT_CODE) { + // Parse the information returned by the callee UIAbility. + let info = data.want?.parameters?.info; + // ... + } + }).catch((err) => { + // ... + }) + ``` + + +## Starting UIAbility of Another Application + +Generally, the user only needs to do a common operation (for example, selecting a document application to view the document content) to start the UIAbility of another application. The [implicit Want launch mode](want-overview.md#types-of-want) is recommended. The system identifies a matched UIAbility and starts it based on the **want** parameter of the caller. + +There are two ways to start **UIAbility**: [explicit and implicit](want-overview.md). + +- Explicit Want launch: This mode is used to start a determined UIAbility component of an application. You need to set **bundleName** and **abilityName** of the target application in the **want** parameter. + +- Implicit Want launch: The user selects a UIAbility to start based on the matching conditions. That is, the UIAbility to start is not determined (the **abilityName** parameter is not specified). When the **startAbility()** method is called, the **want** parameter specifies a series of parameters such as [entities](../reference/apis/js-apis-ability-wantConstant.md#wantconstantentity) and [actions](../reference/apis/js-apis-ability-wantConstant.md#wantconstantaction). **entities** provides additional type information of the target UIAbility, such as the browser or video player. **actions** specifies the common operations to perform, such as viewing, sharing, and application details. Then the system analyzes the **want** parameter to find the right UIAbility to start. You usually do not know whether the target application is installed and what **bundleName** and **abilityName** of the target application are. Therefore, implicit Want launch is usually used to start the UIAbility of another application. + +This section describes how to start the UIAbility of another application through implicit Want. + +1. Install multiple document applications on your device. In the **module.json5** file of each UIAbility component, configure [entities](../reference/apis/js-apis-ability-wantConstant.md#wantconstantentity) and [actions](../reference/apis/js-apis-ability-wantConstant.md#wantconstantaction) under **skills**. + + ```json + { + "module": { + "abilities": [ + { + // ... + "skills": [ + { + "entities": [ + // ... + "entity.system.default" + ], + "actions": [ + // ... + "ohos.want.action.viewData" + ] + } + ] + } + ] + } + } + ``` + +2. Include **entities** and **actions** of the caller's **want** parameter into **entities** and **actions** under **skills** of the target UIAbility. After the system matches the UIAbility that meets the **entities** and **actions** information, a dialog box is displayed, showing the list of matched UIAbility instances for users to select. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). + + ```ts + let wantInfo = { + deviceId: '', // An empty deviceId indicates the local device. + // 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.default'], + } + + // context is the ability-level context of the initiator UIAbility. + this.context.startAbility(wantInfo).then(() => { + // ... + }).catch((err) => { + // ... + }) + ``` + + The following figure shows the effect. When you click **Open PDF**, a dialog box is displayed for you to select. + uiability-intra-device-interaction + +3. To stop the **UIAbility** instance after the document application is used, call **terminateSelf()**. + + ```ts + // context is the ability context of the UIAbility instance to stop. + this.context.terminateSelf((err) => { + // ... + }); + ``` + + +## Starting UIAbility of Another Application and Obtaining the Return Result + +If you want to obtain the return result when using implicit Want to start the UIAbility of another application, use the **startAbilityForResult()** method. An example scenario is that the main application needs to start a third-party payment application and obtain the payment result. + +1. In the **module.json5** file of the UIAbility corresponding to the payment application, set [entities](../reference/apis/js-apis-ability-wantConstant.md#wantconstantentity) and [actions](../reference/apis/js-apis-ability-wantConstant.md#wantconstantaction) under **skills**. + + ```json + { + "module": { + "abilities": [ + { + // ... + "skills": [ + { + "entities": [ + // ... + "entity.system.default" + ], + "actions": [ + // ... + "ohos.want.action.editData" + ] + } + ] + } + ] + } + } + ``` + +2. Call the **startAbilityForResult()** method to start the UIAbility of the payment application. Include **entities** and **actions** of the caller's **want** parameter into **entities** and **actions** under **skills** of the target UIAbility. Use **data** in the asynchronous callback to receive the information returned to the caller after the payment UIAbility stops itself. After the system matches the UIAbility that meets the **entities** and **actions** information, a dialog box is displayed, showing the list of matched UIAbility instances for users to select. + + ```ts + let wantInfo = { + deviceId: '', // An empty deviceId indicates the local device. + // Uncomment the line below if you want to implicitly query data only in the specific bundle. + // bundleName: 'com.example.myapplication', + action: 'ohos.want.action.editData', + // entities can be omitted. + entities: ['entity.system.default'], + } + + // context is the ability-level context of the initiator UIAbility. + this.context.startAbilityForResult(wantInfo).then((data) => { + // ... + }).catch((err) => { + // ... + }) + ``` + +3. After the payment is finished, call the **terminateSelfWithResult()** method to stop the payment UIAbility and return the **abilityResult** parameter. + + ```ts + const RESULT_CODE: number = 1001; + let abilityResult = { + resultCode: RESULT_CODE, + want: { + bundleName: 'com.example.myapplication', + abilityName: 'EntryAbility', + moduleName: 'entry', + parameters: { + payResult: 'OKay', + }, + }, + } + // context is the ability context of the callee UIAbility. + this.context.terminateSelfWithResult(abilityResult, (err) => { + // ... + }); + ``` + +4. Receive the information returned by the payment application in the callback of the **startAbilityForResult()** method. The value of **RESULT_CODE** must be the same as that returned by **terminateSelfWithResult()**. + + ```ts + const RESULT_CODE: number = 1001; + + let want = { + // Want parameter information. + }; + + // context is the ability-level context of the initiator UIAbility. + this.context.startAbilityForResult(want).then((data) => { + if (data?.resultCode === RESULT_CODE) { + // Parse the information returned by the callee UIAbility. + let payResult = data.want?.parameters?.payResult; + // ... + } + }).catch((err) => { + // ... + }) + ``` + + +## Starting a Specified Page of UIAbility + +A UIAbility component can have multiple pages. When it is started in different scenarios, different pages can be displayed. For example, when a user jumps from a page of a UIAbility component to another UIAbility, you want to start a specified page of the target UIAbility. This section describes how to specify a startup page and start the specified page when the target UIAbility is started for the first time or when the target UIAbility is not started for the first time. + + +### Specifying a Startup Page + +When the caller UIAbility starts another UIAbility, it usually needs to redirect to a specified page. For example, FuncAbility contains two pages: Index (corresponding to the home page) and Second (corresponding to function A page). You can configure the specified page URL in the **want** parameter by adding a custom parameter to **parameters** in **want**. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). + + +```ts +let wantInfo = { + deviceId: '', // An empty deviceId indicates the local device. + bundleName: 'com.example.myapplication', + abilityName: 'FuncAbility', + moduleName: 'module1', // moduleName is optional. + parameters: {// Custom parameter used to pass the page information. + router: 'funcA', + }, +} +// context is the ability-level context of the initiator UIAbility. +this.context.startAbility(wantInfo).then(() => { + // ... +}).catch((err) => { + // ... +}) +``` + + +### Starting a Page When the Target UIAbility Is Started for the First Time + +When the target UIAbility is started for the first time, in the **onWindowStageCreate()** callback of the target UIAbility, parse the **want** parameter passed by EntryAbility to obtain the URL of the page to be loaded, and pass the URL to the **windowStage.loadContent()** method. + + +```ts +import UIAbility from '@ohos.app.ability.UIAbility' +import Window from '@ohos.window' + +export default class FuncAbility extends UIAbility { + funcAbilityWant; + + onCreate(want, launchParam) { + // Receive the parameters passed by the caller UIAbility. + this.funcAbilityWant = want; + } + + onWindowStageCreate(windowStage: Window.WindowStage) { + // Main window is created. Set a main page for this ability. + let url = 'pages/Index'; + if (this.funcAbilityWant?.parameters?.router) { + if (this.funcAbilityWant.parameters.router === 'funA') { + url = 'pages/Second'; + } + } + windowStage.loadContent(url, (err, data) => { + // ... + }); + } +} +``` + + +### Starting a Page When the Target UIAbility Is Not Started for the First Time + +You start application A, and its home page is displayed. Then you return to the home screen and start application B. Now you need to start application A again from application B and have a specified page of application A displayed. An example scenario is as follows: When you open the home page of the SMS application and return to the home screen, the SMS application is in the opened state and its home page is displayed. Then you open the home page of the Contacts application, access user A's details page, and touch the SMS icon to send an SMS message to user A. The SMS application is started again and the sending page is displayed. + +![uiability_not_first_started](figures/uiability_not_first_started.png) + +In summary, when a UIAbility instance of application A has been created and the main page of the UIAbility instance is displayed, you need to start the UIAbility of application A from application B and have a different page displayed. + +1. In the target UIAbility, the **Index** page is loaded by default. The UIAbility instance has been created, and the **onNewWant()** callback rather than **onCreate()** and **onWindowStageCreate()** will be invoked. In the **onNewWant()** callback, parse the **want** parameter and bind it to the global variable **globalThis**. + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility' + + export default class FuncAbility extends UIAbility { + onNewWant(want, launchParam) { + // Receive the parameters passed by the caller UIAbility. + globalThis.funcAbilityWant = want; + // ... + } + } + ``` + +2. In FuncAbility, use the router module to implement redirection to the specified page on the **Index** page. Because the **Index** page of FuncAbility is active, the variable will not be declared again and the **aboutToAppear()** callback will not be triggered. Therefore, the page routing functionality can be implemented in the **onPageShow()** callback of the **Index** page. + + ```ts + import router from '@ohos.router'; + + @Entry + @Component + struct Index { + onPageShow() { + let funcAbilityWant = globalThis.funcAbilityWant; + let url2 = funcAbilityWant?.parameters?.router; + if (url2 && url2 === 'funcA') { + router.replaceUrl({ + url: 'pages/Second', + }) + } + } + + // Page display. + build() { + // ... + } + } + ``` + +> **NOTE** +> +> When the [launch type of the callee UIAbility](uiability-launch-type.md) is set to **standard**, a new instance is created each time the callee UIAbility is started. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback will not be invoked. + + +## Using Ability Call to Implement UIAbility Interaction + +This feature applies only to system applications. Ability call is an extension of the UIAbility capability. It enables the UIAbility to be invoked by and communicate with external systems. The UIAbility invoked can be either started in the foreground or created and run in the background. You can use the ability call to implement data sharing between two UIAbility instances (caller ability and callee ability) through IPC. + +The core API used for the ability call is **startAbilityByCall**, which differs from **startAbility** in the following ways: + +- **startAbilityByCall** supports ability launch in the foreground and background, whereas **startAbility** supports ability launch in the foreground only. + +- The caller ability can use the caller object returned by **startAbilityByCall** to communicate with the callee ability, but **startAbility** does not provide the communication capability. + +Ability call is usually used in the following scenarios: + +- Communicating with the callee ability + +- Starting the callee ability in the background + +**Table 1** Terms used in the ability call + +| **Term**| Description| +| -------- | -------- | +| CallerAbility | UIAbility that triggers the ability call.| +| CalleeAbility | UIAbility invoked by the ability call.| +| Caller | Object returned by **startAbilityByCall** and used by the caller ability to communicate with the callee ability.| +| Callee | Object held by the callee ability to communicate with the caller ability.| + +The following figure shows the ability call process. + +Figure 1 Ability call process +call + +- The caller ability uses **startAbilityByCall** to obtain a caller object and uses **call()** of the caller object to send data to the callee ability. + +- The 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. + +> **NOTE** +> 1. Currently, only system applications can use the ability call. +> +> 2. The launch type of the callee ability must be **singleton**. +> +> 3. Both local (intra-device) and cross-device ability calls are supported. The following describes how to initiate a local call. For details about how to initiate a cross-device ability call, see [Using Cross-Device Ability Call](hop-multi-device-collaboration.md#using-cross-device-ability-call). + + +### Available APIs + +The following table describes the main APIs used for the ability call. For details, see [AbilityContext](../reference/apis/js-apis-app-ability-uiAbility.md#caller). + + **Table 2** Ability call APIs + +| API| Description| +| -------- | -------- | +| startAbilityByCall(want: Want): Promise<Caller> | Starts a UIAbility in the foreground (through the **want** configuration) or background (default) and obtains the caller object for communication with the UIAbility. For details, see [AbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilitybycall) or [ServiceExtensionContext](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartabilitybycall).| +| on(method: string, callback: CalleeCallBack): void | Callback invoked when the callee ability registers a method.| +| 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.| +| callWithResult(method: string, data: rpc.Sequenceable): Promise<rpc.MessageParcel> | Sends agreed sequenceable data to the callee ability and obtains the agreed sequenceable data returned by the callee ability.| +| release(): void | Releases the caller object.| +| on(type: "release", callback: OnReleaseCallback): void | Callback invoked when the caller object is released.| + +The implementation of using the ability call for UIAbility interaction involves two parts. + +- [Creating a Callee Ability](#creating-a-callee-ability) + +- [Accessing the Callee Ability](#accessing-the-callee-ability) + + +### Creating a Callee Ability + +For the callee ability, implement the callback to receive data and the methods to marshal and unmarshal data. When data needs to be received, use **on()** to register a listener. When data does not need to be received, use **off()** to deregister the listener. + +1. Configure the ability launch type. + + +Set **launchType** of the callee ability to **singleton** in the **module.json5** file. + +| JSON Field| Description| +| -------- | -------- | +| "launchType" | Ability launch type. Set this parameter to **singleton**.| + +An example of the ability configuration is as follows: + + + ```json + "abilities":[{ + "name": ".CalleeAbility", + "srcEntrance": "./ets/CalleeAbility/CalleeAbility.ts", + "launchType": "singleton", + "description": "$string:CalleeAbility_desc", + "icon": "$media:icon", + "label": "$string:CalleeAbility_label", + "visible": true + }] + ``` + +2. Import the **UIAbility** module. + + ```ts + import Ability from '@ohos.app.ability.UIAbility'; + ``` + +3. Define the agreed sequenceable data. + + The data formats sent and received by the caller and callee abilities must be consistent. In the following example, the data formats are number and string. + + + ```ts + export default class MySequenceable { + num: number = 0 + str: string = "" + + constructor(num, string) { + this.num = num + this.str = string + } + + marshalling(messageParcel) { + messageParcel.writeInt(this.num) + messageParcel.writeString(this.str) + return true + } + + unmarshalling(messageParcel) { + this.num = messageParcel.readInt() + this.str = messageParcel.readString() + return true + } + } + ``` + +4. Implement **Callee.on** and **Callee.off**. + + The time to register a listener for the callee ability depends on your application. The data sent and received before the listener is registered and that after the listener is deregistered are not processed. In the following example, the **MSG_SEND_METHOD** listener is registered in **onCreate** of the ability and deregistered in **onDestroy**. After receiving sequenceable data, the application processes the data and returns the data result. You need to implement processing based on service requirements. The sample code is as follows: + + + ```ts + const TAG: string = '[CalleeAbility]'; + const MSG_SEND_METHOD: string = 'CallSendMsg'; + + function sendMsgCallback(data) { + console.info('CalleeSortFunc called'); + + // Obtain the sequenceable data sent by the caller ability. + let receivedData = new MySequenceable(0, ''); + data.readSequenceable(receivedData); + console.info(`receiveData[${receivedData.num}, ${receivedData.str}]`); + + // Process the data. + // Return the sequenceable data result to the caller ability. + return new MySequenceable(receivedData.num + 1, `send ${receivedData.str} succeed`); + } + + export default class CalleeAbility extends Ability { + onCreate(want, launchParam) { + try { + this.callee.on(MSG_SEND_METHOD, sendMsgCallback); + } catch (error) { + console.info(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`); + } + } + + onDestroy() { + try { + this.callee.off(MSG_SEND_METHOD); + } catch (error) { + console.error(TAG, `${MSG_SEND_METHOD} unregister failed with error ${JSON.stringify(error)}`); + } + } + } + ``` + + +### Accessing the Callee Ability + +1. Import the **UIAbility** module. + + ```ts + import Ability from '@ohos.app.ability.UIAbility'; + ``` + +2. Obtain the caller interface. + + + The **context** attribute of the ability implements **startAbilityByCall** to obtain the caller object for communication. The following example uses **this.context** to obtain the **context** attribute of the ability, uses **startAbilityByCall** to start the callee ability, obtain the caller object, and register the **onRelease** listener of the caller ability. You need to implement processing based on service requirements. + + ```ts + // Register the onRelease() listener of the caller ability. + private regOnRelease(caller) { + try { + caller.on("release", (msg) => { + console.info(`caller onRelease is called ${msg}`); + }) + console.info('caller register OnRelease succeed'); + } catch (error) { + console.info(`caller register OnRelease failed with ${error}`); + } + } + + async onButtonGetCaller() { + try { + this.caller = await context.startAbilityByCall({ + bundleName: 'com.samples.CallApplication', + abilityName: 'CalleeAbility' + }) + if (this.caller === undefined) { + console.info('get caller failed') + return + } + console.info('get caller success') + this.regOnRelease(this.caller) + } catch (error) { + console.info(`get caller failed with ${error}`) + } + } + ``` diff --git a/en/application-dev/application-models/uiability-launch-type.md b/en/application-dev/application-models/uiability-launch-type.md new file mode 100644 index 0000000000000000000000000000000000000000..c64d7fb3ffc0e3fa31741924439998118449068a --- /dev/null +++ b/en/application-dev/application-models/uiability-launch-type.md @@ -0,0 +1,158 @@ +# UIAbility Component Launch Type + + +The launch type of the UIAbility component refers to the state of the UIAbility instance at startup. The system provides three launch types: + + +- [Singleton](#singleton) + +- [Standard](#standard) + +- [Specified](#specified) + + +## Singleton + +**singleton** is the default launch type. + +Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, if a UIAbility instance of this type already exists in the application process, the instance is reused. Therefore, only one UIAbility instance of this type exists in the system, that is, displayed in **Recents**. + +**Figure 1** Demonstration effect in singleton mode +uiability-launch-type1 + +> **NOTE** +> +> Assume that the application already has a UIAbility instance created, and the launch type of the UIAbility instance is set to **singleton**. If [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called again to start the UIAbility instance, the original UIAbility instance is started, and no new UIAbility instance is created. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback is invoked, but the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks are not. + +To use the singleton mode, set **launchType** in the [module.json5 configuration file](../quick-start/module-configuration-file.md) to **singleton**. + + +```json +{ + "module": { + // ... + "abilities": [ + { + "launchType": "singleton", + // ... + } + ] + } +} +``` + + +## Standard + +In standard mode, each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, a new UIAbility instance of this type is created in the application process. Multiple UIAbility instances of this type are displayed in **Recents**. + +**Figure 2** Demonstration effect in standard mode +standard-mode + +To use the standard mode, set **launchType** in the [module.json5 configuration file](../quick-start/module-configuration-file.md) to **standard**. + + +```json +{ + "module": { + // ... + "abilities": [ + { + "launchType": "standard", + // ... + } + ] + } +} +``` + + +## Specified + +The **specified** mode is used in some special scenarios. For example, in a document application, you want a document instance to be created each time you create a document, but you want to use the same document instance when you repeatedly open an existing document. + +**Figure 3** Demonstration effect in specified mode +uiability-launch-type2 + +For example, there are EntryAbility and SpecifiedAbility, and the launch type of SpecifiedAbility is set to **specified**. You are required to start SpecifiedAbility from EntryAbility. + +1. In SpecifiedAbility, set the **launchType** field in the [module.json5 configuration file](../quick-start/module-configuration-file.md) to **specified**. + + ```json + { + "module": { + // ... + "abilities": [ + { + "launchType": "specified", + // ... + } + ] + } + } + ``` + +2. Before a UIAbility instance is created, you can create a unique string key for the instance. The key is bound to the UIAbility instance when it is created. Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, the application is asked which UIAbility instance is used to respond to the [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) request. + In EntryAbility, add a custom parameter, for example, **instanceKey**, to the **want** parameter in [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to distinguish the UIAbility instances. + + ```ts + // Configure an independent key for each UIAbility instance. + // For example, in the document usage scenario, use the document path as the key. + function getInstance() { + // ... + } + + let want = { + deviceId: '', // An empty deviceId indicates the local device. + bundleName: 'com.example.myapplication', + abilityName: 'SpecifiedAbility', + moduleName: 'module1', // moduleName is optional. + parameters: {// Custom information. + instanceKey: getInstance(), + }, + } + // context is the ability-level context of the initiator UIAbility. + this.context.startAbility(want).then(() => { + // ... + }).catch((err) => { + // ... + }) + ``` + +3. During running, the internal service of UIAbility determines whether to create multiple instances. If the key is matched, the UIAbility instance bound to the key is started. Otherwise, a new UIAbility instance is created. + The launch type of SpecifiedAbility is set to **specified**. Before SpecifiedAbility is started, the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback of the corresponding AbilityStage instance is invoked to parse the input **want** parameter and obtain the custom parameter **instanceKey**. A string key identifier is returned through the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback of the AbilityStage instance. [If the returned key corresponds to a started UIAbility instance](mission-management-launch-type.md#fig14520125175314), that UIAbility instance is switched to the foreground and gains focus again. Otherwise, a new instance is created and started. + + ```ts + import AbilityStage from '@ohos.app.ability.AbilityStage'; + + export default class MyAbilityStage extends AbilityStage { + onAcceptWant(want): string { + // In the AbilityStage instance of the callee, a key value corresponding to a UIAbility instance is returned for UIAbility whose launch type is specified. + // In this example, SpecifiedAbility of module1 is returned. + if (want.abilityName === 'SpecifiedAbility') { + // The returned string key is a custom string. + return `SpecifiedAbilityInstance_${want.parameters.instanceKey}`; + } + + return ''; + } + } + ``` + + > **NOTE** + > + > 1. Assume that the application already has a UIAbility instance created, and the launch type of the UIAbility instance is set to **specified**. If [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called again to start the UIAbility instance, and the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback of [AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md) matches a created UIAbility instance, the original UIAbility instance is started, and no new UIAbility instance is created. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback is invoked, but the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks are not. + > 2. AbilityStage is not automatically generated in the default project of DevEco Studio. For details about how to create an AbilityStage file, see [AbilityStage Component Container](abilitystage.md). + + For example, in the document application, different key values are bound to different document instances. Each time a document is created, a new key value (for example, file path) is passed, and a new UIAbility instance is created when UIAbility is started in AbilityStage. However, when you open an existing document, the same UIAbility instance is started again in AbilityStage. + + The following steps are used as an example. + 1. Open file A. A UIAbility instance, for example, UIAbility instance 1, is started. + + 2. Close the process of file A in **Recents**. UIAbility instance 1 is destroyed. Return to the home screen and open file A again. A new UIAbility instance is started, for example, UIAbility instance 2. + + 3. Return to the home screen and open file B. A new UIAbility instance is started, for example, UIAbility instance 3. + + 4. Return to the home screen and open file A again. UIAbility instance 2 is started. + + \ No newline at end of file diff --git a/en/application-dev/application-models/uiability-lifecycle.md b/en/application-dev/application-models/uiability-lifecycle.md new file mode 100644 index 0000000000000000000000000000000000000000..b530a7bda5c4f3c4fe0dd2eb96d53991083a5ff4 --- /dev/null +++ b/en/application-dev/application-models/uiability-lifecycle.md @@ -0,0 +1,147 @@ +# UIAbility Component Lifecycle + + +## Overview + +When a user opens, switches, and returns to an application, the UIAbility instances in the application transit in their different states. The UIAbility class provides a series of callbacks. Through these callbacks, you can know the state changes of the UIAbility instance, for example, being created or destroyed, or running in the foreground or background. + +The lifecycle of UIAbility has four states: **Create**, **Foreground**, **Background**, and **Destroy**, as shown in the figure below. + + **Figure 1** UIAbility lifecycle states +Ability-Life-Cycle + + +## Description of Lifecycle States + + +### Create + +The **Create** state is triggered when the UIAbility instance is created during application loading. The system invokes the **onCreate()** callback. In this callback, you can perform application initialization operations, for example, defining variables or loading resources. + + +```ts +import UIAbility from '@ohos.app.ability.UIAbility'; +import Window from '@ohos.window'; + +export default class EntryAbility extends UIAbility { + onCreate(want, launchParam) { + // Initialize the application. + } + // ... +} +``` + + +### WindowStageCreate and WindowStageDestory + +After the UIAbility instance is created but before it enters the **Foreground** state, the system creates a WindowStage instance and triggers the **onWindowStageCreate()** callback. You can set UI loading and WindowStage event subscription in the callback. + + **Figure 2** WindowStageCreate and WindowStageDestory +Ability-Life-Cycle-WindowStage + +In the **onWindowStageCreate()** callback, use [loadContent()](../reference/apis/js-apis-window.md#loadcontent9-2) to set the page to be loaded, and call [on('windowStageEvent')](../reference/apis/js-apis-window.md#onwindowstageevent9) to subscribe to [WindowStage events](../reference/apis/js-apis-window.md#windowstageeventtype9), for example, having or losing focus, or becoming visible or invisible. + +```ts +import UIAbility from '@ohos.app.ability.UIAbility'; +import Window from '@ohos.window'; + +export default class EntryAbility extends UIAbility { + // ... + + onWindowStageCreate(windowStage: Window.WindowStage) { + // Subscribe to the WindowStage events (having or losing focus, or becoming visible or invisible). + try { + windowStage.on('windowStageEvent', (data) => { + console.info('Succeeded in enabling the listener for window stage event changes. Data: ' + + JSON.stringify(data)); + }); + } catch (exception) { + console.error('Failed to enable the listener for window stage event changes. Cause:' + + JSON.stringify(exception)); + }; + + // Set the UI loading. + windowStage.loadContent('pages/Index', (err, data) => { + // ... + }); + } +} +``` + +> **NOTE** +> +> For details about how to use WindowStage, see [Window Development](../windowmanager/application-window-stage.md). + +Before the UIAbility instance is destroyed, the **onWindowStageDestroy()** callback is invoked to release UI resources. In this callback, you can unsubscribe from the WindowStage events. + + +```ts +import UIAbility from '@ohos.app.ability.UIAbility'; +import Window from '@ohos.window'; + +export default class EntryAbility extends UIAbility { + // ... + + onWindowStageDestroy() { + // Release UI resources. + // Unsubscribe from the WindowStage events such as having or losing focus in the onWindowStageDestroy() callback. + try { + windowStage.off('windowStageEvent'); + } catch (exception) { + console.error('Failed to disable the listener for window stage event changes. Cause:' + + JSON.stringify(exception)); + }; + } +} +``` + + +### Foreground and Background + +The **Foreground** and **Background** states are triggered when the UIAbility instance is switched to the foreground and background respectively. They correspond to the **onForeground()** and **onBackground()** callbacks. + +The **onForeground()** callback is triggered before the UI of the UIAbility instance becomes visible, for example, when the UIAbility instance is switched to the foreground. In this callback, you can apply for resources required by the system or re-apply for resources that have been released in the **onBackground()** callback. + +The **onBackground()** callback is triggered after the UI of the UIAbility component is completely invisible, for example, when the UIAbility instance is switched to the background. In this callback, you can release useless resources or perform time-consuming operations such as saving the status. + +For example, an application needs to use positioning, and the application has requested the positioning permission from the user. Before the UI is displayed, you can enable positioning in the **onForeground()** callback to obtain the location information. + +When the application is switched to the background, you can disable positioning in the **onBackground()** callback to reduce system resource consumption. + + +```ts +import UIAbility from '@ohos.app.ability.UIAbility'; + +export default class EntryAbility extends UIAbility { + // ... + + onForeground() { + // Apply for the resources required by the system or re-apply for the resources released in onBackground(). + } + + onBackground() { + // Release useless resources when the UI is invisible, or perform time-consuming operations in this callback, + // for example, saving the status. + } +} +``` + + +### Destroy + +The **Destroy** state is triggered when the UIAbility instance is destroyed. You can perform operations such as releasing system resources and saving data in the **onDestroy()** callback. + +The UIAbility instance is destroyed when **terminateSelf()** is called or the user closes the instance in **Recents**. + +```ts +import UIAbility from '@ohos.app.ability.UIAbility'; +import Window from '@ohos.window'; + +export default class EntryAbility extends UIAbility { + // ... + + onDestroy() { + // Release system resources and save data. + } +} +``` diff --git a/en/application-dev/application-models/uiability-overview.md b/en/application-dev/application-models/uiability-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..ec26d2ca9b360259d7f7c00c37cba53bd5db8756 --- /dev/null +++ b/en/application-dev/application-models/uiability-overview.md @@ -0,0 +1,40 @@ +# UIAbility Component Overview + + +## Overview + +UIAbility has the UI and is mainly used for user interaction. + +UIAbility is the basic unit scheduled by the system and provides a window for applications to draw UIs. A UIAbility component can implement a functional module through multiple pages. Each UIAbility component instance corresponds to a mission in **Recents**. + + +## Privacy Statement Configuration + +To enable an application to properly use a UIAbility component, declare the UIAbility name, entry, and tags under [abilities](../quick-start/module-configuration-file.md#abilities) in the [module.json5 configuration file](../quick-start/module-configuration-file.md). + + +```json +{ + "module": { + // ... + "abilities": [ + { + "name": "EntryAbility", // Name of the UIAbility component. + "srcEntrance": "./ets/entryability/EntryAbility.ts", // Code path of the UIAbility component. + "description": "$string:EntryAbility_desc", // Description of the UIAbility component. + "icon": "$media:icon", // Icon of the UIAbility component. + "label": "$string:EntryAbility_label", // Label of the UIAbility component. + "startWindowIcon": "$media:icon", // Index of the icon resource file. + "startWindowBackground": "$color:start_window_background", // Index of the background color resource file. + // ... + } + ] + } +} +``` + +> **NOTE** +> +> For the ability composition, see [Adding an Ability to a Module](https://developer.harmonyos.com/en/docs/documentation/doc-guides-V3/ohos-adding-ability-0000001218280664-V3). + + \ No newline at end of file diff --git a/en/application-dev/application-models/uiability-usage.md b/en/application-dev/application-models/uiability-usage.md new file mode 100644 index 0000000000000000000000000000000000000000..ccd80625f460ea704f689f9b7dfa83f6b42fa47f --- /dev/null +++ b/en/application-dev/application-models/uiability-usage.md @@ -0,0 +1,99 @@ +# UIAbility Component Usage + + +When using the UIAbility component, you must specify a startup page and obtain the context, [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md). + + +## Specifying the Startup Page of UIAbility + +If no startup page is specified, a white screen occurs after the application is started. You can use **loadContent()** of [WindowStage](../reference/apis/js-apis-window.md#windowstage9) to set the startup page in the **onWindowStageCreate()** callback of the UIAbility instance. + + +```ts +import UIAbility from '@ohos.app.ability.UIAbility'; +import Window from '@ohos.window'; + +export default class EntryAbility extends UIAbility { + onWindowStageCreate(windowStage: Window.WindowStage) { + // Main window is created. Set a main page for this ability. + windowStage.loadContent('pages/Index', (err, data) => { + // ... + }); + } + + // ... +} +``` + +> **NOTE** +> +> When you create UIAbility in DevEco Studio, the UIAbility instance loads the **Index** page by default. Therefore, you only need to replace the **Index** page path with the required startup page path. + + +## Obtaining the Context of UIAbility + +The UIAbility class has its own context, which is an instance of the [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) class. The UIAbilityContext class has attributes such as **abilityInfo** and **currentHapModuleInfo**. UIAbilityContext can be used to obtain the UIAbility configuration information, such as the bundle code path, bundle name, ability name, and environment status required by the application. It can also be used to obtain methods to operate the UIAbility instance, such as **startAbility()**, **connectServiceExtensionAbility()**, and **terminateSelf()**. + +- You can use **this.context** to obtain the context of a UIAbility instance. + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility'; + + export default class EntryAbility extends UIAbility { + onCreate(want, launchParam) { + // Obtain the context of the UIAbility instance. + let context = this.context; + + // ... + } + } + ``` + +- Import the context module and define the **context** variable in the component. + + ```ts + import common from '@ohos.app.ability.common'; + + @Entry + @Component + struct Index { + private context = getContext(this) as common.UIAbilityContext; + + startAbilityTest() { + let want = { + // Want parameter information. + }; + this.context.startAbility(want); + } + + // Page display. + build() { + // ... + } + } + ``` + + You can also define variables after importing the context module but before using [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md). + + + ```ts + import common from '@ohos.app.ability.common'; + + @Entry + @Component + struct Index { + + startAbilityTest() { + let context = getContext(this) as common.UIAbilityContext; + let want = { + // Want parameter information. + }; + context.startAbility(want); + } + + // Page display. + build() { + // ... + } + } + ``` diff --git a/en/application-dev/application-models/want-fa.md b/en/application-dev/application-models/want-fa.md new file mode 100644 index 0000000000000000000000000000000000000000..5ef82daf1f6ac353200131fd8195cbea35725e3c --- /dev/null +++ b/en/application-dev/application-models/want-fa.md @@ -0,0 +1,4 @@ +# Want (FA Model) + + +For details, see "[Want](want-overview.md)" in the stage model. diff --git a/en/application-dev/application-models/want-overview.md b/en/application-dev/application-models/want-overview.md new file mode 100644 index 0000000000000000000000000000000000000000..784f190ad6b23a85c60995c44babdc8dd34d576d --- /dev/null +++ b/en/application-dev/application-models/want-overview.md @@ -0,0 +1,51 @@ +# Want Overview + + +## Definition and Usage of Want + +[Want](../reference/apis/js-apis-app-ability-want.md) is used as the carrier to transfer information between application components. It is used as a parameter of **startAbility()** to specify the startup target and information that needs to be carried during startup, for example, **bundleName** and **abilityName**, which respectively indicate the bundle name of the target ability and the ability name in the bundle. For example, when UIAbilityA starts UIAbilityB and needs to transfer some data to UIAbilityB, it can use Want to transfer the data. + +**Figure 1** Want usage +usage-of-want + + +## Types of Want + +- **Explicit Want**: A type of Want with **abilityName** and **bundleName** specified when starting an ability. + When there is an explicit object to process the request, the target ability can be started by specifying the bundle name and ability name in Want. Explicit Want is usually used to start a known ability. + + ```ts + let wantInfo = { + deviceId: '', // An empty deviceId indicates the local device. + bundleName: 'com.example.myapplication', + abilityName: 'FuncAbility', + } + ``` + +- **Implicit Want**: A type of Want with **abilityName** unspecified when starting the ability. + Implicit Want can be used when the object used to process the request is unclear and the current application wants to use a capability (defined by the [skills tag](../quick-start/module-configuration-file.md#skills-tag)) provided by another application. For example, you can use implicit Want to describe a request for opening a link, since you do not care which application is used to open the link. The system matches all applications that support the request. + + + ```ts + 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.search', + // entities can be omitted. + entities: [ 'entity.system.browsable' ], + uri: 'https://www.test.com:8080/query/student', + type: 'text/plain', + }; + ``` + + > **NOTE** + > - Depending on the ability matching result, the following cases may be possible when you attempt to use implicit Want to start the ability. + > - No ability is matched. The startup fails. + > - An ability that meets the conditions is matched. That ability is started. + > - Multiple abilities that meet the conditions are matched. A dialog box is displayed for users to select one of them. + > + > - If the **want** parameter passed does not contain **abilityName** or **bundleName**, the ServiceExtensionAbility components of all applications cannot be started through implicit Want. + > + > - If the **want** parameter passed contains **bundleName**, the **startServiceExtensionAbility()** method can be used to implicitly start ServiceExtensionAbility. By default, ServiceExtensionAbility with the highest priority is returned. If all the matching ServiceExtensionAbility components have the same priority, the first ServiceExtensionAbility is returned. + + \ No newline at end of file diff --git a/en/application-dev/application-models/widget-development-fa.md b/en/application-dev/application-models/widget-development-fa.md new file mode 100644 index 0000000000000000000000000000000000000000..c170f134932af44c4e8b55888e216926ef51186e --- /dev/null +++ b/en/application-dev/application-models/widget-development-fa.md @@ -0,0 +1,546 @@ +# Widget Development + + +## Widget Overview + +A service widget (also called widget) is a set of UI components that display important information or operations specific to an application. It provides users with direct access to a desired application service, without the need to open the application first. + +A widget usually appears as a part of the UI of another application (which currently can only be a system application) and provides basic interactive features such as opening a UI page or sending a message. + +Before you get started, it would be helpful if you have a basic understanding of the following concepts: + +- Widget host: an application that displays the widget content and controls the widget location. + +- Widget Manager: a resident agent that provides widget management features such as periodic widget updates. + +- Widget provider: an atomic service that provides the widget content to display and controls how widget components are laid out and how they interact with users. + + +## Working Principles + +Figure 1 shows the working principles of the widget framework. + +**Figure 1** Widget framework working principles in the FA model +![form-extension](figures/form-extension.png) + +The widget host consists of the following modules: + +- Widget usage: provides operations such as creating, deleting, or updating a widget. + +- Communication adapter: provided by the OpenHarmony SDK for communication with the Widget Manager. It sends widget-related operations to the Widget Manager. + +The Widget Manager consists of the following modules: + +- Periodic updater: starts a scheduled task based on the update policy to periodically update a widget after it is added to the Widget Manager. + +- Cache manager: caches view information of a widget after it is added to the Widget Manager to directly return the cached data when the widget is obtained next time. This reduces the latency greatly. + +- Lifecycle manager: suspends update when a widget is switched to the background or is blocked, and updates and/or clears widget data during upgrade and deletion. + +- Object manager: manages RPC objects of the widget host. It is used to verify requests from the widget host and process callbacks after the widget update. + +- Communication adapter: communicates with the widget host and provider through RPCs. + +The widget provider consists of the following modules: + +- Widget service: implemented by the widget provider developer to process requests on widget creation, update, and deletion, and to provide corresponding widget services. + +- Instance manager: implemented by the widget provider developer for persistent management of widget instances allocated by the Widget Manager. + +- Communication adapter: provided by the OpenHarmony SDK for communication with the Widget Manager. It pushes update data to the Widget Manager. + +> **NOTE** +> +> You only need to develop the widget provider. The system automatically handles the work of the widget host and Widget Manager. + + +## Available APIs + +The **FormAbility** has the following APIs. + +| API| Description| +| -------- | -------- | +| onCreate(want: Want): formBindingData.FormBindingData | Called to notify the widget provider that a widget has been created.| +| onCastToNormal(formId: string): void | Called to notify the widget provider that a temporary widget has been converted to a normal one.| +| onUpdate(formId: string): void | Called to notify the widget provider that a widget has been updated.| +| onVisibilityChange(newStatus: { [key: string]: number }): void | Called to notify the widget provider of the change in widget visibility.| +| onEvent(formId: string, message: string): void | Called to instruct the widget provider to receive and process a widget event.| +| onDestroy(formId: string): void | Called to notify the widget provider that a widget has been destroyed.| +| onAcquireFormState?(want: Want): formInfo.FormState | Called to instruct the widget provider to receive the status query result of a widget.| +| onShare?(formId: string): {[key: string]: any} | Called by the widget provider to receive shared widget data.| + +The **FormProvider** class has the following APIs. For details, see [FormProvider](../reference/apis/js-apis-app-form-formProvider.md). + + +| API| Description| +| -------- | -------- | +| setFormNextRefreshTime(formId: string, minute: number, callback: AsyncCallback<void>): void;| Sets the next refresh time for a widget. This API uses an asynchronous callback to return the result.| +| setFormNextRefreshTime(formId: string, minute: number): Promise<void>;| Sets the next refresh time for a widget. This API uses a promise to return the result.| +| updateForm(formId: string, formBindingData: FormBindingData, callback: AsyncCallback<void>): void; | Updates a widget. This API uses an asynchronous callback to return the result.| +| updateForm(formId: string, formBindingData: FormBindingData): Promise<void>; | Updates a widget. This API uses a promise to return the result.| + + +The **FormBindingData** class has the following APIs. For details, see [FormBindingData](../reference/apis/js-apis-app-form-formBindingData.md). + + +| API| Description| +| -------- | -------- | +| createFormBindingData(obj?: Object \ string): FormBindingData| | Creates a **FormBindingData** object.| + + +## How to Develop + +The widget provider development based on the [FA model](fa-model-development-overview.md) involves the following key steps: + +- [Implementing Widget Lifecycle Callbacks](#implementing-widget-lifecycle-callbacks): Develop the **FormAbility** lifecycle callback functions. + +- [Configuring the Widget Configuration File](#configuring-the-widget-configuration-file): Configure the application configuration file **config.json**. + +- [Persistently Storing Widget Data](#persistently-storing-widget-data): Perform persistent management on widget information. + +- [Updating Widget Data](#updating-widget-data): Call **updateForm()** to update the information displayed on a widget. + +- [Developing the Widget UI Page](#developing-the-widget-ui-page): Use HML+CSS+JSON to develop a JS widget UI page. + +- [Developing Widget Events](#developing-widget-events): Add the router and message events for a widget. + + +### Implementing Widget Lifecycle Callbacks + +To create a widget in the FA model, implement the widget lifecycle callbacks. Generate a widget template by referring to [Developing a Service Widget](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-development-service-widget-0000001263280425). + +1. Import related modules to **form.ts**. + + ```ts + import formBindingData from '@ohos.app.form.formBindingData'; + import formInfo from '@ohos.app.form.formInfo'; + import formProvider from '@ohos.app.form.formProvider'; + import dataStorage from '@ohos.data.storage'; + ``` + +2. Implement the widget lifecycle callbacks in **form.ts**. + + ```ts + export default { + onCreate(want) { + console.info('FormAbility onCreate'); + // Called when the widget is created. The widget provider should return the widget data binding class. + let obj = { + "title": "titleOnCreate", + "detail": "detailOnCreate" + }; + let formData = formBindingData.createFormBindingData(obj); + return formData; + }, + onCastToNormal(formId) { + // Called when the widget host converts the temporary widget into a normal one. The widget provider should do something to respond to the conversion. + console.info('FormAbility onCastToNormal'); + }, + onUpdate(formId) { + // Override this method to support scheduled updates, periodic updates, or updates requested by the widget host. + console.info('FormAbility onUpdate'); + let obj = { + "title": "titleOnUpdate", + "detail": "detailOnUpdate" + }; + let formData = formBindingData.createFormBindingData(obj); + formProvider.updateForm(formId, formData).catch((error) => { + console.info('FormAbility updateForm, error:' + JSON.stringify(error)); + }); + }, + onVisibilityChange(newStatus) { + // Called when the widget host initiates an event about visibility changes. The widget provider should do something to respond to the notification. This callback takes effect only for system applications. + console.info('FormAbility onVisibilityChange'); + }, + onEvent(formId, message) { + // If the widget supports event triggering, override this method and implement the trigger. + console.info('FormAbility onEvent'); + }, + onDestroy(formId) { + // Delete widget data. + console.info('FormAbility onDestroy'); + }, + onAcquireFormState(want) { + console.info('FormAbility onAcquireFormState'); + return formInfo.FormState.READY; + }, + } + ``` + +> **NOTE** +> +> FormAbility cannot reside in the background. Therefore, continuous tasks cannot be processed in the widget lifecycle callbacks. + +### Configuring the Widget Configuration File + +The widget configuration file is named **config.json**. Find the **config.json** file for the widget and edit the file depending on your need. + +- The **js** module in the **config.json** file provides JavaScript resources of the widget. The internal structure is described as follows: + | Name| Description| Data Type| Initial Value Allowed| + | -------- | -------- | -------- | -------- | + | name | Name of a JavaScript component. The default value is **default**.| String| No| + | pages | Route information about all pages in the JavaScript component, including the page path and page name. The value is an array, in which each element represents a page. The first element in the array represents the home page of the JavaScript FA.| Array| No| + | window | Window-related configurations.| Object| Yes| + | type | Type of the JavaScript component. The value can be:
**normal**: indicates an application instance.
**form**: indicates a widget instance.| String| Yes (initial value: **normal**)| + | mode | Development mode of the JavaScript component.| Object| Yes (initial value: left empty)| + + A configuration example is as follows: + + + ```json + "js": [{ + "name": "widget", + "pages": ["pages/index/index"], + "window": { + "designWidth": 720, + "autoDesignWidth": true + }, + "type": "form" + }] + ``` + +- The **abilities** module in the **config.json** file corresponds to **FormAbility** of the widget. The internal structure is described as follows: + | Name| Description| Data Type| Initial Value Allowed| + | -------- | -------- | -------- | -------- | + | name | Class name of a widget. The value is a string with a maximum of 127 bytes.| String| No| + | description | Description of the widget. The value can be a string or a resource index to descriptions in multiple languages. The value is a string with a maximum of 255 bytes.| String| Yes (initial value: left empty)| + | isDefault | Whether the widget is a default one. Each ability has only one default widget.
**true**: The widget is the default one.
**false**: The widget is not the default one.| Boolean| No| + | type | Type of the widget. The value can be:
**JS**: indicates a JavaScript-programmed widget.| String| No| + | colorMode | Color mode of the widget.
**auto**: The widget adopts the auto-adaptive color mode.
**dark**: The widget adopts the dark color mode.
**light**: The widget adopts the light color mode.| String| Yes (initial value: **auto**)| + | supportDimensions | Grid styles supported by the widget.
**1 * 2**: indicates a grid with one row and two columns.
**2 * 2**: indicates a grid with two rows and two columns.
**2 * 4**: indicates a grid with two rows and four columns.
**4 * 4**: indicates a grid with four rows and four columns.| String array| 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.
**true**: The widget can be updated at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** takes precedence over **scheduledUpdateTime**.
**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.
**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.
If the value is **0**, this attribute does not take effect.
If the value is a positive integer *N*, the interval is calculated by multiplying *N* and 30 minutes.
**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)| + | 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| + | metaData | Metadata of the widget. This attribute contains the array of the **customizeData** attribute.| Object| Yes (initial value: left empty)| + | customizeData | Custom information about the widget.| Object array| Yes (initial value: left empty)| + + A configuration example is as follows: + + + ```json + "abilities": [{ + "name": "FormAbility", + "description": "This is a FormAbility", + "formsEnabled": true, + "icon": "$media:icon", + "label": "$string:form_FormAbility_label", + "srcPath": "FormAbility", + "type": "service", + "srcLanguage": "ets", + "formsEnabled": true, + "formConfigAbility": "ability://com.example.entry.MainAbility", + "forms": [{ + "colorMode": "auto", + "defaultDimension": "2*2", + "description": "This is a service widget.", + "formVisibleNotify": true, + "isDefault": true, + "jsComponentName": "widget", + "name": "widget", + "scheduledUpdateTime": "10:30", + "supportDimensions": ["2*2"], + "type": "JS", + "updateEnabled": true + }] + }] + ``` + + +### Persistently Storing Widget Data + +A widget provider is usually started when it is needed to provide information about a widget. The Widget Manager supports multi-instance management and uses the widget ID to identify an instance. If the widget provider supports widget data modification, it must persistently store the data based on the widget ID, so that it can access the data of the target widget when obtaining, updating, or starting a widget. + + +```ts +const DATA_STORAGE_PATH = "/data/storage/el2/base/haps/form_store"; +async function storeFormInfo(formId: string, formName: string, tempFlag: boolean) { + // Only the widget ID (formId), widget name (formName), and whether the widget is a temporary one (tempFlag) are persistently stored. + let formInfo = { + "formName": formName, + "tempFlag": tempFlag, + "updateCount": 0 + }; + try { + const storage = await dataStorage.getStorage(DATA_STORAGE_PATH); + // Put the widget information. + await storage.put(formId, JSON.stringify(formInfo)); + console.info(`storeFormInfo, put form info successfully, formId: ${formId}`); + await storage.flush(); + } catch (err) { + console.error(`failed to storeFormInfo, err: ${JSON.stringify(err)}`); + } +} + +// ... + onCreate(want) { + console.info('FormAbility onCreate'); + + let formId = want.parameters["ohos.extra.param.key.form_identity"]; + let formName = want.parameters["ohos.extra.param.key.form_name"]; + let tempFlag = want.parameters["ohos.extra.param.key.form_temporary"]; + // Persistently store widget information for subsequent use, such as instance acquisition and update. + // Implement this API based on project requirements. + storeFormInfo(formId, formName, tempFlag); + + let obj = { + "title": "titleOnCreate", + "detail": "detailOnCreate" + }; + let formData = formBindingData.createFormBindingData(obj); + return formData; + } +// ... +``` + +You should override **onDestroy** to implement widget data deletion. + + +```ts +const DATA_STORAGE_PATH = "/data/storage/el2/base/haps/form_store"; +async function deleteFormInfo(formId: string) { + try { + const storage = await dataStorage.getStorage(DATA_STORAGE_PATH); + // Delete the widget information. + await storage.delete(formId); + console.info(`deleteFormInfo, del form info successfully, formId: ${formId}`); + await storage.flush(); + } catch (err) { + console.error(`failed to deleteFormInfo, err: ${JSON.stringify(err)}`); + } +} + +// ... + onDestroy(formId) { + console.info('FormAbility onDestroy'); + // Delete the persistent widget instance data. + // Implement this API based on project requirements. + deleteFormInfo(formId); + } +// ... +``` + +For details about how to implement persistent data storage, see [Lightweight Data Store Development](../database/database-preference-guidelines.md). + +The **Want** object passed 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 + +- Temporary widget: a widget temporarily used by the widget host + +Data of a temporary widget will be deleted on the Widget Manager if the widget framework is killed and restarted. The widget provider, however, is not notified of the deletion and still keeps the data. Therefore, the widget provider needs to clear the data of temporary widgets proactively if the data has been kept for a long period of time. If the widget host has converted a temporary widget into a normal one, the widget provider should change the widget data from temporary storage to persistent storage. Otherwise, the widget data may be deleted by mistake. + + +### Updating Widget Data + +When an application initiates a scheduled or periodic update, the application obtains the latest data and calls **updateForm()** to update the widget. + + +```ts +onUpdate(formId) { + // Override this method to support scheduled updates, periodic updates, or updates requested by the widget host. + console.info('FormAbility onUpdate'); + let obj = { + "title": "titleOnUpdate", + "detail": "detailOnUpdate" + }; + 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. + formProvider.updateForm(formId, formData).catch((error) => { + console.info('FormAbility updateForm, error:' + JSON.stringify(error)); + }); +} +``` + + +### Developing the Widget UI Page + +You can use the web-like paradigm (HML+CSS+JSON) to develop JS widget pages. This section describes how to develop a page shown below. + +![widget-development-fa](figures/widget-development-fa.png) + +> **NOTE** +> +> Only the JavaScript-based web-like development paradigm is supported when developing the widget UI. + +- HML: uses web-like paradigm components to describe the widget page information. + + ```html +
+ +
+ +
+
+ {{title}} + {{detail}} +
+
+
+ ``` + +- CSS: defines style information about the web-like paradigm components in HML. + + ```css + .container { + flex-direction: column; + justify-content: center; + align-items: center; + } + + .bg-img { + flex-shrink: 0; + height: 100%; + } + + .container-inner { + flex-direction: column; + justify-content: flex-end; + align-items: flex-start; + height: 100%; + width: 100%; + padding: 12px; + } + + .title { + font-size: 19px; + font-weight: bold; + color: white; + text-overflow: ellipsis; + max-lines: 1; + } + + .detail_text { + font-size: 16px; + color: white; + opacity: 0.66; + text-overflow: ellipsis; + max-lines: 1; + margin-top: 6px; + } + ``` + +- JSON: defines data and event interaction on the widget UI page. + + ```json + { + "data": { + "title": "TitleDefault", + "detail": "TextDefault" + }, + "actions": { + "routerEvent": { + "action": "router", + "abilityName": "com.example.entry.MainAbility", + "params": { + "message": "add detail" + } + } + } + } + ``` + + +### Developing Widget Events + +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. + +2. Set the router event. + - **action**: **router**, which indicates a router event. + - **abilityName**: name of the ability to redirect to (PageAbility component in the FA model and UIAbility component in the stage model). For example, the default MainAbility name of the FA model created by DevEco Studio is com.example.entry.MainAbility. + - **params**: custom parameters passed to 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. + +3. Set the 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**. + +The following is an example: + +- HML file: + + ```html +
+ +
+ +
+
+ {{title}} + {{detail}} +
+
+
+ ``` + +- CSS file: + + ```css + .container { + flex-direction: column; + justify-content: center; + align-items: center; + } + + .bg-img { + flex-shrink: 0; + height: 100%; + } + + .container-inner { + flex-direction: column; + justify-content: flex-end; + align-items: flex-start; + height: 100%; + width: 100%; + padding: 12px; + } + + .title { + font-size: 19px; + font-weight: bold; + color: white; + text-overflow: ellipsis; + max-lines: 1; + } + + .detail_text { + font-size: 16px; + color: white; + opacity: 0.66; + text-overflow: ellipsis; + max-lines: 1; + margin-top: 6px; + } + ``` + +- JSON file: + + ```json + { + "data": { + "title": "TitleDefault", + "detail": "TextDefault" + }, + "actions": { + "routerEvent": { + "action": "router", + "abilityName": "com.example.entry.MainAbility", + "params": { + "message": "add detail" + } + }, + "messageEvent": { + "action": "message", + "params": { + "message": "add detail" + } + } + } + } + ``` + diff --git a/en/application-dev/application-models/widget-development-stage.md b/en/application-dev/application-models/widget-development-stage.md new file mode 100644 index 0000000000000000000000000000000000000000..38f4e89d108d9d012c968b3d05de5b4e841ff482 --- /dev/null +++ b/en/application-dev/application-models/widget-development-stage.md @@ -0,0 +1,600 @@ +# FormExtensionAbility (Widget) + + +## Widget Overview + +FormExtensionAbility provides a service widget (also called widget), which is a set of UI components that display important information or operations specific to an application. It provides users with direct access to a desired application service, without the need to open the application first. + +A widget usually appears as a part of the UI of another application (which currently can only be a system application) and provides basic interactive features such as opening a UI page or sending a message. + +Before you get started, it would be helpful if you have a basic understanding of the following concepts: + +- Widget host: an application that displays the widget content and controls the widget location. + +- Widget Manager: a resident agent that provides widget management features such as periodic widget updates. + +- Widget provider: an atomic service that provides the widget content to display and controls how widget components are laid out and how they interact with users. + + +## Working Principles + +Figure 1 shows the working principles of the widget framework. + +**Figure 1** Widget framework working principles in the stage model +![form-extension](figures/form-extension.png) + +The widget host consists of the following modules: + +- Widget usage: provides operations such as creating, deleting, or updating a widget. + +- Communication adapter: provided by the OpenHarmony SDK for communication with the Widget Manager. It sends widget-related operations to the Widget Manager. + +The Widget Manager consists of the following modules: + +- Periodic updater: starts a scheduled task based on the update policy to periodically update a widget after it is added to the Widget Manager. + +- Cache manager: caches view information of a widget after it is added to the Widget Manager to directly return the cached data when the widget is obtained next time. This reduces the latency greatly. + +- Lifecycle manager: suspends update when a widget is switched to the background or is blocked, and updates and/or clears widget data during upgrade and deletion. + +- Object manager: manages RPC objects of the widget host. It is used to verify requests from the widget host and process callbacks after the widget update. + +- Communication adapter: communicates with the widget host and provider through RPCs. + +The widget provider consists of the following modules: + +- Widget service: implemented by the widget provider developer to process requests on widget creation, update, and deletion, and to provide corresponding widget services. + +- Instance manager: implemented by the widget provider developer for persistent management of widget instances allocated by the Widget Manager. + +- Communication adapter: provided by the OpenHarmony SDK for communication with the Widget Manager. It pushes update data to the Widget Manager. + +> **NOTE** +> +> You only need to develop the widget provider. The system automatically handles the work of the widget host and Widget Manager. + + +## Available APIs + +The **FormExtensionAbility** class has the following APIs. For details, see [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md). + +| API| Description| +| -------- | -------- | +| onAddForm(want: Want): formBindingData.FormBindingData | Called to notify the widget provider that a widget has been created.| +| onCastToNormalForm(formId: string): void | Called to notify the widget provider that a temporary widget has been converted to a normal one.| +| onUpdateForm(formId: string): void | Called to notify the widget provider that a widget has been updated.| +| onChangeFormVisibility(newStatus: { [key: string]: number }): void | Called to notify the widget provider of the change in widget visibility.| +| onFormEvent(formId: string, message: string): void | Called to instruct the widget provider to receive and process a widget event.| +| onRemoveForm(formId: string): void| Called to notify the widget provider that a widget has been destroyed.| +| onConfigurationUpdate(config: Configuration): void | Called when the configuration of the environment where the widget is running is updated.| +| onShareForm?(formId: string): { [key: string]: any }| Called by the widget provider to receive shared widget data.| + +The **FormExtensionAbility** class also has a member context, that is, the FormExtensionContext class. For details, see [FormExtensionContext](../reference/apis/js-apis-inner-application-formExtensionContext.md). + +| API| Description| +| -------- | -------- | +| startAbility(want: Want, callback: AsyncCallback<void>): void | Starts UIAbility of the application to which a widget belongs. This API uses an asynchronous callback to return the result. (This is a system API and cannot be called by third-party applications. You must apply for the permission to use the API.)| +| startAbility(want: Want): Promise<void> | Starts UIAbility of the application to which a widget belongs. This API uses a promise to return the result. (This is a system API and cannot be called by third-party applications. You must apply for the permission to use the API.)| + +The **FormProvider** class has the following APIs. For details, see [FormProvider](../reference/apis/js-apis-app-form-formProvider.md). + +| API| Description| +| -------- | -------- | +| setFormNextRefreshTime(formId: string, minute: number, callback: AsyncCallback<void>): void; | Sets the next refresh time for a widget. This API uses an asynchronous callback to return the result.| +| setFormNextRefreshTime(formId: string, minute: number): Promise<void>; | Sets the next refresh time for a widget. This API uses a promise to return the result.| +| updateForm(formId: string, formBindingData: FormBindingData, callback: AsyncCallback<void>): void; | Updates a widget. This API uses an asynchronous callback to return the result.| +| updateForm(formId: string, formBindingData: FormBindingData): Promise<void>;| Updates a widget. This API uses a promise to return the result.| + +The **FormBindingData** class has the following APIs. For details, see [FormBindingData](../reference/apis/js-apis-app-form-formBindingData.md). + +| API| Description| +| -------- | -------- | +| createFormBindingData(obj?: Object \ string): FormBindingData| | Creates a **FormBindingData** object.| + + +## How to Develop + +The widget provider development based on the [stage model](stage-model-development-overview.md) involves the following key steps: + +- [Creating a FormExtensionAbility Instance](#creating-a-formextensionability-instance): Develop the lifecycle callback functions of FormExtensionAbility. + +- [Configuring the Widget Configuration File](#configuring-the-widget-configuration-file): Configure the application configuration file **module.json5** and profile configuration file. + +- [Persistently Storing Widget Data](#persistently-storing-widget-data): Perform persistent management on widget information. + +- [Updating Widget Data](#updating-widget-data): Call **updateForm()** to update the information displayed on a widget. + +- [Developing the Widget UI Page](#developing-the-widget-ui-page): Use HML+CSS+JSON to develop a JS widget UI page. + +- [Developing Widget Events](#developing-widget-events): Add the router and message events for a widget. + + +### Creating a FormExtensionAbility Instance + +To create a widget in the stage model, implement the lifecycle callbacks of **FormExtensionAbility**. Generate a widget template by referring to [Developing a Service Widget](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-development-service-widget-0000001263280425). + +1. Import related modules to **EntryFormAbility.ts**. + + ```ts + import FormExtension from '@ohos.app.form.FormExtensionAbility'; + import formBindingData from '@ohos.app.form.formBindingData'; + import formInfo from '@ohos.app.form.formInfo'; + import formProvider from '@ohos.app.form.formProvider'; + import dataStorage from '@ohos.data.storage'; + ``` + +2. Implement the FormExtension lifecycle callbacks in **EntryFormAbility.ts**. + + ```ts + export default class EntryFormAbility extends FormExtension { + onAddForm(want) { + console.info('[EntryFormAbility] onAddForm'); + // Called when the widget is created. The widget provider should return the widget data binding class. + let obj = { + "title": "titleOnCreate", + "detail": "detailOnCreate" + }; + let formData = formBindingData.createFormBindingData(obj); + return formData; + } + onCastToNormalForm(formId) { + // Called when the widget host converts the temporary widget into a normal one. The widget provider should do something to respond to the conversion. + console.info('[EntryFormAbility] onCastToNormalForm'); + } + onUpdateForm(formId) { + // Override this method to support scheduled updates, periodic updates, or updates requested by the widget host. + console.info('[EntryFormAbility] onUpdateForm'); + let obj = { + "title": "titleOnUpdate", + "detail": "detailOnUpdate" + }; + let formData = formBindingData.createFormBindingData(obj); + formProvider.updateForm(formId, formData).catch((error) => { + console.info('[EntryFormAbility] updateForm, error:' + JSON.stringify(error)); + }); + } + onChangeFormVisibility(newStatus) { + // Called when the widget host initiates an event about visibility changes. The widget provider should do something to respond to the notification. This callback takes effect only for system applications. + console.info('[EntryFormAbility] onChangeFormVisibility'); + } + onFormEvent(formId, message) { + // If the widget supports event triggering, override this method and implement the trigger. + console.info('[EntryFormAbility] onFormEvent'); + } + onRemoveForm(formId) { + // Delete widget data. + console.info('[EntryFormAbility] onRemoveForm'); + } + onConfigurationUpdate(config) { + console.info('[EntryFormAbility] nConfigurationUpdate, config:' + JSON.stringify(config)); + } + onAcquireFormState(want) { + return formInfo.FormState.READY; + } + } + ``` + +> **NOTE** +> +> FormExtensionAbility cannot reside in the background. Therefore, continuous tasks cannot be processed in the widget lifecycle callbacks. + +### Configuring the Widget Configuration File + +1. Configure ExtensionAbility information under **extensionAbilities** in the [module.json5 file](../quick-start/module-configuration-file.md). For a FormExtensionAbility, you must specify **metadata**. Specifically, set **name** to **ohos.extension.form** (fixed), and set **resource** to the index of the widget configuration information. + A configuration example is as follows: + + + ```json + { + "module": { + // ... + "extensionAbilities": [ + { + "name": "EntryFormAbility", + "srcEntrance": "./ets/entryformability/EntryFormAbility.ts", + "label": "$string:EntryFormAbility_label", + "description": "$string:EntryFormAbility_desc", + "type": "form", + "metadata": [ + { + "name": "ohos.extension.form", + "resource": "$profile:form_config" + } + ] + } + ] + } + } + ``` + +2. Configure the widget configuration information. In the **metadata** configuration item of FormExtensionAbility, you can specify the resource index of specific configuration information of the widget. For example, if resource is set to **$profile:form_config**, **form_config.json** in the **resources/base/profile/** directory of the development view is used as the profile configuration file of the widget. The following table describes the internal field structure. + **Table 1** Widget profile configuration file + + | Field| Description| Data Type| Initial Value Allowed| + | -------- | -------- | -------- | -------- | + | name | Class name of a widget. The value is a string with a maximum of 127 bytes.| String| No| + | description | Description of the widget. The value can be a string or a resource index to descriptions in multiple languages. The value is a string with a maximum of 255 bytes.| String| Yes (initial value: left empty)| + | src | Full path of the UI code corresponding to the widget.| String| No| + | window | Window-related configurations.| Object| Yes| + | isDefault | Whether the widget is a default one. Each ability has only one default widget.
**true**: The widget is the default one.
**false**: The widget is not the default one.| Boolean| No| + | colorMode | Color mode of the widget.
**auto**: The widget adopts the auto-adaptive color mode.
**dark**: The widget adopts the dark color mode.
**light**: The widget adopts the light color mode.| String| Yes (initial value: **auto**)| + | supportDimensions | Grid styles supported by the widget.
**1 * 2**: indicates a grid with one row and two columns.
**2 * 2**: indicates a grid with two rows and two columns.
**2 * 4**: indicates a grid with two rows and four columns.
**4 * 4**: indicates a grid with four rows and four columns.| String array| 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.
**true**: The widget can be updated at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** takes precedence over **scheduledUpdateTime**.
**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.
**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.
If the value is **0**, this attribute does not take effect.
If the value is a positive integer *N*, the interval is calculated by multiplying *N* and 30 minutes.
**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)| + | formVisibleNotify | Whether the widget is allowed to use the widget visibility notification.| String| Yes (initial value: left empty)| + | metaData | Metadata of the widget. This attribute contains the array of the **customizeData** attribute.| Object| Yes (initial value: left empty)| + + A configuration example is as follows: + + ```json + { + "forms": [ + { + "name": "widget", + "description": "This is a service widget.", + "src": "./js/widget/pages/index/index", + "window": { + "designWidth": 720, + "autoDesignWidth": true + }, + "colorMode": "auto", + "isDefault": true, + "updateEnabled": true, + "scheduledUpdateTime": "10:30", + "updateDuration": 1, + "defaultDimension": "2*2", + "supportDimensions": [ + "2*2" + ] + } + ] + } + ``` + + +### Persistently Storing Widget Data + +A widget provider is usually started when it is needed to provide information about a widget. The Widget Manager supports multi-instance management and uses the widget ID to identify an instance. If the widget provider supports widget data modification, it must persistently store the data based on the widget ID, so that it can access the data of the target widget when obtaining, updating, or starting a widget. + + +```ts +const DATA_STORAGE_PATH = "/data/storage/el2/base/haps/form_store"; +async function storeFormInfo(formId: string, formName: string, tempFlag: boolean) { + // Only the widget ID (formId), widget name (formName), and whether the widget is a temporary one (tempFlag) are persistently stored. + let formInfo = { + "formName": formName, + "tempFlag": tempFlag, + "updateCount": 0 + }; + try { + const storage = await dataStorage.getStorage(DATA_STORAGE_PATH); + // Put the widget information. + await storage.put(formId, JSON.stringify(formInfo)); + console.info(`[EntryFormAbility] storeFormInfo, put form info successfully, formId: ${formId}`); + await storage.flush(); + } catch (err) { + console.error(`[EntryFormAbility] failed to storeFormInfo, err: ${JSON.stringify(err)}`); + } +} + +export default class EntryFormAbility extends FormExtension { + // ... + onAddForm(want) { + console.info('[EntryFormAbility] onAddForm'); + + let formId = want.parameters["ohos.extra.param.key.form_identity"]; + let formName = want.parameters["ohos.extra.param.key.form_name"]; + let tempFlag = want.parameters["ohos.extra.param.key.form_temporary"]; + // Persistently store widget information for subsequent use, such as instance acquisition and update. + // Implement this API based on project requirements. + storeFormInfo(formId, formName, tempFlag); + + let obj = { + "title": "titleOnCreate", + "detail": "detailOnCreate" + }; + let formData = formBindingData.createFormBindingData(obj); + return formData; + } +} +``` + +You should override **onRemoveForm** to implement widget data deletion. + + +```ts +const DATA_STORAGE_PATH = "/data/storage/el2/base/haps/form_store"; +async function deleteFormInfo(formId: string) { + try { + const storage = await dataStorage.getStorage(DATA_STORAGE_PATH); + // Delete the widget information. + await storage.delete(formId); + console.info(`[EntryFormAbility] deleteFormInfo, del form info successfully, formId: ${formId}`); + await storage.flush(); + } catch (err) { + console.error(`[EntryFormAbility] failed to deleteFormInfo, err: ${JSON.stringify(err)}`); + } +} + +// ... + +export default class EntryFormAbility extends FormExtension { + // ... + onRemoveForm(formId) { + console.info('[EntryFormAbility] onRemoveForm'); + // Delete the persistent widget instance data. + // Implement this API based on project requirements. + deleteFormInfo(formId); + } +} +``` + +For details about how to implement persistent data storage, see [Lightweight Data Store Development](../database/database-preference-guidelines.md). + +The **Want** object passed 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 + +- Temporary widget: a widget temporarily used by the widget host + +Data of a temporary widget will be deleted on the Widget Manager if the widget framework is killed and restarted. The widget provider, however, is not notified of the deletion and still keeps the data. Therefore, the widget provider needs to clear the data of temporary widgets proactively if the data has been kept for a long period of time. If the widget host has converted a temporary widget into a normal one, the widget provider should change the widget data from temporary storage to persistent storage. Otherwise, the widget data may be deleted by mistake. + + +### Updating Widget Data + +When an application initiates a scheduled or periodic update, the application obtains the latest data and calls **updateForm()** to update the widget. + + +```ts +onUpdateForm(formId) { + // Override this method to support scheduled updates, periodic updates, or updates requested by the widget host. + console.info('[EntryFormAbility] onUpdateForm'); + let obj = { + "title": "titleOnUpdate", + "detail": "detailOnUpdate" + }; + 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. + formProvider.updateForm(formId, formData).catch((error) => { + console.info('[EntryFormAbility] updateForm, error:' + JSON.stringify(error)); + }); +} +``` + + +### Developing the Widget UI Page + +You can use the web-like paradigm (HML+CSS+JSON) to develop JS widget pages. This section describes how to develop a page shown below. + +![widget-development-stage](figures/widget-development-stage.png) + +> **NOTE** +> +> Only the JavaScript-based web-like development paradigm is supported when developing the widget UI. + +- HML: uses web-like paradigm components to describe the widget page information. + + ```html +
+ +
+ +
+
+ {{title}} + {{detail}} +
+
+
+ ``` + +- CSS: defines style information about the web-like paradigm components in HML. + + ```css + .container { + flex-direction: column; + justify-content: center; + align-items: center; + } + + .bg-img { + flex-shrink: 0; + height: 100%; + } + + .container-inner { + flex-direction: column; + justify-content: flex-end; + align-items: flex-start; + height: 100%; + width: 100%; + padding: 12px; + } + + .title { + font-size: 19px; + font-weight: bold; + color: white; + text-overflow: ellipsis; + max-lines: 1; + } + + .detail_text { + font-size: 16px; + color: white; + opacity: 0.66; + text-overflow: ellipsis; + max-lines: 1; + margin-top: 6px; + } + ``` + +- JSON: defines data and event interaction on the widget UI page. + + ```json + { + "data": { + "title": "TitleDefault", + "detail": "TextDefault" + }, + "actions": { + "routerEvent": { + "action": "router", + "abilityName": "EntryAbility", + "params": { + "message": "add detail" + } + } + } + } + ``` + + +### Developing Widget Events + +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. + +2. Set the router event. + - **action**: **router**, which indicates a router event. + - **abilityName**: name of the ability to redirect to (PageAbility component in the FA model and UIAbility component in the stage model). For example, the default UIAbility name of the stage model created by DevEco Studio is EntryAbility. + - **params**: custom parameters passed to 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 stage model, you can obtain **want** and its **parameters** field. + +3. Set the 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 **onFormEvent()**. + +The following is an example: + +- HML file: + + ```html +
+ +
+ +
+
+ {{title}} + {{detail}} +
+
+
+ ``` + +- CSS file: + + ```css + .container { + flex-direction: column; + justify-content: center; + align-items: center; + } + + .bg-img { + flex-shrink: 0; + height: 100%; + } + + .container-inner { + flex-direction: column; + justify-content: flex-end; + align-items: flex-start; + height: 100%; + width: 100%; + padding: 12px; + } + + .title { + font-size: 19px; + font-weight: bold; + color: white; + text-overflow: ellipsis; + max-lines: 1; + } + + .detail_text { + font-size: 16px; + color: white; + opacity: 0.66; + text-overflow: ellipsis; + max-lines: 1; + margin-top: 6px; + } + ``` + +- JSON file: + + ```json + { + "data": { + "title": "TitleDefault", + "detail": "TextDefault" + }, + "actions": { + "routerEvent": { + "action": "router", + "abilityName": "EntryAbility", + "params": { + "info": "router info", + "message": "router message" + } + }, + "messageEvent": { + "action": "message", + "params": { + "detail": "message detail" + } + } + } + } + ``` + +- Receive the router event and obtain parameters in UIAbility. + + ```ts + import UIAbility from '@ohos.app.ability.UIAbility' + + export default class EntryAbility extends UIAbility { + onCreate(want, launchParam) { + // Obtain the info parameter passed in the router event. + if (want.parameters.info === "router info") { + // Do something. + // console.log("router info:" + want.parameters.info) + } + // Obtain the message parameter passed in the router event. + if (want.parameters.message === "router message") { + // Do something. + // console.log("router message:" + want.parameters.message) + } + } + // ... + }; + ``` + +- Receive the message event in FormExtensionAbility and obtain parameters. + + ```ts + import FormExtension from '@ohos.app.form.FormExtensionAbility'; + + export default class FormAbility extends FormExtension { + // ... + onFormEvent(formId, message) { + // Obtain the detail parameter passed in the message event. + let msg = JSON.parse(message) + if (msg.params.detail === "message detail") { + // Do something. + // console.log("message info:" + msg.params.detail) + } + } + // ... + }; + ``` + + \ No newline at end of file diff --git a/en/application-dev/application-models/widget-switch.md b/en/application-dev/application-models/widget-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..8d9823385a8a05f71c742327dc966054427a6718 --- /dev/null +++ b/en/application-dev/application-models/widget-switch.md @@ -0,0 +1,48 @@ +# Widget Switching + + +Widget switching involves the following parts: + + +- Widget UI layout: Both the FA model and stage model use the web-like paradigm to develop the widget UI layout. Therefore, the UI layout of a widget in the FA model can be directly reused in the stage mode. +- Widget configuration file: Widgets are configured in the **config.json** file in the FA model and in **module.json5** and **form_config.json** files in the stage model (as shown in Figure 1 and Figure 2). +- Widget service logic: The widget entry file and lifecycle of the FA model are slightly different from those of the stage model, as shown in Figure 3 and Figure 4. + +| Configuration Item | FA Model | Stage Model | +| ---------------- | ------------------------------------------- | ------------------------------------------------------------ | +| Configuration item location | **formAbility** and **forms** are in the **config.json** file.| **extensionAbilities** (configuration for **formExtensionAbility**) is in the **module.json5** file in the level-1 directory, and **forms** (configuration for **forms** contained in **formExtensionAbility**) is in the **form_config.json** file in the level-2 directory.| +| Widget code path | Specified by **srcPath**, without the file name. | Specified by **srcEntrance**, with the file name. | +| Programming language | **srcLanguage** can be set to **js** or **ets**. | This configuration item is unavailable. Only ets is supported. | +| Whether to enable widgets | formsEnabled | This configuration item is unavailable. The setting of **type** set to **form** means that the widgets are enabled. | +| Ability type | type: service | type: form | +| Level-2 directory configuration tag| This configuration item is unavailable. | **metadata**, which consists of **name**, **value**, and **resource**, where **resource** points to the location of the **form_config.json** file in the level-2 directory.| + + +Figure 1 Entry configuration differences + + +![widget-switch1](figures/widget-switch1.png) + + +Figure 2 Widget configuration differences + + +![widget-switch2](figures/widget-switch2.png) + + +| Item| FA Model| Stage Model| +| -------- | -------- | -------- | +| Entry file| **form.ts** in the directory pointed to by **srcPath**| File pointed to by **srcEntrance**| +| Lifecycle| export default| import FormExtension from '\@ohos.app.form.FormExtensionAbility';
export default class FormAbility extends FormExtension| + + +Figure 3 Entry file differences + + +![widget-switch3](figures/widget-switch3.png) + + +Figure 4 Lifecycle differences (The lifecycle callbacks are the same and require no adjustment.) + + +![widget-switch4](figures/widget-switch4.png) diff --git a/en/application-dev/application-models/window-properties.md b/en/application-dev/application-models/window-properties.md new file mode 100644 index 0000000000000000000000000000000000000000..250476f05f7fc66b5deaa52ee2e4905f8de0edf6 --- /dev/null +++ b/en/application-dev/application-models/window-properties.md @@ -0,0 +1,4 @@ +# Window Properties + + +For details about the APIs for obtaining a window instance and setting window properties, see [Application Window Development (FA Model)](../windowmanager/application-window-fa.md). diff --git a/en/application-dev/application-models/window-switch.md b/en/application-dev/application-models/window-switch.md new file mode 100644 index 0000000000000000000000000000000000000000..379f0282b1e50e856d0010a9087622e2e1363d89 --- /dev/null +++ b/en/application-dev/application-models/window-switch.md @@ -0,0 +1,8 @@ +# window Switching + + +| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| +| -------- | -------- | -------- | +| [create(id: string, type: WindowType, callback: AsyncCallback<Window>): void;](../reference/apis/js-apis-window.md#windowcreatedeprecated)
[create(id: string, type: WindowType): Promise<Window>;](../reference/apis/js-apis-window.md#windowcreatedeprecated-1) | \@ohos.window.d.ts | [createSubWindow(name: string, callback: AsyncCallback<Window>): void;](../reference/apis/js-apis-window.md#createsubwindow9)
[createSubWindow(name: string): Promise;](../reference/apis/js-apis-window.md#createsubwindow9-1)
An application developed on the FA model uses **window.create(id, WindowType.TYPE_APP)** to create a subwindow, whereas an application developed on the stage model uses **WindowStage.CreateSubWindow()** to create a subwindow.| +| [getTopWindow(callback: AsyncCallback<Window>): void;](../reference/apis/js-apis-window.md#windowgettopwindowdeprecated)
[getTopWindow(): Promise<Window>;](../reference/apis/js-apis-window.md#windowgettopwindowdeprecated-1) | \@ohos.window.d.ts | [getLastWindow(ctx: BaseContext, callback: AsyncCallback<Window>): void;](../reference/apis/js-apis-window.md#windowgetlastwindow9)
[getLastWindow(ctx: BaseContext): Promise<Window>;](../reference/apis/js-apis-window.md#windowgetlastwindow9-1) | + diff --git a/en/application-dev/dfx/Readme-EN.md b/en/application-dev/dfx/Readme-EN.md index af9e5d190ab515b61be1c7441d72e264c87ca310..b8a4496e09420b3a7557e5c8b8996deaf14ce1c9 100644 --- a/en/application-dev/dfx/Readme-EN.md +++ b/en/application-dev/dfx/Readme-EN.md @@ -1,14 +1,8 @@ # DFX -- Application Event Logging - - [Overview of Application Event Logging](hiappevent-overview.md) - - [Development of Application Event Logging](hiappevent-guidelines.md) -- Performance Tracing - - [Overview of Performance Tracing](hitracemeter-overview.md) - - [Development of Performance Tracing](hitracemeter-guidelines.md) -- Distributed Call Chain Tracing - - [Overview of Distributed Call Chain Tracing](hitracechain-overview.md) - - [Development of Distributed Call Chain Tracing](hitracechain-guidelines.md) +- [Development of Application Event Logging](hiappevent-guidelines.md) +- [Development of Performance Tracing](hitracemeter-guidelines.md) +- [Development of Distributed Call Chain Tracing](hitracechain-guidelines.md) - Error Management - [Development of Error Manager](errormanager-guidelines.md) - [Development of Application Recovery](apprecovery-guidelines.md) diff --git a/en/application-dev/dfx/errormanager-guidelines.md b/en/application-dev/dfx/errormanager-guidelines.md index 835a6ab9ce3c0beacd19f7c76f5a1eec68bf36cd..631445b862097d5aa71320ff154d6e235660a95e 100644 --- a/en/application-dev/dfx/errormanager-guidelines.md +++ b/en/application-dev/dfx/errormanager-guidelines.md @@ -48,28 +48,28 @@ var callback = { export default class MainAbility extends Ability { onCreate(want, launchParam) { console.log("[Demo] MainAbility onCreate") + registerId = errorManager.registerErrorObserver(callback); globalThis.abilityWant = want; } onDestroy() { console.log("[Demo] MainAbility onDestroy") + errorManager.unregisterErrorObserver(registerId, (result) => { + console.log("[Demo] result " + result.code + ";" + result.message) + }); } onWindowStageCreate(windowStage) { // Main window is created for this ability. console.log("[Demo] MainAbility onWindowStageCreate") - globalThis.registerObserver = (() => { - registerId = errorManager.registerErrorObserver(callback); - }) - - globalThis.unRegisterObserver = (() => { - errorManager.unregisterErrorObserver(registerId, (result) => { - console.log("[Demo] result " + result.code + ";" + result.message) - }); - }) - - windowStage.setUIContent(this.context, "pages/index", null) + windowStage.loadContent("pages/index", (err, data) => { + if (err.code) { + console.error('Failed to load the content. Cause:' + JSON.stringify(err)); + return; + } + console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)) + }); } onWindowStageDestroy() { diff --git a/en/application-dev/dfx/figures/fault_rectification.png b/en/application-dev/dfx/figures/fault_rectification.png index 63ac5e5f666d5c23c9e9ea3123a9566013336aba..67aa40592f7bcad23e216222e898c1f1327a4efb 100644 Binary files a/en/application-dev/dfx/figures/fault_rectification.png and b/en/application-dev/dfx/figures/fault_rectification.png differ diff --git a/en/application-dev/dfx/hiappevent-guidelines.md b/en/application-dev/dfx/hiappevent-guidelines.md index 067b9b8c915417b93340ab55bf34a74bca422a3d..6343b502fad6e7572f1d08eee1debd6cd8407061 100644 --- a/en/application-dev/dfx/hiappevent-guidelines.md +++ b/en/application-dev/dfx/hiappevent-guidelines.md @@ -1,12 +1,29 @@ # Development of Application Event Logging -## When to Use +## Introduction -The event logging function helps applications log various information generated during running. +A traditional log system aggregates log information generated by all applications running on the entire device, making it difficult to identify key information in the log. Therefore, an effective logging mechanism is needed to evaluate mission-critical information, for example, number of visits, number of daily active users, user operation habits, and key factors that affect application usage. -## Available APIs +HiAppEvent is a module that provides the event logging function for applications to log the fault, statistical, security, and user behavior events reported during running. Based on event information, you will be able to analyze the running status of applications. + +## Basic Concepts + +- **Logging** + + Logs changes caused by user operations to provide service data for development, product, and O&M analysis. + +## Event Design Specifications -JS application event logging APIs are provided by the **hiAppEvent** module. +- Event domain: identifies the domain of an event. You are advised to set this parameter to the service module name to differentiate service modules. +- Event name: specifies the name of an event. You are advised to set this parameter to a specific service name to differentiate services. +- Event type: specifies the type of an event. Four event types are supported: + - Behavior event: used to record the daily operation behavior of a user, for example, button click and page redirection. + - Fault event: used to locate and analyze application faults, for example, frame freezing, network disconnection, and call drop. + - Statistical event: used to collect statistics on key application behaviors, for example, usage duration and number of visits. + - Security event: used to record events related to application security, for example, password change and user authorization. +- Event parameter: specifies the parameters of an event. Each event can contain a group of parameters. You are advised to set this parameter to an event attribute or event context to depict the event details. + +## Available APIs The following table provides only a brief description of related APIs. For details, see [HiAppEvent](../reference/apis/js-apis-hiviewdfx-hiappevent.md). @@ -17,33 +34,68 @@ The following table provides only a brief description of related APIs. For detai | write(AppEventInfo info, AsyncCallback\ callback): void | Logs application events in asynchronous mode. This API uses an asynchronous callback to return the result.| | write(AppEventInfo info): Promise\ | Logs application events in asynchronous mode. This API uses a promise to return the result. | -**Table 2** APIs for event logging configuration - -| API | Description | -| ------------------------------------ | ---------------------------------------------------- | -| configure(ConfigOption config): void | Sets the configuration options for application event logging.| - **Table 3** APIs for watcher management -| API | Description | -| -------------------------------------------------- | -------------------- | -| addWatcher(Watcher watcher): AppEventPackageHolder | Adds an event watcher.| -| removeWatcher(Watcher watcher): void | Removes an event watcher.| +| API | Description | +| -------------------------------------------------- | -------------------------------------------- | +| addWatcher(Watcher watcher): AppEventPackageHolder | Adds an event watcher to subscribe to expected application events.| +| removeWatcher(Watcher watcher): void | Adds an event watcher to unsubscribe from expected application events.| -**Table 4** APIs for clearing logging data +## How to Develop -| API | Description | -| ----------------- | -------------------- | -| clearData(): void | Clears local logging data.| +The following example illustrates how to log and subscribe to button click events of users. -## How to Develop +1. Create an eTS application project. In the displayed **Project** window, choose **entry** > **src** > **main** > **ets** > **entryability** > **EntryAbility.ts**, and double-click **EntryAbility.ts**. Then, add an event watcher to subscribe to button click events. The complete sample code is as follows: -The following uses a one-time event watcher as an example to illustrate the development procedure. + ```js + import hilog from '@ohos.hilog'; + import Ability from '@ohos.application.Ability' + import Window from '@ohos.window' + import hiAppEvent from '@ohos.hiviewdfx.hiAppEvent' + + export default class EntryAbility extends Ability { + onCreate(want, launchParam) { + hilog.isLoggable(0x0000, 'testTag', hilog.LogLevel.INFO); + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? ''); + + hiAppEvent.addWatcher({ + // Add a watcher. You can customize the watcher name. The system identifies different watchers based on their names. + name: "watcher1", + // Subscribe to application events you are interested in, for example, button click events. + appEventFilters: [{ domain: "button" }], + // Set the subscription callback trigger condition. In this example, a callback is triggered if one event is logged. + triggerCondition: { row: 1 }, + // Implement the subscription callback function to apply custom processing to the event logging data obtained through subscription. + onTrigger: function (curRow, curSize, holder) { + // If the watcher incurs an error while it is working, return a null holder object after recording the error in the log. + if (holder == null) { + hilog.error(0x0000, 'testTag', "HiAppEvent holder is null") + return + } + let eventPkg = null + // Fetch the subscription event package based on the specified threshold (512 KB by default) until all subscription event data is fetched. + // If all subscription event data is fetched, return a null event package object. The subscription callback process is ended. + while ((eventPkg = holder.takeNext()) != null) { + // Apply custom processing to the event logging data in the event package, for example, print the event logging data in the log. + hilog.info(0x0000, 'testTag', `HiAppEvent eventPkg.packageId=%{public}d`, eventPkg.packageId) + hilog.info(0x0000, 'testTag', `HiAppEvent eventPkg.row=%{public}d`, eventPkg.row) + hilog.info(0x0000, 'testTag', `HiAppEvent eventPkg.size=%{public}d`, eventPkg.size) + for (const eventInfo of eventPkg.data) { + hilog.info(0x0000, 'testTag', `HiAppEvent eventPkg.info=%{public}s`, eventInfo) + } + } + } + }) + } + } -1. Create an eTS application project. In the displayed **Project** window, choose **entry** > **src** > **main** > **ets** > **pages** > **index.ets**, and double-click **index.ets**. Then, add three buttons to simulate the process of watching for application events. Wherein, button 1 is used to invoke application event logging, button 2 to add an event watcher that automatically triggers a callback, and button 3 to remove the watcher. The complete sample code is as follows: +2. Choose **entry** > **src** > **main** > **ets** > **pages** > **index.ets**, and double-click **index.ets**. Then, add a button, and enable logging of button click events in its **onClick** function. The complete sample code is as follows: - ```ts - import hiAppEvent from '@ohos.hiviewdfx.hiAppEvent'; + ```js + import hiAppEvent from '@ohos.hiviewdfx.hiAppEvent' + import hilog from '@ohos.hilog' @Entry @Component @@ -57,61 +109,21 @@ The following uses a one-time event watcher as an example to illustrate the deve .fontSize(50) .fontWeight(FontWeight.Bold) - Button("1 writeTest").onClick(()=>{ - // Perform event logging based on the input event parameters. + Button("writeTest").onClick(()=>{ + // Enable event logging in the button click function to log button click events. hiAppEvent.write({ - domain: "test_domain", - name: "test_event", - eventType: hiAppEvent.EventType.FAULT, - params: { - int_data: 100, - str_data: "strValue" - } + // Define the event domain. + domain: "button", + // Define the event name. + name: "click", + // Define the event type. + eventType: hiAppEvent.EventType.BEHAVIOR, + // Define event parameters. + params: { click_time: 100 } }).then(() => { - console.log(`HiAppEvent success to write event`); + hilog.info(0x0000, 'testTag', `HiAppEvent success to write event`) }).catch((err) => { - console.error(`code: ${err.code}, message: ${err.message}`); - }); - }) - - Button("2 addWatcherTest").onClick(()=>{ - // Add an event watcher based on the input subscription parameters. - hiAppEvent.addWatcher({ - name: "watcher1", - appEventFilters: [{ domain: "test_domain" }], - triggerCondition: { - row: 2, - size: 1000, - timeOut: 2 - }, - onTrigger: function (curRow, curSize, holder) { - // If the holder object is null, return an error after recording it in the log. - if (holder == null) { - console.error("HiAppEvent holder is null"); - return; - } - // Set the size threshold to 1,000 bytes for obtaining an event package. - holder.setSize(1000); - let eventPkg = null; - // Obtain the event package based on the configured size threshold. If returned event package is null, all event data has been obtained. - while ((eventPkg = holder.takeNext()) != null) { - // Parse the obtained event package and display the result on the Log page. - console.info(`HiAppEvent eventPkg.packageId=${eventPkg.packageId}`); - console.info(`HiAppEvent eventPkg.row=${eventPkg.row}`); - console.info(`HiAppEvent eventPkg.size=${eventPkg.size}`); - // Traverse and parse event string arrays in the obtained event package. - for (const eventInfo of eventPkg.data) { - console.info(`HiAppEvent eventPkg.data=${eventInfo}`); - } - } - } - }); - }) - - Button("3 removeWatcherTest").onClick(()=>{ - // Remove the specified event watcher. - hiAppEvent.removeWatcher({ - name: "watcher1" + hilog.error(0x0000, 'testTag', `HiAppEvent err.code: ${err.code}, err.message: ${err.message}`) }) }) } @@ -121,26 +133,20 @@ The following uses a one-time event watcher as an example to illustrate the deve } } ``` + +3. Touch the run button on the IDE to run the project. Then, touch the **writeTest** button on the application UI to trigger application event logging. -2. Touch the run button on the IDE to run the project. - -3. Touch button 1 on the application UI to start application event logging. If the logging is successful, you'll see the following message in the **Log** window: - - ``` - success to write event: 0 - ``` - -4. On the application UI, touch button 2 to add an event watcher, and touch button 1 for multiple times to perform application event logging. If any callback trigger condition (event count, event data size, and timeout duration) is met, the event watcher will invoke a callback and the event package obtained through the callback will be displayed in the **Log** window. +4. View the information printed in the **Log** window. If logging of the button click event is successful, you will see a message indicating successful event logging as well as the log information specific to processing of the event logging data in the subscription callback. - ``` + ```js + HiAppEvent success to write event + HiAppEvent eventPkg.packageId=0 - HiAppEvent eventPkg.row=2 - HiAppEvent eventPkg.size=308 - HiAppEvent eventPkg.data={"domain_":"test_domain","name_":"test_event","type_":1,"time_":1502096107556,"tz_":"+0000","pid_":4204,"tid_":4223,"int_data":100,"str_data":"strValue"} + HiAppEvent eventPkg.row=1 + HiAppEvent eventPkg.size=124 + HiAppEvent eventPkg.info={"domain_":"button","name_":"click","type_":4,"time_":1670268234523,"tz_":"+0800","pid_":3295,"tid_":3309,"click_time":100} ``` -5. On the application UI, touch button 3 to remove the event watcher. Then, touch button 1 for multiple times to perform application event logging. In such a case, there will be no log information about the callback invoked by the event watcher. - ## Samples The following sample is provided to help you better understand how to develop the application event logging feature: diff --git a/en/application-dev/dfx/hiappevent-overview.md b/en/application-dev/dfx/hiappevent-overview.md deleted file mode 100644 index 2e54f28d8a69623accc2aff1b8dc96f30045f8ed..0000000000000000000000000000000000000000 --- a/en/application-dev/dfx/hiappevent-overview.md +++ /dev/null @@ -1,11 +0,0 @@ -# Overview of Application Event Logging - -The HiAppEvent module provides event logging APIs for applications to log the fault, statistical, security, and user behavior events reported during running. Based on event information, you will be able to analyze the running status of your application. - -You can use this module to develop application event-related functions, including flushing application events to a disk, querying and clearing application events, and customizing application event logging configuration. - -## Basic Concepts - -**Logging** - - A function that logs changes caused by user operations to provide service data for development, product, and O&M analysis. \ No newline at end of file diff --git a/en/application-dev/dfx/hitracechain-guidelines.md b/en/application-dev/dfx/hitracechain-guidelines.md index 06d849872941ab84a894224ef4e3d17ddb8d491d..affd260b0503f3c4f4c4b748d5911d94f7fef9e3 100644 --- a/en/application-dev/dfx/hitracechain-guidelines.md +++ b/en/application-dev/dfx/hitracechain-guidelines.md @@ -1,8 +1,16 @@ # Development of Distributed Call Chain Tracing -## When to Use +## Introduction -HiTraceChain is the module that provides APIs to implement call chain tracing throughout a service process. With HiTraceChain, you can quickly obtain the run log for the call chain of a specified service process and locate faults in inter-device, inter-process, or inter-thread communications. +The hiTraceChain module provides APIs to implement call chain tracing throughout a service process. This can help you quickly obtain the run log for the call chain of a specified service process and locate faults in inter-device, inter-process, or inter-thread communications. + +hiTraceChain is a lightweight implementation of the cloud-based distributed call chain tracing. It allows applications to trace cross-thread, cross-process, and cross-device service calls. The hiTraceChain module generates a unique **chainId** for a service process and passes it to various information (including application events, system time, and logs) specific to the service process. During debugging and fault locating, you can use the unique **chainId** to quickly correlate various information related to the service process. + +## Basic Concepts + +- **chainId** + + Distributed call chain tracing ID, which is a part of **HiTraceId** and is used to identify the service process being traced. ## Available APIs diff --git a/en/application-dev/dfx/hitracechain-overview.md b/en/application-dev/dfx/hitracechain-overview.md deleted file mode 100644 index 64eae517ace23beb6e3ad80bc7b6f0df1ef9b34a..0000000000000000000000000000000000000000 --- a/en/application-dev/dfx/hitracechain-overview.md +++ /dev/null @@ -1,17 +0,0 @@ -# Overview of Distributed Call Chain Tracing - -hiTraceChain is a lightweight implementation of the cloud-based distributed call chain tracing. It allows applications to trace cross-thread, cross-process, and cross-device service calls. - -## Basic Concepts - -- **chainId** - - Distributed call chain tracing ID, which is a part of **HiTraceId** and is used to identify the service process being traced. - -## Working Principles - -The hiTraceChain module generates a unique **chainId** for a service process and passes it to various information (including application events, system time, and logs) specific to the service process. During debugging and fault locating, you can use the unique **chainId** to quickly correlate various information related to the service process. - -## Constraints - -All APIs provided by the hiTraceChain module work in synchronous mode. diff --git a/en/application-dev/dfx/hitracemeter-guidelines.md b/en/application-dev/dfx/hitracemeter-guidelines.md index 1b45886ca4c593bbfff1b1b07d5892ad20ba58ae..2b8b7a562a7e896db40faba9de194777c4d1c170 100644 --- a/en/application-dev/dfx/hitracemeter-guidelines.md +++ b/en/application-dev/dfx/hitracemeter-guidelines.md @@ -1,8 +1,23 @@ # Development of Performance Tracing -## When to Use +## Introduction -HiTraceMeter provides APIs for system performance tracing. You can call the APIs provided by HiTraceMeter module in your own service logic to effectively track service processes and check the system performance. +hiTraceMeter provides APIs for system performance tracing. You can call the APIs provided by the hiTraceMeter module in your own service logic to effectively track service processes and check the system performance. + +## Basic Concepts + +- **hiTraceMeter Tag** + + Tag used for tracing data categorization. It is also known as **hiTraceMeter Category**. Generally, one subsystem maps to a tag. The tag is passed as the **Tag** parameter in performance tracing APIs. When you use the hiTraceMeter CLI tool to collect tracing data, only the tracing data specified by the **Tag** parameter is collected. + +## Working Principles + +- The application calls hiTraceMeter APIs to perform performance tracing. The APIs output the tracing data to the kernel's ftrace data buffer through the kernel's sysfs file interface. +- The hiTraceMeter CLI tool reads the tracing data in the ftrace data buffer and saves the trace data as a text file on the device. + +## Constraints + +Due to the asynchronous I/O feature of JS, the hiTraceMeter module provides only asynchronous APIs. ## Available APIs diff --git a/en/application-dev/dfx/hitracemeter-overview.md b/en/application-dev/dfx/hitracemeter-overview.md deleted file mode 100644 index 649fa7704dd566ab8bc02776de6f62756d7f26a6..0000000000000000000000000000000000000000 --- a/en/application-dev/dfx/hitracemeter-overview.md +++ /dev/null @@ -1,18 +0,0 @@ -# Overview of Performance Tracing - -hiTraceMeter is a tool for you to trace service processes and monitor system performance. Through encapsulating and extending the ftrace inside the kernel, hiTraceMeter supports performance tracing for code execution in the user space. You can use hiTraceMeter APIs to implement performance tracing and use the hiTraceMeter CLI tool to collect traced data. - -## Basic Concepts - -- **hiTraceMeter Tag** - - Tag used for tracing data categorization. It is also known as **hiTraceMeter Category**. Generally, one subsystem maps to a tag. The tag is passed as the **Tag** parameter in performance tracing APIs. When you use the hiTraceMeter CLI tool to collect tracing data, only the tracing data specified by the **Tag** parameter is collected. - -## Working Principles - -- The application calls hiTraceMeter APIs to perform performance tracing. The APIs output the tracing data to the kernel's ftrace data buffer through the kernel's sysfs file interface. -- The hiTraceMeter CLI tool reads the tracing data in the ftrace data buffer and saves the trace data as a text file on the device. - -## Constraints - -Due to the asynchronous I/O feature of JS, the hiTraceMeter module provides only asynchronous APIs. diff --git a/en/application-dev/quick-start/arkts-rendering-control.md b/en/application-dev/quick-start/arkts-rendering-control.md index dff2cda50c02afabc15d0f5c8bb576218cab316e..d0ff5a8c183d8efba03b12f7343f001a3ba31fe5 100644 --- a/en/application-dev/quick-start/arkts-rendering-control.md +++ b/en/application-dev/quick-start/arkts-rendering-control.md @@ -34,7 +34,7 @@ Column() { You can use **ForEach** to obtain data from arrays and create components for each data item. -``` +```ts ForEach( arr: any[], itemGenerator: (item: any, index?: number) => void, @@ -275,7 +275,7 @@ struct MyComponent { > > ```ts > LazyForEach(dataSource, -> item => Text(`${item.i}. item.data.label`)), +> item => Text(`${item.i}. item.data.label`), > item => item.data.id.toString()) > ``` diff --git a/en/application-dev/quick-start/figures/alarm.png b/en/application-dev/quick-start/figures/alarm.png new file mode 100644 index 0000000000000000000000000000000000000000..d8710f4cb2d41a8f9dde0be779909867aa237536 Binary files /dev/null and b/en/application-dev/quick-start/figures/alarm.png differ diff --git a/en/application-dev/quick-start/figures/alarmHand.png b/en/application-dev/quick-start/figures/alarmHand.png new file mode 100644 index 0000000000000000000000000000000000000000..020ae09b94904b6b89e4503b7139dcc2843daeb2 Binary files /dev/null and b/en/application-dev/quick-start/figures/alarmHand.png differ diff --git a/en/application-dev/quick-start/full-sdk-switch-guide.md b/en/application-dev/quick-start/full-sdk-switch-guide.md index 818249975bfd00cd582414549237f955fec1fcb8..f9116ce7ead9c4dbcf15f9d7e6b88a1d8b274d6d 100644 --- a/en/application-dev/quick-start/full-sdk-switch-guide.md +++ b/en/application-dev/quick-start/full-sdk-switch-guide.md @@ -4,7 +4,7 @@ Both the public SDK and full SDK are toolkits for application development.
T The full SDK is intended for original equipment manufacturers (OEMs) and provided separately. It contains system APIs. -The SDK of API version 8 provided in DevEco Studio is a public SDK. If your project depends on any system API, such as the **animator** component, **xcomponent** component, or APIs in **@ohos.application.abilityManager.d.ts**, **@ohos.application.formInfo.d.ts**, or **@ohos.bluetooth.d.ts**, switch to the full SDK by performing the following steps. +The SDK of API version 8 provided in DevEco Studio is a public SDK. If your project depends on any system API, such as the **animator** component, **XComponent**, or APIs in **@ohos.application.abilityManager.d.ts**, **@ohos.application.formInfo.d.ts**, or **@ohos.bluetooth.d.ts**, switch to the full SDK by performing the following steps. > **NOTE** > @@ -16,7 +16,8 @@ Manually download the system-specific full SDK package from the mirror. For deta ## Checking the Local SDK Location -In this example, an ArkTS project is used. For a JS project, replace **ets** with **js**. +In this example, an eTS project is used. For a JS project, replace **ets** with **js**. + In DevEco Studio, choose **Tools** > **OpenHarmony SDK Manager** to check the location of the local SDK. @@ -35,11 +36,15 @@ In DevEco Studio, choose **Tools** > **OpenHarmony SDK Manager** to check the lo b. Verify that the SDK contains system APIs (such as APIs defined in **@ohos.application.abilityManager.d.ts**, **@ohos.application.formInfo.d.ts**, and **@ohos.bluetooth.d.ts**). - Note: The criteria for identifying system APIs are subject to the released API documentation. + Note: The criteria for identifying system APIs are subject to the official API documentation. + + 2. Replace the SDK. The following uses public-SDK-3.x.x.x for Windows as an example. - a. Decompress the downloaded full SDK file: `ets-windows-3.x.x.x-Release.zip` + + + a. Decompress the downloaded full SDK file: **ets-windows-3.x.x.x-Release.zip** ![image-20220613165018184](figures/en-us_image_0000001655129264.png) @@ -51,13 +56,13 @@ In DevEco Studio, choose **Tools** > **OpenHarmony SDK Manager** to check the lo ![image-20220613161352157](figures/en-us_image_0000001655129041.png) - Note: The name of the backup version directory must be different from the value of **version** field in the **oh-uni-package.json** file. In the example below, the name of the backup version directory is **3.x.x.x_backup**. + Note: The name of the backup version directory must be different from the value of the **version** field in the **oh-uni-package.json** file. In the example below, the name of the backup version directory is **3.1.6.6_backup**. ![image-20220613165018184](figures/en-us_image_0000001655129398.png) - The configuration in the **oh-uni-package.json** file is as follows, where the value of `apiVersion` is subject to the API version of the SDK, and the value of `version` is subject to the version number in the SDK file. + The configuration in the **oh-uni-package.json** file is as follows, where the value of **apiVersion** is subject to the API version of the SDK, and the value of **version** is subject to the version number in the SDK file. - ``` + ```json { "apiVersion": "X", "displayName": "Ets", @@ -71,24 +76,42 @@ In DevEco Studio, choose **Tools** > **OpenHarmony SDK Manager** to check the lo ``` - Delete all files in the original SDK (3.x.x.x) directory. Failure to do so may result in some files being unable to be overwritten. + **Delete all files in the original SDK (3.x.x.x) directory.** Failure to do so may result in some files being unable to be overwritten. Copy the full SDK to the location of the local SDK. - Copy all files in the **ets** directory in the full SDK to the **ets\*3.x.x.x*** directory in the location of the local SDK. + Copy all files in the **ets** directory in the full SDK to the **ets\3.x.x.x** directory in the location of the local SDK. Change the value of **version** in the **oh-uni-package.json** file to the current SDK version number. - In the ***3.x.x.x*\build-tools\ets-loader** directory, open the **cmd/powerShell** window and run the `npm install` command to download the **node_modules** dependency package. + In the ***3.x.x.x*\build-tools\ets-loader** directory, open the **cmd/powerShell** window and run the **npm install** command to download the **node_modules** dependency package. ![image-20220613171111405](figures/en-us_image_0000001655129333.png) c. Check for system APIs. - + ![image-20220613213038104](figures/en-us_image_0000001655129372.png) + +## Appendix: macOS Security Alarm Handling + +After the SDK is switched to the full SDK in DevEco Studio on macOS, an alarm is generated when the Previewer is opened. + +![alarm](figures/alarm.png) + +To clear the alarm, perform the following steps: + +1. Start the Terminal application. + +2. In Terminal, run **sudo spctl -- master - disable**. + +3. In **System Preferences**, choose **Security & Privacy**, click the **General** tab and select **Anywhere** under **Allow apps downloaded from**. + +![alarmHand](figures/alarmHand.png) + +Now, applications downloaded from third-party sources will not be blocked, meaning that you can open the Previewer. For security purposes, change the **Allow apps downloaded from** settings back to the original option when the Previewer is not in use. diff --git a/en/application-dev/quick-start/resource-categories-and-access.md b/en/application-dev/quick-start/resource-categories-and-access.md index b79359a99ee1f7ecf434a7858a7ee1999b9af5d5..56e8209a5c19e353a21b80ff8b34dd51885db310 100644 --- a/en/application-dev/quick-start/resource-categories-and-access.md +++ b/en/application-dev/quick-start/resource-categories-and-access.md @@ -83,6 +83,7 @@ You can create resource group subdirectories (including element, media, and prof | ------- | ---------------------------------------- | ---------------------------------------- | | element | Indicates element resources. Each type of data is represented by a JSON file. The options are as follows:
- **boolean**: boolean data
- **color**: color data
- **float**: floating-point data
- **intarray**: array of integers
- **integer**: integer data
- **pattern**: pattern data
- **plural**: plural form data
- **strarray**: array of strings
- **string**: string data| It is recommended that files in the **element** subdirectory be named the same as the following files, each of which can contain only data of the same type:
- boolean.json
- color.json
- float.json
- intarray.json
- integer.json
- pattern.json
- plural.json
- strarray.json
- string.json | | media | Indicates media resources, including non-text files such as images, audios, and videos. | The file name can be customized, for example, **icon.png**. | +| profile | Indicates a user-defined configuration file. You can obtain the file content by using the [getProfileByAbility](../reference/apis/js-apis-bundleManager.md#bundlemanagergetprofilebyability) API. | The file name can be customized, for example, **test_profile.json**. | | rawfile | Indicates other types of files, which are stored in their raw formats after the application is built as an HAP file. They will not be integrated into the **resources.index** file.| The file name can be customized. | **Media Resource Types** diff --git a/en/application-dev/reference/apis/Readme-EN.md b/en/application-dev/reference/apis/Readme-EN.md index 76d12ed38f81bdf496fd228f9cbea11eb8422510..13110f9784e44ab0d406917924394ef5b84fc470 100644 --- a/en/application-dev/reference/apis/Readme-EN.md +++ b/en/application-dev/reference/apis/Readme-EN.md @@ -16,7 +16,7 @@ - [@ohos.app.ability.StartOptions](js-apis-app-ability-startOptions.md) - [@ohos.app.ability.UIAbility](js-apis-app-ability-uiAbility.md) - [@ohos.app.form.FormExtensionAbility](js-apis-app-form-formExtensionAbility.md) - - [@ohos.application.DataShareExtensionAbility](js-apis-application-DataShareExtensionAbility.md) + - [@ohos.application.DataShareExtensionAbility](js-apis-application-dataShareExtensionAbility.md) - [@ohos.application.StaticSubscriberExtensionAbility](js-apis-application-staticSubscriberExtensionAbility.md) - Stage Model (To Be Deprecated Soon) - [@ohos.application.Ability](js-apis-application-ability.md) @@ -212,7 +212,7 @@ - [@ohos.data.fileAccess](js-apis-fileAccess.md) - [@ohos.fileExtensionInfo](js-apis-fileExtensionInfo.md) - [@ohos.fileio](js-apis-fileio.md) - - [@ohos.filemanagement.userFileManager](js-apis-userfilemanager.md) + - [@ohos.filemanagement.userFileManager](js-apis-userFileManager.md) - [@ohos.multimedia.medialibrary](js-apis-medialibrary.md) - [@ohos.securityLabel](js-apis-securityLabel.md) - [@ohos.statfs](js-apis-statfs.md) diff --git a/en/application-dev/reference/apis/js-apis-animator.md b/en/application-dev/reference/apis/js-apis-animator.md index 4086ca77e506b148c95fdf81e942f44642a5ffca..da7ec7d145779eb5044427fdee758a34f6b33fdc 100644 --- a/en/application-dev/reference/apis/js-apis-animator.md +++ b/en/application-dev/reference/apis/js-apis-animator.md @@ -40,10 +40,10 @@ Creates an **Animator** object. easing: 'friction', delay: 0, fill: 'forwards', - direction: "normal", + direction: 'normal', iterations: 3, begin: 200.0, - end: 400.0, + end: 400.0 }; animator.create(options); ``` @@ -83,10 +83,10 @@ let options = { easing: 'friction', delay: 0, fill: 'forwards', - direction: "normal", + direction: 'normal', iterations: 3, begin: 200.0, - end: 400.0, + end: 400.0 }; try { animator.reset(options); @@ -283,7 +283,7 @@ export default { easing: 'friction', delay: 0, fill: 'forwards', - direction: "normal", + direction: 'normal', iterations: 2, begin: 200.0, end: 400.0 @@ -516,7 +516,7 @@ let options = { easing: 'friction', delay: 0, fill: 'forwards', - direction: "normal", + direction: 'normal', iterations: 3, begin: 200.0, end: 400.0, diff --git a/en/application-dev/reference/apis/js-apis-application-DataShareExtensionAbility.md b/en/application-dev/reference/apis/js-apis-application-dataShareExtensionAbility.md similarity index 91% rename from en/application-dev/reference/apis/js-apis-application-DataShareExtensionAbility.md rename to en/application-dev/reference/apis/js-apis-application-dataShareExtensionAbility.md index 7798cdee3d2f71f54e7cc6937816cbb4c253a833..c6192ce1235b2c75607e92788b68fd635dddaffd 100644 --- a/en/application-dev/reference/apis/js-apis-application-DataShareExtensionAbility.md +++ b/en/application-dev/reference/apis/js-apis-application-dataShareExtensionAbility.md @@ -1,6 +1,6 @@ -# Data Share Extension Ability +# @ohos.application.DataShareExtensionAbility -The **DataShareExtensionAbility** module provides Extension abilities for data share services. +The **DataShareExtensionAbility** module provides extension abilities for data share services. >**NOTE** > @@ -23,7 +23,7 @@ import DataShareExtensionAbility from '@ohos.application.DataShareExtensionAbili | Name| Type| Readable| Writable| Description| | -------- | -------- | -------- | -------- | -------- | -| context | [ExtensionContext](js-apis-extension-context.md) | Yes| No|Context of the DataShare Extension ability.| +| context | [ExtensionContext](js-apis-inner-application-extensionContext.md) | Yes| No|Context of the DataShare Extension ability.| ## onCreate @@ -37,7 +37,7 @@ Called by the server to initialize service logic when the DataShare client conne | Name| Type| Mandatory| Description| | ----- | ------ | ------ | ------ | -| want | [Want](js-apis-application-Want.md#want) | Yes | **Want** information, including the ability name and bundle name.| +| want | [Want](js-apis-application-want.md#want) | Yes | **Want** information, including the ability name and bundle name.| | callback | AsyncCallback<void> | Yes| Callback that returns no value.| **Example** @@ -83,7 +83,7 @@ Inserts data into the database. This API can be overridden as required. | Name| Type| Mandatory| Description| | ----- | ------ | ------ | ------ | | uri |string | Yes | URI of the data to insert.| -| valueBucket |[ValuesBucket](js-apis-data-ValuesBucket.md#valuesbucket) | Yes| Data to insert.| +| valueBucket |[ValuesBucket](js-apis-data-valuesBucket.md#valuesbucket) | Yes| Data to insert.| | callback |AsyncCallback<number> | Yes| Callback invoked to return the index of the data inserted.| **Example** @@ -127,8 +127,8 @@ Updates data in the database. This API can be overridden as required. | Name| Type| Mandatory| Description| | ----- | ------ | ------ | ------ | | uri | string | Yes | URI of the data to update.| -| predicates | [DataSharePredicates](js-apis-data-dataSharePredicates.md#datasharepredicates) | Yes | Filter criteria for updating data.| -| valueBucket | [ValuesBucket](js-apis-data-ValuesBucket.md#valuesbucket) | Yes| New data.| +| predicates | [dataSharePredicates.DataSharePredicates](js-apis-data-dataSharePredicates.md#datasharepredicates) | Yes | Filter criteria for updating data.| +| valueBucket | [ValuesBucket](js-apis-data-valuesBucket.md#valuesbucket) | Yes| New data.| | callback | AsyncCallback<number> | Yes| Callback invoked to return the number of updated data records.| **Example** @@ -170,7 +170,7 @@ Deletes data from the database. This API can be overridden as required. | Name | Type | Mandatory| Description | | ---------- | ------------------------------------------------------------ | ---- | ---------------------------------- | | uri | string | Yes | URI of the data to delete. | -| predicates | [DataSharePredicates](js-apis-data-dataSharePredicates.md#datasharepredicates) | Yes | Filter criteria for deleting data. | +| predicates | [dataSharePredicates.DataSharePredicates](js-apis-data-dataSharePredicates.md#datasharepredicates) | Yes | Filter criteria for deleting data. | | callback | AsyncCallback<number> | Yes | Callback invoked to return the number of data records deleted.| **Example** @@ -212,7 +212,7 @@ Queries data from the database. This API can be overridden as required. | Name| Type| Mandatory| Description| | ----- | ------ | ------ | ------ | | uri | string | Yes | URI of the data to query.| -| predicates | [DataSharePredicates](js-apis-data-dataSharePredicates.md#datasharepredicates) | Yes | Filter criteria for querying data.| +| predicates | [dataSharePredicates.DataSharePredicates](js-apis-data-dataSharePredicates.md#datasharepredicates) | Yes | Filter criteria for querying data.| | columns | Array<string> | Yes| Columns to query. If this parameter is empty, all columns will be queried.| | callback | AsyncCallback<Object> | Yes| Callback invoked to return the result set.| @@ -255,10 +255,10 @@ Batch inserts data into the database. This API is called by the server and can b **Parameters** -| Name | Type | Mandatory| Description | +| Name | Type | Mandatory| Description | | ------------ | ------------------------------------------------------------ | ---- | -------------------------------- | | uri | string | Yes | URI of the data to insert. | -| valueBuckets | Array<[ValuesBucket](js-apis-data-ValuesBucket.md#valuesbucket)> | Yes | Data to insert. | +| valueBuckets | Array<[ValuesBucket](js-apis-data-valuesBucket.md#valuesbucket)> | Yes | Data to insert. | | callback | AsyncCallback<number> | Yes | Callback invoked to return the number of inserted data records.| **Example** diff --git a/en/application-dev/reference/apis/js-apis-call.md b/en/application-dev/reference/apis/js-apis-call.md index 82741c1432d9d4fd9c5babef17548bb643cf2dd9..7c5bd52bd9ccbc5ee7ad99b8a1e7311ce8c5f8d5 100644 --- a/en/application-dev/reference/apis/js-apis-call.md +++ b/en/application-dev/reference/apis/js-apis-call.md @@ -1704,7 +1704,7 @@ This is a system API. | Name | Type | Mandatory| Description | | -------- | ------------------------------------------------------ | ---- | -------------------------- | | type | string | Yes | Cause of the call disconnection.| -| callback | Callback<[DisconnectedDetails](#disconnecteddetails8)> | Yes | Callback used to return the result. | +| callback | Callback<[DisconnectedDetails](#disconnecteddetails9)> | Yes | Callback used to return the result. | **Example** @@ -1812,7 +1812,7 @@ This is a system API. | Name | Type | Mandatory| Description | | -------- | ---------------------------------------------------------- | ---- | -------------------- | | type | 'callDisconnectedCause' | Yes | Unsubscription from the call disconnection cause when a call ends.| -| callback | Callback**<**[DisconnectedDetails](#disconnecteddetails8)> | No | Callback used to return the result. | +| callback | Callback**<**[DisconnectedDetails](#disconnecteddetails9)> | No | Callback used to return the result. | **Example** @@ -2908,11 +2908,15 @@ This is a system API. **System capability**: SystemCapability.Telephony.CallManager -| Name | Type | Mandatory| Description | -| ----------- | ---------------------------------------------------- | ---- | ---------------- | -| transferNum | string | Yes | Call transfer number. | -| type | [CallTransferType](#calltransfertype8) | Yes | Call transfer type. | -| settingType | [CallTransferSettingType](#calltransfersettingtype8) | Yes | Call transfer setting type.| +| Name | Type | Mandatory| Description | +| ------------------------ | ---------------------------------------------------- | ---- | ---------------- | +| transferNum | string | Yes | Call transfer number. | +| type | [CallTransferType](#calltransfertype8) | Yes | Call transfer type. | +| settingType | [CallTransferSettingType](#calltransfersettingtype8) | Yes | Call transfer setting type.| +| startHour9+ | number | No | Hour in the start time.| +| startMinute9+ | number | No | Minute in the start time.| +| endHour9+ | number | No | Hour in the end time.| +| endMinute9+ | number | No | Minute in the end time.| ## CallTransferType8+ @@ -3128,10 +3132,14 @@ This is a system API. **System capability**: SystemCapability.Telephony.CallManager -| Name| Type | Mandatory| Description | -| ------ | ---------------------------------- | ---- | -------- | -| status | [TransferStatus](#transferstatus8) | Yes | Transfer status.| -| number | string | Yes | Number. | +| Name | Type | Mandatory| Description | +| ------------------------ | ---------------------------------- | ---- | ---------------- | +| status | [TransferStatus](#transferstatus8) | Yes | Call transfer status. | +| number | string | Yes | Call transfer number. | +| startHour9+ | number | Yes | Hour in the start time.| +| startMinute9+ | number | Yes | Minute in the start time.| +| endHour9+ | number | Yes | Hour in the end time.| +| endMinute9+ | number | Yes | Minute in the end time.| ## CallWaitingStatus7+ @@ -3172,7 +3180,20 @@ This is a system API. | TRANSFER_DISABLE | 0 | Call transfer disabled.| | TRANSFER_ENABLE | 1 | Call transfer enabled.| -## DisconnectedDetails8+ +## DisconnectedDetails9+ + +Defines the cause of a call disconnection. + +This is a system API. + +**System capability**: SystemCapability.Telephony.CallManager + +| Name | Type | Mandatory| Description | +| ------- | ------------------------------------------ | ---- | --------------- | +| reason | [DisconnectedReason](#disconnectedreason8) | Yes | Cause of the call disconnection. | +| message | string | Yes | Message indicating the call disconnection.| + +## DisconnectedReason8+ Enumerates causes of call disconnection. @@ -3180,28 +3201,87 @@ This is a system API. **System capability**: SystemCapability.Telephony.CallManager -| Name | Value | Description | -| --------------------------- | ---- | ---------------------- | -| UNASSIGNED_NUMBER | 1 | Unallocated number. | -| NO_ROUTE_TO_DESTINATION | 3 | No route to the destination. | -| CHANNEL_UNACCEPTABLE | 6 | Unacceptable channel. | -| OPERATOR_DETERMINED_BARRING | 8 | Operator determined barring (ODB). | -| NORMAL_CALL_CLEARING | 16 | Normal call clearing. | -| USER_BUSY | 17 | User busy. | -| NO_USER_RESPONDING | 18 | No user response. | -| USER_ALERTING_NO_ANSWER | 19 | Alerting but no answer.| -| CALL_REJECTED | 21 | Call rejected. | -| NUMBER_CHANGED | 22 | Number changed. | -| DESTINATION_OUT_OF_ORDER | 27 | Destination fault. | -| INVALID_NUMBER_FORMAT | 28 | Invalid number format. | -| NETWORK_OUT_OF_ORDER | 38 | Network fault. | -| TEMPORARY_FAILURE | 41 | Temporary fault. | -| INVALID_PARAMETER | 1025 | Invalid parameter. | -| SIM_NOT_EXIT | 1026 | SIM card not exit. | -| SIM_PIN_NEED | 1027 | SIM card PIN required. | -| CALL_NOT_ALLOW | 1029 | Call not allowed. | -| SIM_INVALID | 1045 | Invalid SIM card. | -| UNKNOWN | 1279 | Unknown reason. | +| Name | Value | Description | +| ------------------------------------------------------------ | ---- | --------------------------------------- | +| UNASSIGNED_NUMBER | 1 | Unallocated (unassigned) number. | +| NO_ROUTE_TO_DESTINATION | 3 | No route to destination. | +| CHANNEL_UNACCEPTABLE | 6 | Channel unacceptable. | +| OPERATOR_DETERMINED_BARRING | 8 | Operator determined barring (ODB). | +| CALL_COMPLETED_ELSEWHERE9+ | 13 | Call completed elsewhere. | +| NORMAL_CALL_CLEARING | 16 | Normal call clearing. | +| USER_BUSY | 17 | User busy. | +| NO_USER_RESPONDING | 18 | No user responding. | +| USER_ALERTING_NO_ANSWER | 19 | User alerting, no answer. | +| CALL_REJECTED | 21 | Call rejected. | +| NUMBER_CHANGED | 22 | Number changed. | +| CALL_REJECTED_DUE_TO_FEATURE_AT_THE_DESTINATION9+ | 24 | Call rejected due to feature at the destination.| +| FAILED_PRE_EMPTION9+ | 25 | Failed preemption. | +| NON_SELECTED_USER_CLEARING9+ | 26 | Non-selected user clearing. | +| DESTINATION_OUT_OF_ORDER | 27 | Destination out of order. | +| INVALID_NUMBER_FORMAT | 28 | Invalid number format (incomplete number). | +| FACILITY_REJECTED9+ | 29 | Facility rejected. | +| RESPONSE_TO_STATUS_ENQUIRY9+ | 30 | Response to status enquiry. | +| NORMAL_UNSPECIFIED9+ | 31 | Normal, unspecified. | +| NO_CIRCUIT_CHANNEL_AVAILABLE9+ | 34 | No circuit/channel available. | +| NETWORK_OUT_OF_ORDER | 38 | Network fault. | +| TEMPORARY_FAILURE | 41 | Temporary failure. | +| SWITCHING_EQUIPMENT_CONGESTION9+ | 42 | Switching equipment congestion. | +| ACCESS_INFORMATION_DISCARDED9+ | 43 | Access information discarded. | +| REQUEST_CIRCUIT_CHANNEL_NOT_AVAILABLE9+ | 44 | Requested circuit/channel unavailable | +| RESOURCES_UNAVAILABLE_UNSPECIFIED9+ | 47 | Resources unavailable, unspecified. | +| QUALITY_OF_SERVICE_UNAVAILABLE9+ | 49 | QoS unavailable. | +| REQUESTED_FACILITY_NOT_SUBSCRIBED9+ | 50 | Requested facility not subscribed. | +| INCOMING_CALLS_BARRED_WITHIN_THE_CUG9+ | 55 | Incoming calls barred within the CUG. | +| BEARER_CAPABILITY_NOT_AUTHORIZED9+ | 57 | Bearer capability not authorized. | +| BEARER_CAPABILITY_NOT_PRESENTLY_AVAILABLE9+ | 58 | Bearer capability presently available. | +| SERVICE_OR_OPTION_NOT_AVAILABLE_UNSPECIFIED9+ | 63 | Service or option not available, unspecified. | +| BEARER_SERVICE_NOT_IMPLEMENTED9+ | 65 | Bearer service not implemented. | +| ACM_EQUALTO_OR_GREATER_THAN_THE_MAXIMUM_VALUE9+ | 68 | ACM greater than or equal to the maximum value. | +| REQUESTED_FACILITY_NOT_IMPLEMENTED9+ | 69 | Requested facility not implemented. | +| ONLY_RESTRICTED_DIGITAL_INFO_BEARER_CAPABILITY_IS_AVAILABLE9+ | 70 | Only restricted digital information capability available. | +| SERVICE_OR_OPTION_NOT_IMPLEMENTED_UNSPECIFIED9+ | 79 | Service or option not implemented, unspecified. | +| INVALID_TRANSACTION_IDENTIFIER_VALUE9+ | 81 | Invalid transaction identifier value. | +| USER_NOT_MEMBER_OF_CUG9+ | 87 | User not member of CUG. | +| INCOMPATIBLE_DESTINATION9+ | 88 | Incompatible destination. | +| INVALID_TRANSIT_NETWORK_SELECTION9+ | 91 | Invalid transit network selection. | +| SEMANTICALLY_INCORRECT_MESSAGE9+ | 95 | Semantically incorrect message. | +| INVALID_MANDATORY_INFORMATION9+ | 96 | Invalid mandatory information. | +| MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED9+ | 97 | Message type non-existent or not implemented. | +| MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE9+ | 98 | Message type not compatible with protocol state. | +| INFORMATION_ELEMENT_NON_EXISTENT_OR_NOT_IMPLEMENTED9+ | 99 | IE non-existent or not implemented. | +| CONDITIONAL_IE_ERROR9+ | 100 | Conditional IE error. | +| MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE9+ | 101 | Message not compatible with protocol state. | +| RECOVERY_ON_TIMER_EXPIRED9+ | 102 | Recovery on timer expiry. | +| PROTOCOL_ERROR_UNSPECIFIED9+ | 111 | Protocol error, unspecified. | +| INTERWORKING_UNSPECIFIED9+ | 127 | Interworking, unspecified. | +| CALL_BARRED9+ | 240 | Call barred. | +| FDN_BLOCKED9+ | 241 | FDN blocked. | +| IMSI_UNKNOWN_IN_VLR9+ | 242 | IMSI unknown in VLR. | +| IMEI_NOT_ACCEPTED9+ | 243 | IMEI not accepted. | +| DIAL_MODIFIED_TO_USSD9+ | 244 | Dial request modified to USSD request. | +| DIAL_MODIFIED_TO_SS9+ | 245 | Dial request modified to SS request. | +| DIAL_MODIFIED_TO_DIAL9+ | 246 | Dial request modified to dial with different number. | +| RADIO_OFF9+ | 247 | Radio off. | +| OUT_OF_SERVICE9+ | 248 | Out of service. | +| NO_VALID_SIM9+ | 249 | No valid SIM. | +| RADIO_INTERNAL_ERROR9+ | 250 | Radio internal error. | +| NETWORK_RESP_TIMEOUT9+ | 251 | Network response timeout. | +| NETWORK_REJECT9+ | 252 | Request rejected by network. | +| RADIO_ACCESS_FAILURE9+ | 253 | Radio access failure. | +| RADIO_LINK_FAILURE9+ | 254 | Radio link failure. | +| RADIO_LINK_LOST9+ | 255 | Radio link lost. | +| RADIO_UPLINK_FAILURE9+ | 256 | Radio uplink failure. | +| RADIO_SETUP_FAILURE9+ | 257 | Radio setup failure. | +| RADIO_RELEASE_NORMAL9+ | 258 | Radio release normal. | +| RADIO_RELEASE_ABNORMAL9+ | 259 | Radio release abnormal. | +| ACCESS_CLASS_BLOCKED9+ | 260 | Access class blocked. | +| NETWORK_DETACH9+ | 261 | Network detached. | +| INVALID_PARAMETER | 1025 | Invalid parameter. | +| SIM_NOT_EXIT | 1026 | SIM not exit. | +| SIM_PIN_NEED | 1027 | SIM PIN needed. | +| CALL_NOT_ALLOW | 1029 | Call not allowed. | +| SIM_INVALID | 1045 | No valid SIM. | +| UNKNOWN | 1279 | Unknown reason. | ## MmiCodeResults9+ diff --git a/en/application-dev/reference/apis/js-apis-data-storage.md b/en/application-dev/reference/apis/js-apis-data-storage.md index b724dfabc1fed1e99d98ad5bba715d81d91677b8..8df3ab1e84ff92e39f31566416a34c4ffb3afa9b 100644 --- a/en/application-dev/reference/apis/js-apis-data-storage.md +++ b/en/application-dev/reference/apis/js-apis-data-storage.md @@ -1,6 +1,6 @@ -# Lightweight Storage +# @ohos.data.storage -Lightweight storage provides applications with data processing capability and allows applications to perform lightweight data storage and query. Data is stored in key-value (KV) pairs. Keys are of the string type, and values can be of the number, string, or Boolean type. +The **DataStorage** module provides applications with data processing capability and allows applications to perform lightweight data storage and query. Data is stored in key-value (KV) pairs. Keys are of the string type, and values can be of the number, string, or Boolean type. > **NOTE** diff --git a/en/application-dev/reference/apis/js-apis-http.md b/en/application-dev/reference/apis/js-apis-http.md index 683ecdb676eacc3267f0570c02e7c059170fb68c..36faaa094260d0d86f065040f3a99de323fa3d00 100644 --- a/en/application-dev/reference/apis/js-apis-http.md +++ b/en/application-dev/reference/apis/js-apis-http.md @@ -72,7 +72,7 @@ Creates an HTTP request. You can use this API to initiate or destroy an HTTP req **Return value** | Type | Description | -| :---------- | :----------------------------------------------------------- | +| ---------- | ----------------------------------------------------------- | | HttpRequest | An **HttpRequest** object, which contains the **request**, **destroy**, **on**, or **off** method.| **Example** @@ -181,7 +181,7 @@ Initiates an HTTP request to a given URL. This API uses a promise to return the **Return value** | Type | Description | -| :------------------------------------- | :-------------------------------- | +| ------------------------------------- | -------------------------------- | | Promise<[HttpResponse](#httpresponse)> | Promise used to return the result.| @@ -374,7 +374,7 @@ Defines an HTTP request method. **System capability**: SystemCapability.Communication.NetStack | Name | Value | Description | -| :------ | ------- | :------------------ | +| ------ | ------- | ------------------ | | OPTIONS | "OPTIONS" | OPTIONS method.| | GET | "GET" | GET method. | | HEAD | "HEAD" | HEAD method. | @@ -459,7 +459,7 @@ Creates a default object to store responses to HTTP access requests. **Return value** | Type | Description | -| :---------- | :----------------------------------------------------------- | +| ---------- | ----------------------------------------------------------- | | [HttpResponseCache](#httpresponsecache9) | Object that stores the response to the HTTP request.| **Example** @@ -602,6 +602,6 @@ Enumerates HTTP protocol versions. **System capability**: SystemCapability.Communication.NetStack | Name | Description | -| :-------- | :----------- | +| -------- | ----------- | | HTTP1_1 | HTTP1.1 | | HTTP2 | HTTP2 | diff --git a/en/application-dev/reference/apis/js-apis-inputdevice.md b/en/application-dev/reference/apis/js-apis-inputdevice.md index 9ed326b92bb458a475f47ee29aeee01f681cf5b4..29a9d739a1cd77bfd030beee38380dc870440444 100644 --- a/en/application-dev/reference/apis/js-apis-inputdevice.md +++ b/en/application-dev/reference/apis/js-apis-inputdevice.md @@ -33,7 +33,7 @@ Obtains the IDs of all input devices. This API uses an asynchronous callback to ```js try { - inputDevice.getDeviceList((error, ids) => { + inputDevice.getDeviceIds((error, ids) => { if (error) { console.log(`Failed to get device list. error code=${JSON.stringify(err.code)} msg=${JSON.stringify(err.message)}`); @@ -65,7 +65,7 @@ Obtains the IDs of all input devices. This API uses a promise to return the resu ```js try { - inputDevice.getDeviceList().then((ids) => { + inputDevice.getDeviceIds().then((ids) => { console.log("The device ID list is: " + ids); }); } catch (error) { @@ -245,10 +245,15 @@ This API is deprecated since API version 9. You are advised to use [inputDevice. **Example** ```js -inputDevice.getDeviceIds((ids)=>{ - console.log("The device ID list is: " + ids); +inputDevice.getDeviceIds((error, ids) => { + if (error) { + console.log(`Failed to get device id list, error: ${JSON.stringify(error, [`code`, `message`])}`); + return; + } + console.log(`Device id list: ${JSON.stringify(ids)}`); }); ``` +``` ## inputDevice.getDeviceIds(deprecated) @@ -269,8 +274,8 @@ This API is deprecated since API version 9. You are advised to use [inputDevice. **Example** ```js -inputDevice.getDeviceIds().then((ids)=>{ - console.log("The device ID list is: " + ids); +inputDevice.getDeviceIds().then((ids) => { + console.log(`Device id list: ${JSON.stringify(ids)}`); }); ``` @@ -295,8 +300,12 @@ This API is deprecated since API version 9. You are advised to use [inputDevice. ```js // Obtain the name of the device whose ID is 1. -inputDevice.getDevice(1, (inputDevice)=>{ - console.log("The device name is: " + inputDevice.name); +inputDevice.getDevice(1, (error, deviceData) => { + if (error) { + console.log(`Failed to get device info, error: ${JSON.stringify(error, [`code`, `message`])}`); + return; + } + console.log(`Device info: ${JSON.stringify(deviceData)}`); }); ``` @@ -326,8 +335,8 @@ This API is deprecated since API version 9. You are advised to use [inputDevice. ```js // Obtain the name of the device whose ID is 1. -inputDevice.getDevice(1).then((inputDevice)=>{ - console.log("The device name is: " + inputDevice.name); +inputDevice.getDevice(1).then((deviceData) => { + console.log(`Device info: ${JSON.stringify(deviceData)}`); }); ``` diff --git a/en/application-dev/reference/apis/js-apis-mediaquery.md b/en/application-dev/reference/apis/js-apis-mediaquery.md index 4176338c0957632f67df2a74c73cd51a8ab1d48d..f44a0801b9ae1d9d4fec2f4485bf848e8595caa5 100644 --- a/en/application-dev/reference/apis/js-apis-mediaquery.md +++ b/en/application-dev/reference/apis/js-apis-mediaquery.md @@ -1,4 +1,4 @@ -# Media Query +# @ohos.mediaquery The **mediaquery** module provides different styles for different media types. @@ -14,64 +14,64 @@ import mediaquery from '@ohos.mediaquery' ``` -## Required Permissions - -None. - - ## mediaquery.matchMediaSync matchMediaSync(condition: string): MediaQueryListener -Sets the media query criteria and returns the corresponding listening handle. +Sets the media query condition. This API returns the corresponding media query listener. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** + | Name | Type | Mandatory | Description | | --------- | ------ | ---- | ---------------------------------------- | -| condition | string | Yes | Matching condition of a media event. For details, see [Syntax of Media Query Conditions](../../ui/ui-ts-layout-mediaquery.md#syntax-of-media-query-conditions).| +| condition | string | Yes | Media query condition. For details, see [Syntax of Media Query Conditions](../../ui/ui-ts-layout-mediaquery.md#syntax-of-media-query-conditions).| **Return value** + | Type | Description | | ------------------ | ---------------------- | -| MediaQueryListener | Listening handle to a media event, which is used to register or deregister the listening callback.| +| MediaQueryListener | Media query listener, which is used to register or deregister the listening callback.| **Example** - ```js + +```js let listener = mediaquery.matchMediaSync('(orientation: landscape)'); // Listen for landscape events. - ``` +``` ## MediaQueryListener -Media query handle, including the first query result when the handle is applied for. +Implements the media query listener, including the first query result when the listener is applied for. **System capability**: SystemCapability.ArkUI.ArkUI.Full ### Attributes -| Name | Type | Readable | Writable | Description | -| ------- | ------- | ---- | ---- | ---------- | -| matches | boolean | Yes | No | Whether the match condition is met. | -| media | string | Yes | No | Matching condition of a media event.| +| Name | Type | Readable| Writable| Description | +| ------- | ------- | ---- | ---- | -------------------- | +| matches | boolean | Yes | No | Whether the media query condition is met. | +| media | string | Yes | No | Media query condition.| ### on on(type: 'change', callback: Callback<MediaQueryResult>): void -Registers a callback with the corresponding query condition by using the handle. This callback is triggered when the media attributes change. +Registers the media query listener. The callback is triggered when the media attributes change. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** + | Name | Type | Mandatory | Description | | -------- | -------------------------------- | ---- | ---------------- | -| type | string | Yes | Must enter the string **change**.| +| type | string | Yes | Listener type. The value is fixed at **'change'**.| | callback | Callback<MediaQueryResult> | Yes | Callback registered with media query. | **Example** + For details, see [off Example](#off). @@ -79,17 +79,19 @@ Registers a callback with the corresponding query condition by using the handle. off(type: 'change', callback?: Callback<MediaQueryResult>): void -Deregisters a callback with the corresponding query condition by using the handle, so that no callback is triggered when the media attributes change. +Deregisters the media query listener, so that no callback is triggered when the media attributes change. **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** -| Name | Type | Mandatory | Description | -| -------- | -------------------------------- | ---- | ----------------------------- | -| type | boolean | Yes | Must enter the string **change**. | -| callback | Callback<MediaQueryResult> | No | Callback to be deregistered. If the default value is used, all callbacks of the handle are deregistered.| + +| Name | Type | Mandatory| Description | +| -------- | -------------------------------- | ---- | ---------------------------------------------------------- | +| type | string | Yes | Listener type. The value is fixed at **'change'**. | +| callback | Callback<MediaQueryResult> | No | Callback to be deregistered. If the default value is used, all callbacks of the handle are deregistered.| **Example** + ```js import mediaquery from '@ohos.mediaquery' @@ -101,20 +103,23 @@ Deregisters a callback with the corresponding query condition by using the handl // do something here } } - listener.on('change', onPortrait) // Register a callback. - listener.off('change', onPortrait) // Deregister a callback. + listener.on('change', onPortrait) // Register the media query listener. + listener.off('change', onPortrait) // Deregister the media query listener. ``` - ## MediaQueryResult +Provides the media query result. + +**System capability**: SystemCapability.ArkUI.ArkUI.Full + ### Attributes -| Name | Type | Readable | Writable | Description | -| ------- | ------- | ---- | ---- | ---------- | -| matches | boolean | Yes | No | Whether the match condition is met. | -| media | string | Yes | No | Matching condition of a media event.| +| Name | Type | Readable| Writable| Description | +| ------- | ------- | ---- | ---- | -------------------- | +| matches | boolean | Yes | No | Whether the media query condition is met. | +| media | string | Yes | No | Media query condition.| ### Example diff --git a/en/application-dev/reference/apis/js-apis-net-connection.md b/en/application-dev/reference/apis/js-apis-net-connection.md index 2fbe0e1c1d90b155fc52702d1dc69982e511c140..bff6eb26654f551ab744bfdd7d988cb3b7a8f4f4 100644 --- a/en/application-dev/reference/apis/js-apis-net-connection.md +++ b/en/application-dev/reference/apis/js-apis-net-connection.md @@ -61,7 +61,7 @@ connection.getDefaultNet().then(function (netHandle) { }) ``` -## connection.getDefaultNetSync +## connection.getDefaultNetSync9+ getDefaultNetSync(): NetHandle; @@ -303,6 +303,55 @@ connection.getDefaultNet().then(function (netHandle) { }) ``` +## connection.isDefaultNetMetered9+ + +isDefaultNetMetered(callback: AsyncCallback\): void + +Checks whether the data traffic usage on the current network is metered. This API uses an asynchronous callback to return the result. + +**Required permission**: ohos.permission.GET_NETWORK_INFO + +**System capability**: SystemCapability.Communication.NetManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ----------------------- | ---- | -------------------------------------- | +| callback | AsyncCallback\ | Yes | Callback used to return the result. The value **true** indicates the data traffic usage is metered.| + +**Example**: + +```js +connection.isDefaultNetMetered(function (error, has) { + console.log(JSON.stringify(error)) + console.log('has: ' + has) +}) +``` + +## connection.isDefaultNetMetered9+ + +isDefaultNetMetered(): Promise\ + +Checks whether the data traffic usage on the current network is metered. This API uses a promise to return the result. + +**Required permission**: ohos.permission.GET_NETWORK_INFO + +**System capability**: SystemCapability.Communication.NetManager.Core + +**Return value** + +| Type | Description | +| ----------------- | ----------------------------------------------- | +| Promise\ | Promise used to return the result. The value **true** indicates the data traffic usage is metered.| + +**Example**: + +```js +connection.isDefaultNetMetered().then(function (has) { + console.log('has: ' + has) +}) +``` + ## connection.reportNetConnected reportNetConnected(netHandle: NetHandle, callback: AsyncCallback<void>): void @@ -495,7 +544,7 @@ enableAirplaneMode(callback: AsyncCallback\): void Enables the airplane mode. This API uses an asynchronous callback to return the result. -This is a system API. +**System API**: This is a system API. **System capability**: SystemCapability.Communication.NetManager.Core @@ -519,7 +568,7 @@ enableAirplaneMode(): Promise\ Enables the airplane mode. This API uses a promise to return the result. -This is a system API. +**System API**: This is a system API. **System capability**: SystemCapability.Communication.NetManager.Core @@ -543,7 +592,7 @@ disableAirplaneMode(callback: AsyncCallback\): void Disables the airplane mode. This API uses an asynchronous callback to return the result. -This is a system API. +**System API**: This is a system API. **System capability**: SystemCapability.Communication.NetManager.Core @@ -567,7 +616,7 @@ disableAirplaneMode(): Promise\ Disables the airplane mode. This API uses a promise to return the result. -This is a system API. +**System API**: This is a system API. **System capability**: SystemCapability.Communication.NetManager.Core @@ -823,7 +872,7 @@ Before invoking NetHandle APIs, call **getNetHandle** to obtain a **NetHandle** | ------ | ------ | ------------------------- | | netId | number | Network ID. The value **0** indicates no default network. Any other value must be greater than or equal to 100.| -### bindSocket +### bindSocket9+ bindSocket(socketParam: TCPSocket \| UDPSocket, callback: AsyncCallback\): void; @@ -1091,10 +1140,10 @@ Provides an instance that bears data network capabilities. **System capability**: SystemCapability.Communication.NetManager.Core -| Name | Type | Description | -| ----------------------- | ----------------------------------- | ------------------------------------------------------------ | -| netCapabilities | [NetCapabilities](#netcapabilities) | Network transmission capabilities and bearer types of the data network. | -| bearerPrivateIdentifier | string | Network identifier. The identifier of a Wi-Fi network is **wifi**, and that of a cellular network is **slot0** (corresponding to SIM card 1).| +| Name | Type | Mandatory | Description | +| -------- | ------- | --------- | ----------- | +| netCapabilities | [NetCapabilities](#netcapabilities) | Yes | Network transmission capabilities and bearer types of the data network. | +| bearerPrivateIdentifier | string | No | Network identifier. The identifier of a Wi-Fi network is **wifi**, and that of a cellular network is **slot0** (corresponding to SIM card 1).| ## NetCapabilities @@ -1102,12 +1151,12 @@ Defines the network capability set. **System capability**: SystemCapability.Communication.NetManager.Core -| Name | Type | Description | -| --------------------- | ---------------------------------- | ------------------------ | -| linkUpBandwidthKbps | number | Uplink (from the device to the network) bandwidth.| -| linkDownBandwidthKbps | number | Downlink (from the network to the device) bandwidth.| -| networkCap | Array<[NetCap](#netcap)> | Network capability. | -| bearerTypes | Array<[NetBearType](#netbeartype)> | Network type. | +| Name | Type | Mandatory | Description | +| -------- | ------- | --------- | ----------- | +| linkUpBandwidthKbps | number | No | Uplink (from the device to the network) bandwidth.| +| linkDownBandwidthKbps | number | No | Downlink (from the network to the device) bandwidth.| +| networkCap | Array<[NetCap](#netcap)> | No | Network capability. | +| bearerTypes | Array<[NetBearType](#netbeartype)> | Yes | Network type. | ## NetCap @@ -1141,14 +1190,14 @@ Defines the network connection properties. **System capability**: SystemCapability.Communication.NetManager.Core -| Name | Type | Description | -| ------------- | ---------------------------------- | ---------------- | -| interfaceName | string | NIC card name. | -| domains | string | Domain. The default value is **""**.| -| linkAddresses | Array<[LinkAddress](#linkaddress)> | Link information. | -| routes | Array<[RouteInfo](#routeinfo)> | Route information. | -| dnses | Array<[NetAddress](#netaddress)> | Network address. For details, see [NetAddress](#netaddress).| -| mtu | number | Maximum transmission unit (MTU). | +| Name | Type | Mandatory | Description | +| -------- | ------- | --------- | ----------- | +| interfaceName | string | Yes | NIC card name. | +| domains | string | Yes | Domain. The default value is **""**.| +| linkAddresses | Array\<[LinkAddress](#linkaddress)> | Yes | Link information. | +| routes | Array\<[RouteInfo](#routeinfo)> | Yes | Route information. | +| dnses | Array\<[NetAddress](#netaddress)>; | Yes | Network address. For details, see [NetAddress](#netaddress).| +| mtu | number | Yes | Maximum transmission unit (MTU). | ## LinkAddress @@ -1156,10 +1205,10 @@ Network link information. **System capability**: SystemCapability.Communication.NetManager.Core -| Name | Type | Description | -| ------------ | ------------------------- | -------------------- | -| address | [NetAddress](#netaddress) | Link address. | -| prefixLength | number | Length of the link address prefix.| +| Name | Type | Mandatory | Description | +| -------- | ------- | --------- | ----------- | +| address | [NetAddress](#netaddress) | Yes | Link address. | +| prefixLength | number | Yes | Length of the link address prefix.| ## RouteInfo @@ -1167,13 +1216,13 @@ Network route information. **System capability**: SystemCapability.Communication.NetManager.Core -| Name | Type | Description | -| -------------- | --------------------------- | ---------------- | -| interface | string | NIC card name. | -| destination | [LinkAddress](#linkaddress) | Destination IP address. | -| gateway | [NetAddress](#netaddress) | Gateway address. | -| hasGateway | boolean | Whether a gateway is present. | -| isDefaultRoute | boolean | Whether the route is the default route.| +| Name | Type | Mandatory | Description | +| -------- | ------- | --------- | ----------- | +| interface | string | Yes | NIC card name. | +| destination | [LinkAddress](#linkaddress) | Yes | Destination IP address. | +| gateway | [NetAddress](#netaddress) | Yes | Gateway address. | +| hasGateway | boolean | Yes | Whether a gateway is present. | +| isDefaultRoute | boolean | Yes | Whether the route is the default route.| ## NetAddress @@ -1181,8 +1230,8 @@ Defines the network address. **System capability**: SystemCapability.Communication.NetManager.Core -| Name | Type | Description | -| ------- | ------ | ------------------------------ | -| address | string | Network address. | -| family | number | Address family identifier. The value is **1** for IPv4 and **2** for IPv6. The default value is **1**.| -| port | number | Port number. The value ranges from **0** to **65535**. | +| Name | Type | Mandatory | Description | +| -------- | ------- | --------- | ----------- | +| address | string | Yes | Network address. | +| family | number | Yes | Address family identifier. The value is **1** for IPv4 and **2** for IPv6. The default value is **1**.| +| port | number | No | Port number. The value ranges from **0** to **65535**. | diff --git a/en/application-dev/reference/apis/js-apis-net-ethernet.md b/en/application-dev/reference/apis/js-apis-net-ethernet.md index bf132f3c63710fc83b04a3411eb2477f2fe8b855..457fa931fd6550a7461d9a5c1f7bb40a41f7fe8b 100644 --- a/en/application-dev/reference/apis/js-apis-net-ethernet.md +++ b/en/application-dev/reference/apis/js-apis-net-ethernet.md @@ -14,7 +14,7 @@ import ethernet from '@ohos.net.ethernet' ## ethernet.setIfaceConfig -setIfaceConfig(iface: string, ic: InterfaceConfiguration, callback: AsyncCallback\): void; +setIfaceConfig(iface: string, ic: InterfaceConfiguration, callback: AsyncCallback\): void Sets the network interface configuration. This API uses an asynchronous callback to return the result. @@ -46,7 +46,7 @@ ethernet.setIfaceConfig("eth0", {mode:ethernet.STATIC,ipAddr:"192.168.1.123", ro ## ethernet.setIfaceConfig -setIfaceConfig(iface: string, ic: InterfaceConfiguration): Promise\; +setIfaceConfig(iface: string, ic: InterfaceConfiguration): Promise\ Sets the network interface configuration. This API uses a promise to return the result. @@ -80,7 +80,7 @@ ethernet.setIfaceConfig("eth0", {mode:ethernet.STATIC,ipAddr:"192.168.1.123", ro ## ethernet.getIfaceConfig -getIfaceConfig(iface: string, callback: AsyncCallback\): void; +getIfaceConfig(iface: string, callback: AsyncCallback\): void Obtains the configuration of a network interface. This API uses an asynchronous callback to return the result. @@ -115,7 +115,7 @@ ethernet.getIfaceConfig("eth0", (error, value) => { ## ethernet.getIfaceConfig -getIfaceConfig(iface: string): Promise\; +getIfaceConfig(iface: string): Promise\ Obtains the configuration of a network interface. This API uses a promise to return the result. @@ -153,7 +153,7 @@ ethernet.getIfaceConfig("eth0").then((data) => { ## ethernet.isIfaceActive -isIfaceActive(iface?: string, callback: AsyncCallback\): void; +isIfaceActive(iface?: string, callback: AsyncCallback\): void Checks whether a network interface is active. This API uses an asynchronous callback to return the result. @@ -165,7 +165,7 @@ Checks whether a network interface is active. This API uses an asynchronous call | Name | Type | Mandatory| Description | | -------- | --------------------------- | ---- | -------------------------------------------------- | -| iface | string | No | Name of the network interface. If this parameter is left empty, the API checks for any active network interface. | +| iface | string | Yes | Name of the network interface. If this parameter is left empty, the API checks for any active network interface. | | callback | AsyncCallback\ | Yes | Callback used to return the result. The value **1** means that the network interface is active, **0** means that the network interface is inactive, and any other value means that an error has occurred.| **Example** @@ -182,7 +182,7 @@ ethernet.isIfaceActive("eth0", (error, value) => { ## ethernet.isIfaceActive -isIfaceActive(iface?: string): Promise\; +isIfaceActive(iface: string): Promise\ Checks whether a network interface is active. This API uses a promise to return the result. @@ -194,7 +194,7 @@ Checks whether a network interface is active. This API uses a promise to return | Name| Type | Mandatory| Description | | ------ | ------ | ---- | -------------------------------------- | -| iface | string | No | Name of the network interface. If this parameter is left empty, the API checks for any active network interface.| +| iface | string | Yes | Name of the network interface. If this parameter is left empty, the API checks for any active network interface.| **Return value** @@ -214,7 +214,7 @@ ethernet.isIfaceActive("eth0").then((data) => { ## ethernet.getAllActiveIfaces -getAllActiveIfaces(callback: AsyncCallback\>): void; +getAllActiveIfaces(callback: AsyncCallback\>): void Obtains all active network interfaces. This API uses an asynchronous callback to return the result. @@ -245,7 +245,7 @@ ethernet.getAllActiveIfaces((error, value) => { ## ethernet.getAllActiveIfaces -getAllActiveIfaces(): Promise\>; +getAllActiveIfaces(): Promise\> Obtains all active network interfaces. This API uses a promise to return the result. @@ -280,14 +280,14 @@ Defines the network configuration for the Ethernet connection. **System capability**: SystemCapability.Communication.NetManager.Core -| Name | Type | Description | -| ----------------------- | ----------------------------------- | ------------------------------------------------------------ | -| mode | [IPSetMode](#ipsetmode) | Configuration mode of the Ethernet connection.| -| ipAddr | string | Static IP address of the Ethernet connection. The value must be an IPv4 address, which is a 32-bit number displayed in dotted decimal notation and each 8-bit field ranges from 0 to 255. This parameter does not need to be configured in Dynamic Host Configuration Protocol (DHCP) mode.| -| route | string | Route of the Ethernet connection. The value must be an IPv4 address. This parameter does not need to be configured in DHCP mode.| -| gateway | string | Gateway of the Ethernet connection. The value must be an IPv4 address. This parameter does not need to be configured in DHCP mode.| -| netMask | string | Subnet mask of the Ethernet connection. The value must be an IPv4 address. This parameter does not need to be configured in DHCP mode.| -| dnsServers | string | DNS server addresses of the Ethernet connection. The value must be an IPv4 address. This parameter does not need to be configured in DHCP mode. Multiple addresses are separated by commas (,).| +| Name | Type | Mandatory | Description | +| -------- | ------- | --------- | ----------- | +| mode | [IPSetMode](#ipsetmode) | Yes | Configuration mode of the Ethernet connection.| +| ipAddr | string | Yes | Static IP address of the Ethernet connection. The value must be an IPv4 address, which is a 32-bit number displayed in dotted decimal notation and each 8-bit field ranges from 0 to 255. This parameter does not need to be configured in Dynamic Host Configuration Protocol (DHCP) mode.| +| route | string | Yes | Route of the Ethernet connection. The value must be an IPv4 address. This parameter does not need to be configured in DHCP mode.| +| gateway | string | Yes | Gateway of the Ethernet connection. The value must be an IPv4 address. This parameter does not need to be configured in DHCP mode.| +| netMask | string | Yes | Subnet mask of the Ethernet connection. The value must be an IPv4 address. This parameter does not need to be configured in DHCP mode.| +| dnsServers | string | Yes | DNS server addresses of the Ethernet connection. The value must be an IPv4 address. This parameter does not need to be configured in DHCP mode. Multiple addresses are separated by commas (,).| ## IPSetMode diff --git a/en/application-dev/reference/apis/js-apis-net-sharing.md b/en/application-dev/reference/apis/js-apis-net-sharing.md index c63c09c5a84bbec34b5b2274d3089fad4fbb603b..9b0ceaead8faa59011bd2ec931e8fb5bd1477cbf 100644 --- a/en/application-dev/reference/apis/js-apis-net-sharing.md +++ b/en/application-dev/reference/apis/js-apis-net-sharing.md @@ -18,9 +18,11 @@ isSharingSupported(callback: AsyncCallback\): void Checks whether network sharing is supported. This API uses an asynchronous callback to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -43,9 +45,11 @@ isSharingSupported(): Promise\ Checks whether network sharing is supported. This API uses a promise to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Return value** @@ -69,9 +73,11 @@ isSharing(callback: AsyncCallback\): void Checks whether network sharing is in progress. This API uses an asynchronous callback to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -96,7 +102,9 @@ Checks whether network sharing is in progress. This API uses a promise to return **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System API**: This is a system API. + +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Return value** @@ -122,7 +130,9 @@ Starts network sharing of a specified type. This API uses an asynchronous callba **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System API**: This is a system API. + +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -146,9 +156,11 @@ startSharing(type: SharingIfaceType): Promise\ Starts network sharing of a specified type. This API uses a promise to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -179,9 +191,11 @@ stopSharing(type: SharingIfaceType, callback: AsyncCallback\): void Stops network sharing of a specified type. This API uses an asynchronous callback to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -205,9 +219,11 @@ stopSharing(type: SharingIfaceType): Promise\ Stops network sharing of a specified type. This API uses a promise to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -238,9 +254,11 @@ getStatsRxBytes(callback: AsyncCallback\): void Obtains the volume of mobile data traffic received via network sharing. This API uses an asynchronous callback to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -263,9 +281,11 @@ getStatsRxBytes(): Promise\ Obtains the volume of mobile data traffic received via network sharing. This API uses a promise to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Return value** @@ -289,9 +309,11 @@ getStatsTxBytes(callback: AsyncCallback\): void Obtains the volume of mobile data traffic sent via network sharing. This API uses an asynchronous callback to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -314,9 +336,11 @@ getStatsTxBytes(): Promise\ Obtains the volume of mobile data traffic sent via network sharing. This API uses a promise to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Return value** @@ -340,9 +364,11 @@ getStatsTotalBytes(callback: AsyncCallback\): void Obtains the volume of mobile data traffic sent and received via network sharing. This API uses an asynchronous callback to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -365,9 +391,11 @@ getStatsTotalBytes(): Promise\ Obtains the volume of mobile data traffic sent and received via network sharing. This API uses a promise to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Return value** @@ -391,15 +419,17 @@ getSharingIfaces(state: SharingIfaceState, callback: AsyncCallback\> | Yes | Callback used to return an array of NIC names.| **Example** @@ -418,15 +448,17 @@ getSharingIfaces(state: SharingIfaceState): Promise\> Obtains the names of NICs in the specified network sharing state. This API uses a promise to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** | Name | Type | Mandatory| Description | | -------- | --------------------------------------- | ---- | ---------- | -| state | state: [SharingIfaceState](#sharingifacestate) | Yes | Network sharing state.| +| state | [SharingIfaceState](#sharingifacestate) | Yes | Network sharing state.| **Return value** @@ -451,9 +483,11 @@ getSharingState(type: SharingIfaceType, callback: AsyncCallback\ Obtains the network sharing state of the specified type. This API uses a promise to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -511,9 +547,11 @@ getSharableRegexes(type: SharingIfaceType, callback: AsyncCallback\> Obtains regular expressions of NICs of a specified type. This API uses a promise to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -571,9 +611,11 @@ on(type: 'sharingStateChange', callback: Callback\): void Subscribes to network sharing state changes. This API uses an asynchronous callback to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -597,9 +639,11 @@ off(type: 'sharingStateChange', callback?: Callback\): void Unsubscribes from network sharing state changes. This API uses an asynchronous callback to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -623,9 +667,11 @@ on(type: 'interfaceSharingStateChange', callback: Callback\<{ type: SharingIface Subscribes to network sharing state changes of a specified NIC. This API uses an asynchronous callback to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -649,15 +695,17 @@ off(type: 'interfaceSharingStateChange', callback?: Callback\<{ type: SharingIfa Unsubscribes from network sharing status changes of a specified NIC. This API uses an asynchronous callback to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** | Name | Type | Mandatory| Description | | -------- | --------------------------------------- | ---- | ---------- | -| type | string | No | Event name.| +| type | string | Yes | Event name.| | callback | AsyncCallback\<{ type: [SharingIfaceType](#sharingifacetype), iface: string, state: SharingIfaceState(#sharingifacestate) }> | No | Callback used for unsubscription.| **Example** @@ -675,9 +723,11 @@ on(type: 'sharingUpstreamChange', callback: Callback\): void Subscribes to upstream network changes. This API uses an asynchronous callback to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -701,9 +751,11 @@ off(type: 'sharingUpstreamChange', callback?: Callback\): void Unsubscribes from upstream network changes. This API uses an asynchronous callback to return the result. +**System API**: This is a system API. + **Required permissions**: ohos.permission.CONNECTIVITY_INTERNAL -**System capability**: SystemCapability.Communication.NetManager.Core +**System capability**: SystemCapability.Communication.NetManager.NetSharing **Parameters** @@ -725,7 +777,9 @@ sharing.off('sharingUpstreamChange', (error, data) => { Enumerates the network sharing states of an NIC. -**System capability**: SystemCapability.Communication.NetManager.Core +**System API**: This is a system API. + +**System capability**: SystemCapability.Communication.NetManager.NetSharing | Name | Value | Description | | ------------------------ | ---- | ---------------------- | @@ -737,7 +791,9 @@ Enumerates the network sharing states of an NIC. Enumerates the network sharing types of an NIC. -**System capability**: SystemCapability.Communication.NetManager.Core +**System API**: This is a system API. + +**System capability**: SystemCapability.Communication.NetManager.NetSharing | Name | Value | Description | | ------------------------ | ---- | ---------------------- | diff --git a/en/application-dev/reference/apis/js-apis-prompt.md b/en/application-dev/reference/apis/js-apis-prompt.md index 1fd0357783d6cf3ead6913cfc07a0e4b4e1c3c82..27a450de58306f1b018468d6f2590778a9f0d484 100644 --- a/en/application-dev/reference/apis/js-apis-prompt.md +++ b/en/application-dev/reference/apis/js-apis-prompt.md @@ -1,4 +1,4 @@ -# Prompt +# @ohos.prompt The **Prompt** module provides APIs for creating and showing toasts, dialog boxes, and action menus. @@ -146,11 +146,11 @@ Describes the options for showing the dialog box. **System capability**: SystemCapability.ArkUI.ArkUI.Full -| Name | Type | Mandatory | Description | -| ------- | ---------------------------------------- | ---- | ---------------------------------------- | -| title | string\| [Resource](../arkui-ts/ts-types.md#resource)9+ | No | Title of the dialog box. | -| message | string\| [Resource](../arkui-ts/ts-types.md#resource)9+ | No | Text body. | -| buttons | Array | No | Array of buttons in the dialog box. The array structure is **{text:'button', color: '\#666666'}**. Up to three buttons are supported. The first button is of the **positiveButton** type, the second is of the **negativeButton** type, and the third is of the **neutralButton** type.| +| Name | Type | Mandatory| Description | +| ------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | +| title | string\| [Resource](../arkui-ts/ts-types.md#resource)9+ | No | Title of the dialog box. | +| message | string\| [Resource](../arkui-ts/ts-types.md#resource)9+ | No | Text body. | +| buttons | [[Button](#button),[Button](#button)?,[Button](#button)?] | No | Array of buttons in the dialog box. The array structure is **{text:'button', color: '\#666666'}**. Up to three buttons are supported. The first button is of the **positiveButton** type, the second is of the **negativeButton** type, and the third is of the **neutralButton** type.| ## ShowDialogSuccessResponse @@ -158,9 +158,9 @@ Describes the dialog box response result. **System capability**: SystemCapability.ArkUI.ArkUI.Full -| Name | Type | Description | -| ----- | ------ | ------------------- | -| index | number | Index of the selected button in the **buttons** array.| +| Name | Type | Mandatory| Description | +| ----- | ------ | ---- | ------------------------------- | +| index | number | No | Index of the selected button in the **buttons** array.| ## prompt.showActionMenu @@ -255,10 +255,10 @@ Describes the options for showing the action menu. **System capability**: SystemCapability.ArkUI.ArkUI.Full -| Name | Type | Mandatory | Description | -| ------- | ---------------------------------------- | ---- | ---------------------------------------- | -| title | string\| [Resource](../arkui-ts/ts-types.md#resource)9+ | No | Title of the text to display. | -| buttons | Array<[Button](#button)> | Yes | Array of menu item buttons. The array structure is **{text:'button', color: '\#666666'}**. Up to six buttons are supported. If there are more than six buttons, extra buttons will not be displayed.| +| Name | Type | Mandatory| Description | +| ------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | +| title | string\| [Resource](../arkui-ts/ts-types.md#resource)9+ | No | Title of the text to display. | +| buttons | [[Button](#button),[Button](#button)?,[Button](#button)?,[Button](#button)?,[Button](#button)?,[Button](#button)?] | Yes | Array of menu item buttons. The array structure is **{text:'button', color: '\#666666'}**. Up to six buttons are supported. If there are more than six buttons, extra buttons will not be displayed.| ## ActionMenuSuccessResponse diff --git a/en/application-dev/reference/apis/js-apis-promptAction.md b/en/application-dev/reference/apis/js-apis-promptAction.md index 268673b046bbb5f775dfffe3986105718319d009..0faa9cf211bbd0a673287c34b8d9ad45d34374e6 100644 --- a/en/application-dev/reference/apis/js-apis-promptAction.md +++ b/en/application-dev/reference/apis/js-apis-promptAction.md @@ -1,4 +1,4 @@ -# Prompt +# @ohos.promptAction The **PromptAction** module provides APIs for creating and showing toasts, dialog boxes, and action menus. @@ -32,7 +32,7 @@ For details about the error codes, see [promptAction Error Codes](../errorcodes/ | ID | Error Message| | --------- | ------- | -| 100001 | Internal error. | +| 100001 | If UI execution context not found. | **Example** @@ -88,7 +88,7 @@ For details about the error codes, see [promptAction Error Codes](../errorcodes/ | ID | Error Message| | --------- | ------- | -| 100001 | Internal error. | +| 100001 | If UI execution context not found. | **Example** @@ -142,7 +142,7 @@ For details about the error codes, see [promptAction Error Codes](../errorcodes/ | ID | Error Message| | --------- | ------- | -| 100001 | Internal error. | +| 100001 | If UI execution context not found. | **Example** @@ -181,11 +181,11 @@ Describes the options for showing the dialog box. **System capability**: SystemCapability.ArkUI.ArkUI.Full -| Name | Type | Mandatory | Description | -| ------- | ---------------------------------------- | ---- | ---------------------------------------- | -| title | string\| [Resource](../arkui-ts/ts-types.md#resource)9+| No | Title of the dialog box. | -| message | string\| [Resource](../arkui-ts/ts-types.md#resource)9+| No | Text body. | -| buttons | Array | No | Array of buttons in the dialog box. The array structure is **{text:'button', color: '\#666666'}**. Up to three buttons are supported. The first button is of the **positiveButton** type, the second is of the **negativeButton** type, and the third is of the **neutralButton** type.| +| Name | Type | Mandatory| Description | +| ------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | +| title | string\| [Resource](../arkui-ts/ts-types.md#resource)9+| No | Title of the dialog box. | +| message | string\| [Resource](../arkui-ts/ts-types.md#resource)9+| No | Text body. | +| buttons | [[Button](#button),[Button](#button)?,[Button](#button)?] | No | Array of buttons in the dialog box. The array structure is **{text:'button', color: '\#666666'}**. Up to three buttons are supported. The first button is of the **positiveButton** type, the second is of the **negativeButton** type, and the third is of the **neutralButton** type.| ## ShowDialogSuccessResponse @@ -193,9 +193,9 @@ Describes the dialog box response result. **System capability**: SystemCapability.ArkUI.ArkUI.Full -| Name | Type | Description | -| ----- | ------ | ------------------- | -| index | number | Index of the selected button in the **buttons** array.| +| Name | Type | Mandatory| Description | +| ----- | ------ | ---- | ------------------------------- | +| index | number | No | Index of the selected button in the **buttons** array.| ## promptAction.showActionMenu @@ -218,7 +218,7 @@ For details about the error codes, see [promptAction Error Codes](../errorcodes/ | ID | Error Message| | --------- | ------- | -| 100001 | Internal error. | +| 100001 | If UI execution context not found. | **Example** @@ -276,7 +276,7 @@ For details about the error codes, see [promptAction Error Codes](../errorcodes/ | ID | Error Message| | --------- | ------- | -| 100001 | Internal error. | +| 100001 | If UI execution context not found. | **Example** @@ -314,10 +314,10 @@ Describes the options for showing the action menu. **System capability**: SystemCapability.ArkUI.ArkUI.Full -| Name | Type | Mandatory | Description | -| ------- | ---------------------------------------- | ---- | ---------------------------------------- | -| title | string\| [Resource](../arkui-ts/ts-types.md#resource)9+| No | Title of the dialog box. | -| buttons | Array<[Button](#button)> | Yes | Array of menu item buttons. The array structure is **{text:'button', color: '\#666666'}**. Up to six buttons are supported. If there are more than six buttons, extra buttons will not be displayed.| +| Name | Type | Mandatory| Description | +| ------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | +| title | string\| [Resource](../arkui-ts/ts-types.md#resource)9+| No | Title of the dialog box. | +| buttons | [[Button](#button),[Button](#button)?,[Button](#button)?,[Button](#button)?,[Button](#button)?,[Button](#button)?] | Yes | Array of menu item buttons. The array structure is **{text:'button', color: '\#666666'}**. Up to six buttons are supported. If there are more than six buttons, extra buttons will not be displayed.| ## ActionMenuSuccessResponse diff --git a/en/application-dev/reference/apis/js-apis-router.md b/en/application-dev/reference/apis/js-apis-router.md index 5e85658f698d0ca85ea2d422d648b020f5d02e4b..75d75ddb09e5c9e7d5d7028b02295cf24e8cf57e 100644 --- a/en/application-dev/reference/apis/js-apis-router.md +++ b/en/application-dev/reference/apis/js-apis-router.md @@ -1,4 +1,4 @@ -# Page Routing +# @ohos.router The **Router** module provides APIs to access pages through URLs. You can use the APIs to navigate to a specified page in an application, replace the current page with another one in an application, and return to the previous page or a specified page. @@ -40,9 +40,9 @@ For details about the error codes, see [Router Error Codes](../errorcodes/errorc | ID | Error Message| | --------- | ------- | -| 100001 | Internal error. | -| 100002 | Uri error. The uri of router is not exist. | -| 100003 | Page stack error. The pages are pushed too much. | +| 100001 | If UI execution context not found. | +| 100002 | If the uri is not exist. | +| 100003 | If the pages are pushed too much. | **Example** @@ -54,8 +54,8 @@ try { data1: 'message', data2: { data3: [123, 456, 789] - }, - }, + } + } }) .then(() => { // success @@ -89,9 +89,9 @@ For details about the error codes, see [Router Error Codes](../errorcodes/errorc | ID | Error Message| | --------- | ------- | -| 100001 | Internal error. | -| 100002 | Uri error. The uri of router is not exist. | -| 100003 | Page stack error. The pages are pushed too much. | +| 100001 | If UI execution context not found. | +| 100002 | If the uri is not exist. | +| 100003 | If the pages are pushed too much. | **Example** @@ -103,8 +103,8 @@ try { data1: 'message', data2: { data3: [123, 456, 789] - }, - }, + } + } }, (err) => { if (err) { console.error(`pushUrl failed, code is ${err.code}, message is ${err.message}`); @@ -143,9 +143,9 @@ For details about the error codes, see [Router Error Codes](../errorcodes/errorc | ID | Error Message| | --------- | ------- | -| 100001 | Internal error. | -| 100002 | Uri error. The uri of router is not exist. | -| 100003 | Page stack error. The pages are pushed too much. | +| 100001 | If UI execution context not found. | +| 100002 | If the uri is not exist. | +| 100003 | If the pages are pushed too much. | **Example** @@ -157,8 +157,8 @@ try { data1: 'message', data2: { data3: [123, 456, 789] - }, - }, + } + } }, router.RouterMode.Standard) .then(() => { // success @@ -193,9 +193,9 @@ For details about the error codes, see [Router Error Codes](../errorcodes/errorc | ID | Error Message| | --------- | ------- | -| 100001 | Internal error. | -| 100002 | Uri error. The uri of router is not exist. | -| 100003 | Page stack error. The pages are pushed too much. | +| 100001 | If UI execution context not found. | +| 100002 | If the uri is not exist. | +| 100003 | If the pages are pushed too much. | **Example** @@ -207,8 +207,8 @@ try { data1: 'message', data2: { data3: [123, 456, 789] - }, - }, + } + } }, router.RouterMode.Standard, (err) => { if (err) { console.error(`pushUrl failed, code is ${err.code}, message is ${err.message}`); @@ -247,8 +247,8 @@ For details about the error codes, see [Router Error Codes](../errorcodes/errorc | ID | Error Message| | --------- | ------- | -| 100001 | Internal error. | -| 200002 | Uri error. The uri of router is not exist. | +| 100001 | If UI execution context not found, only throw in standard system. | +| 200002 | If the uri is not exist. | **Example** @@ -257,8 +257,8 @@ try { router.replaceUrl({ url: 'pages/detail', params: { - data1: 'message', - }, + data1: 'message' + } }) .then(() => { // success @@ -292,8 +292,8 @@ For details about the error codes, see [Router Error Codes](../errorcodes/errorc | ID | Error Message| | --------- | ------- | -| 100001 | Internal error. | -| 200002 | Uri error. The uri of router is not exist. | +| 100001 | If UI execution context not found, only throw in standard system. | +| 200002 | If the uri is not exist. | **Example** @@ -302,8 +302,8 @@ try { router.replaceUrl({ url: 'pages/detail', params: { - data1: 'message', - }, + data1: 'message' + } }, (err) => { if (err) { console.error(`replaceUrl failed, code is ${err.code}, message is ${err.message}`); @@ -344,8 +344,8 @@ For details about the error codes, see [Router Error Codes](../errorcodes/errorc | ID | Error Message| | --------- | ------- | -| 100001 | Internal error. | -| 200002 | Uri error. The uri of router is not exist. | +| 100001 | If UI execution context not found, only throw in standard system. | +| 200002 | If the uri is not exist. | **Example** @@ -354,8 +354,8 @@ try { router.replaceUrl({ url: 'pages/detail', params: { - data1: 'message', - }, + data1: 'message' + } }, router.RouterMode.Standard) .then(() => { // success @@ -390,8 +390,8 @@ For details about the error codes, see [Router Error Codes](../errorcodes/errorc | ID | Error Message| | --------- | ------- | -| 100001 | Internal error. | -| 200002 | Uri error. The uri of router is not exist. | +| 100001 | If UI execution context not found, only throw in standard system. | +| 200002 | If the uri is not exist. | **Example** @@ -400,8 +400,8 @@ try { router.replaceUrl({ url: 'pages/detail', params: { - data1: 'message', - }, + data1: 'message' + } }, router.RouterMode.Standard, (err) => { if (err) { console.error(`replaceUrl failed, code is ${err.code}, message is ${err.message}`); @@ -465,7 +465,7 @@ Obtains the number of pages in the current stack. **Example** ```js -var size = router.getLength(); +let size = router.getLength(); console.log('pages stack size = ' + size); ``` @@ -486,7 +486,7 @@ Obtains state information about the current page. **Example** ```js -var page = router.getState(); +let page = router.getState(); console.log('current index = ' + page.index); console.log('current name = ' + page.name); console.log('current path = ' + page.path); @@ -498,11 +498,11 @@ Describes the page routing state. **System capability**: SystemCapability.ArkUI.ArkUI.Full -| Name | Type | Description | -| ----- | ------ | ---------------------------------- | -| index | number | Index of the current page in the stack. The index starts from 1 from the bottom to the top of the stack.| -| name | string | Name of the current page, that is, the file name. | -| path | string | Path of the current page. | +| Name | Type | Mandatory| Description | +| ----- | ------ | ---- | ------------------------------------------------------------ | +| index | number | Yes | Index of the current page in the stack. The index starts from 1 from the bottom to the top of the stack.| +| name | string | No | Name of the current page, that is, the file name. | +| path | string | Yes | Path of the current page. | ## router.enableBackPageAlert9+ @@ -524,7 +524,7 @@ For details about the error codes, see [Router Error Codes](../errorcodes/errorc | ID | Error Message| | --------- | ------- | -| 100001 | Internal error. | +| 100001 | If UI execution context not found. | **Example** @@ -590,7 +590,7 @@ Describes the page routing options. | Name | Type | Mandatory| Description | | ------ | ------ | ---- | ------------------------------------------------------------ | | url | string | Yes | URL of the target page, in either of the following formats:
- Absolute path of the page. The value is available in the pages list in the **config.json** file, for example:
- pages/index/index
- pages/detail/detail
- Particular path. If the URL is a slash (/), the home page is displayed.| -| params | Object | No | Data that needs to be passed to the target page during redirection. The target page can use **router.getParams()** to obtain the passed parameters, for example, **this.keyValue** (**keyValue** is the value of a key in **params**). In the web-like paradigm, these parameters can be directly used on the target page. If the field specified by **key** already exists on the target page, the passed value of the key will be displayed.| +| params | object | No | Data that needs to be passed to the target page during redirection. The target page can use **router.getParams()** to obtain the passed parameters, for example, **this.keyValue** (**keyValue** is the value of a key in **params**). In the web-like paradigm, these parameters can be directly used on the target page. If the field specified by **key** already exists on the target page, the passed value of the key will be displayed.| > **NOTE** @@ -602,9 +602,9 @@ Enumerates the routing modes. **System capability**: SystemCapability.ArkUI.ArkUI.Full -| Name | Description | -| -------- | ---------------------------------------- | -| Standard | Standard mode.
The target page is added to the top of the page stack, regardless of whether a page with the same URL exists in the stack. | +| Name | Description | +| -------- | ------------------------------------------------------------ | +| Standard | Standard mode.
The target page is added to the top of the page stack, regardless of whether a page with the same URL exists in the stack.| | Single | Singleton mode.
If the URL of the target page already exists in the page stack, the page closest to the top of the stack is moved as a new page to the top of the stack.
If the URL of the target page does not exist in the page stack, the page is redirected to in standard mode.| ## Examples @@ -618,8 +618,8 @@ export default { router.push({ url: 'pages/detail/detail', params: { - data1: 'message', - }, + data1: 'message' + } }); } } @@ -642,18 +642,18 @@ import router from '@ohos.router' @Entry @Component struct Index { - async routePage() { + async routePage() { let options = { url: 'pages/second', params: { text: 'This is the value on the first page.', data: { array: [12, 45, 78] - }, + } } } try { - await router.push(options) + await router.pushUrl(options) } catch (err) { console.info(` fail callback, code: ${err.code}, msg: ${err.msg}`) } @@ -661,18 +661,18 @@ struct Index { build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { - Text('This is the first page.') - .fontSize(50) - .fontWeight(FontWeight.Bold) + Text('This is the first page.') + .fontSize(50) + .fontWeight(FontWeight.Bold) Button() { Text('next page') .fontSize(25) .fontWeight(FontWeight.Bold) }.type(ButtonType.Capsule) - .margin({ top: 20 }) - .backgroundColor('#ccc') - .onClick(() => { - this.routePage() + .margin({ top: 20 }) + .backgroundColor('#ccc') + .onClick(() => { + this.routePage() }) } .width('100%') @@ -704,7 +704,7 @@ struct Second { this.secondData = (this.data.array[1]).toString() }) .margin({top:20}) - Text('Value from the first page '+'' + this.secondData) + Text(`This is the data passed from the first page: ${this.secondData}`) .fontSize(20) .margin({top:20}) .backgroundColor('red') @@ -741,8 +741,8 @@ router.push({ data1: 'message', data2: { data3: [123, 456, 789] - }, - }, + } + } }); ``` ## router.push(deprecated) @@ -772,8 +772,8 @@ router.push({ data1: 'message', data2: { data3: [123, 456, 789] - }, - }, + } + } },router.RouterMode.Standard); ``` @@ -799,8 +799,8 @@ This API is deprecated since API version 9. You are advised to use [replaceUrl9+](#routerreplaceurl9) instead. -**System capability**: SystemCapability.ArkUI.ArkUI.Full +**System capability**: SystemCapability.ArkUI.ArkUI.Lite **Parameters** @@ -827,8 +827,8 @@ This API is deprecated since API version 9. You are advised to use [replaceUrl9+ + +Enumerates carrier configuration keys. + +**System API**: This is a system API. + +**System capability**: SystemCapability.Telephony.CoreService + +| Name | Value | Description | +| ------------------------------------------------------- | ---------------------------------------------------- | -------------------- | +| KEY_VOICE_MAIL_NUMBER_STRING | "voice_mail_number_string" | Voice mailbox number. | +| KEY_IMS_SWITCH_ON_BY_DEFAULT_BOOL | "ims_switch_on_by_default_bool" | Fixed dialing number. | +| KEY_HIDE_IMS_SWITCH_BOOL | "hide_ims_switch_bool" | Whether to hide the IMS switch. | +| KEY_VOLTE_SUPPORTED_BOOL | "volte_supported_bool" | Whether to support VoLTE. | +| KEY_NR_MODE_SUPPORTED_LIST_INT_ARRAY | "nr_mode_supported_list_int_array" | List of supported NR modes. | +| KEY_VOLTE_PROVISIONING_SUPPORTED_BOOL | "volte_provisioning_supported_bool" | Whether to support VoLTE provisioning. | +| KEY_SS_OVER_UT_SUPPORTED_BOOL | "ss_over_ut_supported_bool" | Whether SS over UT is supported. | +| KEY_IMS_GBA_REQUIRED_BOOL | "ims_gba_required_bool" | Whether GBA is required for IMS. | +| KEY_UT_PROVISIONING_SUPPORTED_BOOL | "ut_provisioning_supported_bool" | Whether to support UT provisioning. | +| KEY_IMS_PREFER_FOR_EMERGENCY_BOOL | "ims_prefer_for_emergency_bool" | IMS preferences for emergency. | +| KEY_CALL_WAITING_SERVICE_CLASS_INT | "call_waiting_service_class_int" | Call waiting service. | +| KEY_CALL_TRANSFER_VISIBILITY_BOOL | "call_transfer_visibility_bool" | Call transfer visibility. | +| KEY_IMS_CALL_DISCONNECT_REASONINFO_MAPPING_STRING_ARRAY | "ims_call_disconnect_reasoninfo_mapping_string_array" | List of IMS call disconnection reasons.| +| KEY_FORCE_VOLTE_SWITCH_ON_BOOL | "force_volte_switch_on_bool" | Whether to forcibly turn on VoLTE. | +| KEY_ENABLE_OPERATOR_NAME_CUST_BOOL | "enable_operator_name_cust_bool" | Whether to display the carrier name.| +| KEY_OPERATOR_NAME_CUST_STRING | "operator_name_cust_string" | Carrier name. | +| KEY_SPN_DISPLAY_CONDITION_CUST_INT | "spn_display_condition_cust_int" | SPN display rule. | +| KEY_PNN_CUST_STRING_ARRAY | "pnn_cust_string_array" | PLMN name | +| KEY_OPL_CUST_STRING_ARRAY | "opl_cust_string_array" | PLMN information of the carrier. | +| KEY_EMERGENCY_CALL_STRING_ARRAY | "emergency_call_string_array" | Emergency call list. | diff --git a/en/application-dev/reference/apis/js-apis-sms.md b/en/application-dev/reference/apis/js-apis-sms.md index e9e32416426bf852590ed7d7a7f9c5e086a89480..c26311312c5cc2360ddf4f3784f66bba05b0f5b1 100644 --- a/en/application-dev/reference/apis/js-apis-sms.md +++ b/en/application-dev/reference/apis/js-apis-sms.md @@ -870,7 +870,7 @@ promise.then(data => { ## sms.isImsSmsSupported8+ -isImsSmsSupported(callback: AsyncCallback): void +isImsSmsSupported(slotId: number, callback: AsyncCallback): void Checks whether SMS is supported on IMS. This API uses an asynchronous callback to return the result. @@ -882,12 +882,14 @@ Checks whether SMS is supported on IMS. This API uses an asynchronous callback t | Name | Type | Mandatory| Description | | -------- | ---------------------------- | ---- | ---------- | +| slotId | number | Yes | SIM card slot ID.
- **0**: card slot 1
- **1**: card slot 2| | callback | AsyncCallback<boolean> | Yes | Callback used to return the result.| **Example** ```js -sms.isImsSmsSupported((err, data) => { +let slotId = 0; +sms.isImsSmsSupported(slotId, (err, data) => { console.log(`callback: err->${JSON.stringify(err)}, data->${JSON.stringify(data)}`); }); ``` @@ -895,7 +897,7 @@ sms.isImsSmsSupported((err, data) => { ## sms.isImsSmsSupported8+ -isImsSmsSupported(): Promise +isImsSmsSupported(slotId: number): Promise Checks whether SMS is supported on IMS. This API uses a promise to return the result. @@ -903,6 +905,12 @@ Checks whether SMS is supported on IMS. This API uses a promise to return the re **System capability**: SystemCapability.Telephony.SmsMms +**Parameters** + +| Name| Type | Mandatory | Description | +| ------ | ------ | ---- | -------------------------------------- | +| slotId | number | Yes | Card slot ID.
- **0**: card slot 1
- **1**: card slot 2| + **Return value** | Type | Description | @@ -912,7 +920,8 @@ Checks whether SMS is supported on IMS. This API uses a promise to return the re **Example** ```js -let promise = sms.isImsSmsSupported(); +let slotId = 0; +let promise = sms.isImsSmsSupported(slotId); promise.then(data => { console.log(`isImsSmsSupported success, promise: data->${JSON.stringify(data)}`); }).catch(err => { diff --git a/en/application-dev/reference/apis/js-apis-socket.md b/en/application-dev/reference/apis/js-apis-socket.md index 1344f4c6ec574ebb464c844350f331d40804cce8..32c4d78bfbd2fbace12d6294d03488f06aed27ba 100644 --- a/en/application-dev/reference/apis/js-apis-socket.md +++ b/en/application-dev/reference/apis/js-apis-socket.md @@ -21,7 +21,7 @@ Creates a **UDPSocket** object. **Return value** | Type | Description | -| :--------------------------------- | :---------------------- | +| --------------------------------- | ---------------------- | | [UDPSocket](#udpsocket) | **UDPSocket** object.| @@ -87,7 +87,7 @@ Binds the IP address and port number. The port number can be specified or random **Return value** | Type | Description | -| :-------------- | :----------------------------------------- | +| -------------- | ----------------------------------------- | | Promise\ | Promise used to return the result.| **Example** @@ -164,7 +164,7 @@ Before sending data, call [UDPSocket.bind()](#bind) to bind the IP address and p **Return value** | Type | Description | -| :-------------- | :--------------------------------------------- | +| -------------- | --------------------------------------------- | | Promise\ | Promise used to return the result.| **Example** @@ -230,7 +230,7 @@ Closes a UDPSocket connection. This API uses a promise to return the result. **Return value** | Type | Description | -| :-------------- | :----------------------------------------- | +| -------------- | ----------------------------------------- | | Promise\ | Promise used to return the result.| **Example** @@ -252,7 +252,7 @@ getState\(callback: AsyncCallback\): void Obtains the status of the UDPSocket connection. This API uses an asynchronous callback to return the result. ->**NOTE** +>**NOTE**
>This API can be called only after [bind](#bind) is successfully called. **Required permissions**: ohos.permission.INTERNET @@ -292,7 +292,7 @@ getState\(\): Promise Obtains the status of the UDPSocket connection. This API uses a promise to return the result. ->**NOTE** +>**NOTE**
>This API can be called only after [bind](#bind) is successfully called. **Required permissions**: ohos.permission.INTERNET @@ -302,7 +302,7 @@ Obtains the status of the UDPSocket connection. This API uses a promise to retur **Return value** | Type | Description | -| :----------------------------------------------- | :----------------------------------------- | +| ----------------------------------------------- | ----------------------------------------- | | Promise<[SocketStateBase](#socketstatebase)> | Promise used to return the result.| **Example** @@ -331,7 +331,7 @@ setExtraOptions\(options: UDPExtraOptions, callback: AsyncCallback\): voi Sets other properties of the UDPSocket connection. This API uses an asynchronous callback to return the result. ->**NOTE** +>**NOTE**
>This API can be called only after [bind](#bind) is successfully called. **Required permissions**: ohos.permission.INTERNET @@ -379,7 +379,7 @@ setExtraOptions\(options: UDPExtraOptions\): Promise Sets other properties of the UDPSocket connection. This API uses a promise to return the result. ->**NOTE** +>**NOTE**
>This API can be called only after [bind](#bind) is successfully called. **Required permissions**: ohos.permission.INTERNET @@ -395,7 +395,7 @@ Sets other properties of the UDPSocket connection. This API uses a promise to re **Return value** | Type | Description | -| :-------------- | :--------------------------------------------------- | +| -------------- | --------------------------------------------------- | | Promise\ | Promise used to return the result.| **Example** @@ -454,7 +454,7 @@ off\(type: 'message', callback?: Callback<\{message: ArrayBuffer, remoteInfo: So Disables listening for message receiving events of the UDPSocket connection. This API uses an asynchronous callback to return the result. ->**NOTE** +>**NOTE**
>You can pass the callback of the **on** function if you want to cancel listening for a certain type of event. If you do not pass the callback, you will cancel listening for all events. **System capability**: SystemCapability.Communication.NetStack @@ -514,7 +514,7 @@ off\(type: 'listening' | 'close', callback?: Callback\): void Disables listening for data packet message events or close events of the UDPSocket connection. This API uses an asynchronous callback to return the result. ->**NOTE** +>**NOTE**
>You can pass the callback of the **on** function if you want to cancel listening for a certain type of event. If you do not pass the callback, you will cancel listening for all events. **System capability**: SystemCapability.Communication.NetStack @@ -579,7 +579,7 @@ off\(type: 'error', callback?: ErrorCallback\): void Disables listening for error events of the UDPSocket connection. This API uses an asynchronous callback to return the result. ->**NOTE** +>**NOTE**
>You can pass the callback of the **on** function if you want to cancel listening for a certain type of event. If you do not pass the callback, you will cancel listening for all events. **System capability**: SystemCapability.Communication.NetStack @@ -678,7 +678,7 @@ Creates a **TCPSocket** object. **Return value** | Type | Description | - | :--------------------------------- | :---------------------- | + | --------------------------------- | ---------------------- | | [TCPSocket](#tcpsocket) | **TCPSocket** object.| **Example** @@ -743,7 +743,7 @@ Binds the IP address and port number. The port number can be specified or random **Return value** | Type | Description | -| :-------------- | :------------------------------------------------------- | +| -------------- | ------------------------------------------------------- | | Promise\ | Promise used to return the result.| **Example** @@ -809,7 +809,7 @@ Sets up a connection to the specified IP address and port number. This API uses **Return value** | Type | Description | -| :-------------- | :--------------------------------------------------------- | +| -------------- | --------------------------------------------------------- | | Promise\ | Promise used to return the result.| **Example** @@ -831,7 +831,7 @@ send\(options: TCPSendOptions, callback: AsyncCallback\): void Sends data over a TCPSocket connection. This API uses an asynchronous callback to return the result. ->**NOTE** +>**NOTE**
>This API can be called only after [connect](#connect) is successfully called. **Required permissions**: ohos.permission.INTERNET @@ -873,7 +873,7 @@ send\(options: TCPSendOptions\): Promise Sends data over a TCPSocket connection. This API uses a promise to return the result. ->**NOTE** +>**NOTE**
>This API can be called only after [connect](#connect) is successfully called. **Required permissions**: ohos.permission.INTERNET @@ -889,7 +889,7 @@ Sends data over a TCPSocket connection. This API uses a promise to return the re **Return value** | Type | Description | -| :-------------- | :------------------------------------------------- | +| -------------- | ------------------------------------------------- | | Promise\ | Promise used to return the result.| **Example** @@ -957,7 +957,7 @@ Closes a TCPSocket connection. This API uses a promise to return the result. **Return value** | Type | Description | -| :-------------- | :----------------------------------------- | +| -------------- | ----------------------------------------- | | Promise\ | Promise used to return the result.| **Example** @@ -979,7 +979,7 @@ getRemoteAddress\(callback: AsyncCallback\): void Obtains the remote address of a socket connection. This API uses an asynchronous callback to return the result. ->**NOTE** +>**NOTE**
>This API can be called only after [connect](#connect) is successfully called. **Required permissions**: ohos.permission.INTERNET @@ -1018,7 +1018,7 @@ getRemoteAddress\(\): Promise Obtains the remote address of a socket connection. This API uses a promise to return the result. ->**NOTE** +>**NOTE**
>This API can be called only after [connect](#connect) is successfully called. **Required permissions**: ohos.permission.INTERNET @@ -1028,7 +1028,7 @@ Obtains the remote address of a socket connection. This API uses a promise to re **Return value** | Type | Description | -| :------------------------------------------ | :------------------------------------------ | +| ------------------------------------------ | ------------------------------------------ | | Promise<[NetAddress](#netaddress)> | Promise used to return the result.| **Example** @@ -1056,7 +1056,7 @@ getState\(callback: AsyncCallback\): void Obtains the status of the TCPSocket connection. This API uses an asynchronous callback to return the result. ->**NOTE** +>**NOTE**
>This API can be called only after [bind](#bind) or [connect](#connect) is successfully called. **Required permissions**: ohos.permission.INTERNET @@ -1096,7 +1096,7 @@ getState\(\): Promise Obtains the status of the TCPSocket connection. This API uses a promise to return the result. ->**NOTE** +>**NOTE**
>This API can be called only after [bind](#bind) or [connect](#connect) is successfully called. **Required permissions**: ohos.permission.INTERNET @@ -1106,7 +1106,7 @@ Obtains the status of the TCPSocket connection. This API uses a promise to retur **Return value** | Type | Description | -| :----------------------------------------------- | :----------------------------------------- | +| ----------------------------------------------- | ----------------------------------------- | | Promise<[SocketStateBase](#socketstatebase)> | Promise used to return the result.| @@ -1135,7 +1135,7 @@ setExtraOptions\(options: TCPExtraOptions, callback: AsyncCallback\): voi Sets other properties of the TCPSocket connection. This API uses an asynchronous callback to return the result. ->**NOTE** +>**NOTE**
>This API can be called only after [bind](#bind) or [connect](#connect) is successfully called. **Required permissions**: ohos.permission.INTERNET @@ -1184,7 +1184,7 @@ setExtraOptions\(options: TCPExtraOptions\): Promise Sets other properties of the TCPSocket connection. This API uses a promise to return the result. ->**NOTE** +>**NOTE**
>This API can be called only after [bind](#bind) or [connect](#connect) is successfully called. **Required permissions**: ohos.permission.INTERNET @@ -1200,7 +1200,7 @@ Sets other properties of the TCPSocket connection. This API uses a promise to re **Return value** | Type | Description | -| :-------------- | :--------------------------------------------------- | +| -------------- | --------------------------------------------------- | | Promise\ | Promise used to return the result.| @@ -1263,7 +1263,7 @@ off\(type: 'message', callback?: Callback<\{message: ArrayBuffer, remoteInfo: So Disables listening for message receiving events of the TCPSocket connection. This API uses an asynchronous callback to return the result. ->**NOTE** +>**NOTE**
>You can pass the callback of the **on** function if you want to cancel listening for a certain type of event. If you do not pass the callback, you will cancel listening for all events. **System capability**: SystemCapability.Communication.NetStack @@ -1324,7 +1324,7 @@ off\(type: 'connect' | 'close', callback?: Callback\): void Disables listening for connection or close events of the TCPSocket connection. This API uses an asynchronous callback to return the result. ->**NOTE** +>**NOTE**
>You can pass the callback of the **on** function if you want to cancel listening for a certain type of event. If you do not pass the callback, you will cancel listening for all events. **System capability**: SystemCapability.Communication.NetStack @@ -1388,7 +1388,7 @@ off\(type: 'error', callback?: ErrorCallback\): void Disables listening for error events of the TCPSocket connection. This API uses an asynchronous callback to return the result. ->**NOTE** +>**NOTE**
>You can pass the callback of the **on** function if you want to cancel listening for a certain type of event. If you do not pass the callback, you will cancel listening for all events. **System capability**: SystemCapability.Communication.NetStack @@ -1464,7 +1464,7 @@ Creates a **TLSSocket** object. **Return value** | Type | Description | -| :--------------------------------- | :---------------------- | +| --------------------------------- | ---------------------- | | [TLSSocket](#tlssocket9) | **TLSSocket** object.| **Example** @@ -1534,7 +1534,7 @@ Binds the IP address and port number. This API uses a promise to return the resu **Return value** | Type | Description | -| :-------------- | :------------------------------------------------------- | +| -------------- | ------------------------------------------------------- | | Promise\ | Promise used to return the result. If the operation fails, an error message is returned.| **Error codes** @@ -1608,7 +1608,7 @@ Obtains the status of the TLSSocket connection. This API uses a promise to retur **Return value** | Type | Description | -| :----------------------------------------------- | :----------------------------------------- | +| ----------------------------------------------- | ----------------------------------------- | | Promise\<[SocketStateBase](#socketstatebase)> | Promise used to return the result. If the operation fails, an error message is returned.| **Error codes** @@ -1705,7 +1705,7 @@ Sets other properties of the TCPSocket connection after successful binding of th **Return value** | Type | Description | -| :-------------- | :--------------------------------------------------- | +| -------------- | --------------------------------------------------- | | Promise\ | Promise used to return the result. If the operation fails, an error message is returned.| **Error codes** @@ -1984,7 +1984,7 @@ Obtains the remote address of a TLSSocket connection. This API uses a promise to **Return value** | Type | Description | -| :------------------------------------------ | :------------------------------------------ | +| ------------------------------------------ | ------------------------------------------ | | Promise\<[NetAddress](#netaddress)> | Promise used to return the result. If the operation fails, an error message is returned.| **Error codes** @@ -2049,7 +2049,7 @@ Obtains the local digital certificate after a TLSSocket connection is establishe **Return value** -| Type | Description | +| Type | Description | | -------------- | -------------------- | | Promise\<[X509CertRawData](#x509certrawdata9)> | Promise used to return the result. If the operation fails, an error message is returned.| @@ -2490,7 +2490,7 @@ Defines TLS connection options. | -------------- | ------------------------------------- | --- |-------------- | | address | [NetAddress](#netaddress) | Yes | Gateway address. | | secureOptions | [TLSSecureOptions](#tlssecureoptions9) | Yes| TLS security options.| -| ALPNProtocols | Array\ | No| Application Layer Protocol Negotiation (ALPN) protocols. | +| ALPNProtocols | Array\ | Yes| Application Layer Protocol Negotiation (ALPN) protocols. | ## TLSSecureOptions9+ diff --git a/en/application-dev/reference/apis/js-apis-userFileManager.md b/en/application-dev/reference/apis/js-apis-userFileManager.md new file mode 100644 index 0000000000000000000000000000000000000000..5249fa7cc0feff1afbf6e79fe7fb3263434d346a --- /dev/null +++ b/en/application-dev/reference/apis/js-apis-userFileManager.md @@ -0,0 +1,2471 @@ +# @ohos.filemanagement.userFileManager + +The **userFileManager** module provides user data management capabilities, including accessing and modifying user media data (audio and video clips, images, and files). + +> **NOTE** +> +> The initial APIs of this module are supported since API version 9. Newly added APIs will be marked with a superscript to indicate their earliest API version. +> The APIs provided by this module are system APIs. + +## Modules to Import + +```ts +import userFileManager from '@ohos.filemanagement.userFileManager'; +``` + +## userFileManager.getUserFileMgr + +getUserFileMgr(context: Context): UserFileManager + +Obtains a **UserFileManager** instance. This instance can be used to access and modify user media data (such as audio and video clips, images, and files). + +**Model restriction**: This API can be used only in the stage model. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| ------- | ------- | ---- | -------------------------- | +| context | [Context](js-apis-inner-app-context.md) | Yes | Context of the ability instance.| + +**Return value** + +| Type | Description | +| ----------------------------- | :---- | +| [UserFileManager](#userfilemanager) | **UserFileManager** instance obtained.| + +**Example** + +```ts +const context = getContext(this); +let mgr = userFileManager.getUserFileMgr(context); +``` + +## UserFileManager + +### getPhotoAssets + +getPhotoAssets(options: FetchOptions, callback: AsyncCallback<FetchResult<FileAsset>>): void; + + +Obtains image and video assets. This API uses an asynchronous callback to return the result. + + + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------ | ---- | ------------------------- | +| options | [FetchOptions](#fetchoptions) | Yes | Options for fetching the image and video assets. | +| callback | AsyncCallback<[FetchResult](#fetchresult)<[FileAsset](#fileasset)>> | Yes | Callback invoked to return the image and video assets obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getPhotoAssets'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOptions = { + fetchColumns: [], + predicates: predicates + }; + + mgr.getPhotoAssets(fetchOptions, async (err, fetchResult) => { + if (fetchResult != undefined) { + console.info('fetchResult success'); + let fileAsset = await fetchResult.getFirstObject(); + if (fileAsset != undefined) { + console.info("fileAsset.displayName :" + fileAsset.displayName); + } + } else { + console.info('fetchResult fail' + err); + } + }); +} +``` + + +### getPhotoAssets + +getPhotoAssets(options: FetchOptions): Promise<FetchResult<FileAsset>>; + +Obtains image and video assets. This API uses a promise to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO + +**Parameters** + +| Name | Type | Mandatory| Description | +| ------- | ------------------- | ---- | ---------------- | +| options | [FetchOptions](#fetchoptions) | Yes | Options for fetching the image and video assets. | + +**Return value** + +| Type | Description | +| --------------------------- | -------------- | +| Promise<[FetchResult](#fetchresult)<[FileAsset](#fileasset)>> | Promise used to return the image and video assets obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getPhotoAssets'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOptions = { + fetchColumns: [], + predicates: predicates + }; + try { + var fetchResult = await mgr.getPhotoAssets(fetchOptions); + if (fetchResult != undefined) { + console.info('fetchResult success'); + let fileAsset = await fetchResult.getFirstObject(); + if (fileAsset != undefined) { + console.info("fileAsset.displayName :" + fileAsset.displayName); + } + } + } catch (err) { + console.info('getPhotoAssets failed, message = ', err); + } +} +``` +### createPhotoAsset + +createPhotoAsset(displayName: string, albumUri: string, callback: AsyncCallback<FileAsset>): void; + +Creates an image or video asset. This API uses an asynchronous callback to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------ | ---- | ------------------------- | +| displayName | string | Yes | File name of the image or video to create. | +| albumUri | string | Yes | URI of the album where the image or video is located. | +| callback | AsyncCallback<[FileAsset](#fileasset)> | Yes | Callback invoked to return the image or video created.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('createPhotoAssetDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOptions = { + predicates: predicates + }; + let albums = await mgr.getPhotoAlbums(fetchOptions); + let album = await albums.getFirstObject(); + let testFileName = "testFile" + Date.now() + ".jpg"; + mgr.createPhotoAsset(testFileName, album.albumUri, (err, fileAsset) => { + if (fileAsset != undefined) { + console.info('createPhotoAsset file displayName' + fileAsset.displayName); + console.info('createPhotoAsset successfully'); + } else { + console.info('createPhotoAsset failed, message = ', err); + } + }); +} +``` + +### createPhotoAsset + +createPhotoAsset(displayName: string, callback: AsyncCallback<FileAsset>): void; + +Creates an image or video asset. This API uses an asynchronous callback to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------ | ---- | ------------------------- | +| displayName | string | Yes | File name of the image or video to create. | +| callback | AsyncCallback<[FileAsset](#fileasset)> | Yes | Callback invoked to return the image or video created.| + +**Example** + +```ts +async function example() { + console.info('createPhotoAssetDemo'); + let testFileName = "testFile" + Date.now() + ".jpg"; + mgr.createPhotoAsset(testFileName, (err, fileAsset) => { + if (fileAsset != undefined) { + console.info('createPhotoAsset file displayName' + fileAsset.displayName); + console.info('createPhotoAsset successfully'); + } else { + console.info('createPhotoAsset failed, message = ', err); + } + }); +} +``` + +### createPhotoAsset + +createPhotoAsset(displayName: string, albumUri?: string): Promise<FileAsset>; + +Creates an image or video asset. This API uses a promise to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------ | ---- | ------------------------- | +| displayName | string | Yes | File name of the image or video to create. | +| albumUri | string | No | URI of the album where the image or video is located. | + +**Return value** + +| Type | Description | +| --------------------------- | -------------- | +| Promise<[FileAsset](#fileasset)> | Promise used to return the image or video created.| + +**Example** + +```ts +async function example() { + console.info('createPhotoAssetDemo'); + try { + let testFileName = "testFile" + Date.now() + ".jpg"; + let fileAsset = await mgr.createPhotoAsset(testFileName); + console.info('createPhotoAsset file displayName' + fileAsset.displayName); + console.info('createPhotoAsset successfully'); + } catch (err) { + console.info('createPhotoAsset failed, message = ', err); + } +} +``` + +### getPhotoAlbums + +getPhotoAlbums(options: AlbumFetchOptions, callback: AsyncCallback<FetchResult<Album>>): void; + + +Obtains image and video albums. This API uses an asynchronous callback to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------ | ---- | ------------------------- | +| options | [AlbumFetchOptions](#albumfetchoptions) | Yes | Options for fetching the albums. | +| callback | AsyncCallback<[FetchResult](#fetchresult)<[Album](#album)>> | Yes | Callback invoked to return the albums obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getPhotoAlbumsDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let albumFetchOptions = { + predicates: predicates + }; + + mgr.getPhotoAlbums(albumFetchOptions, (err, fetchResult) => { + if (fetchResult != undefined) { + console.info('albums.count = ' + fetchResult.getCount()); + fetchResult.getFirstObject((err, album) => { + if (album != undefined) { + console.info('first album.albumName = ' + album.albumName); + } else { + console.info('album is undefined, err = ', err); + } + }); + } else { + console.info('getPhotoAlbums fail, message = ', err); + } + }); +} +``` + +### getPhotoAlbums + +getPhotoAlbums(options: AlbumFetchOptions): Promise<FetchResult<Album>>; + +Obtains image and video albums. This API uses a promise to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------ | ---- | ------------------------- | +| options | [AlbumFetchOptions](#albumfetchoptions) | Yes | Options for fetching the albums. | + +**Return value** + +| Type | Description | +| --------------------------- | -------------- | +| Promise<[FetchResult](#fetchresult)<[Album](#album)>> | Promise used to return the albums obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getPhotoAlbumsDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let albumFetchOptions = { + predicates: predicates + }; + try { + let fetchResult = await mgr.getPhotoAlbums(albumFetchOptions); + console.info('album.count = ' + fetchResult.getCount()); + const album = await fetchResult.getFirstObject(); + console.info('first album.albumName = ' + album.albumName); + } catch (err) { + console.info('getPhotoAlbums fail, message = ' + err); + } +} +``` + +### getPrivateAlbum + +getPrivateAlbum(type: PrivateAlbumType, callback: AsyncCallback<FetchResult<PrivateAlbum>>): void; + + +Obtains the system album. This API uses an asynchronous callback to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------ | ---- | ------------------------- | +| type | [PrivateAlbumType](#privatealbumtype) | Yes | Type of the album to obtain. | +| callback | AsyncCallback<[FetchResult](#fetchresult)<[PrivateAlbum](#privatealbum)>> | Yes | Callback invoked to return the album obtained.| + +**Example** + +```ts +async function example() { + console.info('getPrivateAlbumDemo'); + mgr.getPrivateAlbum(userFileManager.PrivateAlbumType.TYPE_TRASH, async (err, fetchResult) => { + if (fetchResult != undefined) { + let trashAlbum = await fetchResult.getFirstObject(); + console.info('first album.albumName = ' + trashAlbum.albumName); + } else { + console.info('getPrivateAlbum failed. message = ', err); + } + }); +} +``` + +### getPrivateAlbum + +getPrivateAlbum(type: PrivateAlbumType): Promise<FetchResult<PrivateAlbum>>; + + +Obtains the system album. This API uses a promise to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------ | ---- | ------------------------- | +| type | [PrivateAlbumType](#privatealbumtype) | Yes | Type of the album to obtain. | + +**Return value** + +| Type | Description | +| --------------------------- | -------------- | +| Promise<[FetchResult](#fetchresult)<[PrivateAlbum](#privatealbum)>> | Promise used to return the album obtained.| + +**Example** + +```ts +async function example() { + console.info('getPrivateAlbumDemo'); + try { + var fetchResult = await mgr.getPrivateAlbum(userFileManager.PrivateAlbumType.TYPE_TRASH); + let trashAlbum = await fetchResult.getFirstObject(); + console.info('first album.albumName = ' + trashAlbum.albumName); + } catch (err) { + console.info('getPrivateAlbum failed. message = ', err); + } +} +``` + +### getAudioAssets + +getAudioAssets(options: FetchOptions, callback: AsyncCallback<FetchResult<FileAsset>>): void; + + +Obtains audio assets. This API uses an asynchronous callback to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Required permissions**: ohos.permission.READ_AUDIO + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------ | ---- | ------------------------- | +| options | [FetchOptions](#fetchoptions) | Yes | Options for fetching the audio assets. | +| callback | AsyncCallback<[FetchResult](#fetchresult)<[FileAsset](#fileasset)>> | Yes | Callback invoked to return the audio assets obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getAudioAssets'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOptions = { + fetchColumns: [], + predicates: predicates + }; + + mgr.getAudioAssets(fetchOptions, async (err, fetchResult) => { + if (fetchResult != undefined) { + console.info('fetchFileResult success'); + let fileAsset = await fetchResult.getFirstObject(); + if (fileAsset != undefined) { + console.info("fileAsset.displayName :" + fileAsset.displayName); + } + } else { + console.info('fetchFileResult fail' + err); + } + }); +} +``` + +### getAudioAssets + +getAudioAssets(options: FetchOptions): Promise<FetchResult<FileAsset>>; + + +Obtains audio assets. This API uses a promise to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Required permissions**: ohos.permission.READ_AUDIO + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------ | ---- | ------------------------- | +| options | [FetchOptions](#fetchoptions) | Yes | Options for fetching the audio assets. | + +**Return value** + +| Type | Description | +| --------------------------- | -------------- | +| Promise<[FetchResult](#fetchresult)<[FileAsset](#fileasset)>> | Promise used to return the audio assets obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getAudioAssets'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOptions = { + fetchColumns: [], + predicates: predicates + }; + try { + var fetchResult = await mgr.getAudioAssets(fetchOptions); + } catch (err) { + console.info('getAudioAssets failed, message = ', err); + } + + if (fetchResult != undefined) { + console.info('fetchFileResult success'); + let fileAsset = await fetchResult.getFirstObject(); + if (fileAsset != undefined) { + console.info("fileAsset.displayName :" + fileAsset.displayName); + } + } +} +``` +### delete + +delete(uri: string, callback: AsyncCallback<void>): void; + +Deletes a media file. This API uses an asynchronous callback to return the result. The deleted file is moved to the recycle bin. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------- | ---- | ---------- | +| uri | string | Yes | URI of the media file to delete.| +| callback | AsyncCallback<void> | Yes | Callback that returns no value.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('deleteAssetDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOptions = { + fetchColumns: [], + predicates: predicates + }; + try { + const fetchResult = await mgr.getPhotoAssets(fetchOptions); + var asset = await fetchResult.getFirstObject(); + } catch (err) { + console.info('fetch failed, message =', err); + } + + if (asset == undefined) { + console.error('asset not exist'); + return; + } + mgr.delete(asset.uri, (err) => { + if (err == undefined) { + console.info("delete successfully"); + } else { + console.info("delete failed with error:" + err); + } + }); +} +``` +### delete + +delete(uri: string): Promise<void>; + +Deletes a media file. This API uses a promise to return the result. The deleted file is moved to the recycle bin. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------- | ---- | ---------- | +| uri | string | Yes | URI of the media file to delete.| + +**Return value** + +| Type | Description | +| --------------------------------------- | ----------------- | +| Promise<void>| Promise that returns no value.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('deleteDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOptions = { + fetchColumns: [], + predicates: predicates + }; + try { + const fetchResult = await mgr.getPhotoAssets(fetchOptions); + var asset = await fetchResult.getFirstObject(); + } catch (err) { + console.info('fetch failed, message =', err); + } + + if (asset == undefined) { + console.error('asset not exist'); + return; + } + try { + await mgr.delete(asset.uri); + console.info("delete successfully"); + } catch (err) { + console.info("delete failed with error:" + err); + } +} +``` + +### on + +on(type: ChangeEvent, callback: Callback<void>): void + +Subscribes to changes of the file management library. This API uses a callback to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | -------------------- | ---- | ------------------------------------------------------------ | +| type | [ChangeEvent](#changeevent) | Yes | Type of event to subscribe to.
**deviceChange** indicates the device change.
**albumChange** indicates the album change.
**imageChange** indicates the image change.
**audioChange** indicates the audio file change.
**videoChange** indicates the video file change.
**remoteFileChange** indicates the file change on the registered device.| +| callback | Callback<void> | Yes | Callback that returns no value. | + +**Example** + +```ts +async function example() { + console.info('onDemo'); + let count = 0; + mgr.on('imageChange', () => { + count++; + // Image file changed. Do something. + }); + try { + let testFileName = "testFile" + Date.now() + ".jpg"; + let fileAsset = await mgr.createPhotoAsset(testFileName); + console.info('createPhotoAsset file displayName' + fileAsset.displayName); + console.info('createPhotoAsset successfully'); + } catch (err) { + console.info('createPhotoAsset failed, message = ' + err); + } + //sleep 1s + if (count > 0) { + console.info("onDemo success"); + } else { + console.info("onDemo fail"); + } + mgr.off('imageChange', () => { + // Unsubscription succeeds. + }); +} +``` + +### off + +off(type: ChangeEvent, callback?: Callback<void>): void + +Unsubscribes from changes of the file management library. This API uses a callback to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | -------------------- | ---- | ------------------------------------------------------------ | +| type | [ChangeEvent](#changeevent) | Yes | Type of event to subscribe to.
**deviceChange** indicates the device change.
**albumChange** indicates the album change.
**imageChange** indicates the image change.
**audioChange** indicates the audio file change.
**videoChange** indicates the video file change.
**remoteFileChange** indicates the file change on the registered device.| +| callback | Callback<void> | No | Callback that returns no value. | + +**Example** + +```ts +async function example() { + console.info('offDemo'); + let count = 0; + mgr.on('imageChange', () => { + count++; + // Image file changed. Do something. + }); + + mgr.off('imageChange', () => { + // Unsubscription succeeds. + }); + + try { + let testFileName = "testFile" + Date.now() + ".jpg"; + let fileAsset = await mgr.createPhotoAsset(testFileName); + console.info('createPhotoAsset file displayName' + fileAsset.displayName); + console.info('createPhotoAsset successfully'); + } catch (err) { + console.info('createPhotoAsset failed, message = ' + err); + } + //sleep 1s + if (count == 0) { + console.info("offDemo success"); + } else { + console.info("offDemo fail"); + } +} +``` + +### getActivePeers + +getActivePeers(callback: AsyncCallback<Array<PeerInfo>>): void; + +Obtains information about online peer devices. This API uses an asynchronous callback to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.DistributedCore + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | --------------------------------- | ---- | ------------ | +| callback | AsyncCallback<Array<[PeerInfo](#peerinfo)>> | Yes | Callback invoked to return the online peer device list.| + +**Example** + +```ts +async function example() { + console.info('getActivePeersDemo'); + mgr.getActivePeers((err, devicesInfo) => { + if (devicesInfo != undefined) { + console.log('getActivePeers succeed.'); + for (let i = 0; i < devicesInfo.length; i++) { + console.info('get distributed info ' + devicesInfo[i].deviceName + devicesInfo[i].networkId); + } + } else { + console.info('getActivePeers failed. message = ', err); + } + }); +} +``` + +### getActivePeers + +getActivePeers(): Promise<Array<PeerInfo>>; + +Obtains information about online peer devices. This API uses a promise to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.DistributedCore + +**Return value** + +| Type | Description | +| --------------------------- | ----------------------------- | +| Promise<Array<[PeerInfo](#peerinfo)>> | Promise used to return the online device list.| + +**Example** + +```ts +async function example() { + console.info('getActivePeersDemo'); + try { + var devicesInfo = await mgr.getActivePeers(); + } catch (err) { + console.info('getActivePeers failed. message = ', err); + } + if (devicesInfo != undefined) { + console.log('getActivePeers succeed.'); + for (let i = 0; i < devicesInfo.length; i++) { + console.info('get distributed info ' + devicesInfo[i].deviceName + devicesInfo[i].networkId); + } + } else { + console.info('get distributed fail'); + } +} +``` + +### getAllPeers + +getAllPeers(callback: AsyncCallback<Array<PeerInfo>>): void; + +Obtains information about all peer devices. This API uses an asynchronous callback to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.DistributedCore + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | --------------------------------- | ---- | ------------ | +| callback | AsyncCallback<Array<[PeerInfo](#peerinfo)>> | Yes | Callback invoked to return the online peer device list.| + +**Example** + +```ts +async function example() { + console.info('getAllPeersDemo'); + mgr.getAllPeers((err, devicesInfo) => { + if (devicesInfo != undefined) { + console.log('getAllPeers succeed.'); + for (let i = 0; i < devicesInfo.length; i++) { + console.info('get distributed info ' + devicesInfo[i].deviceName + devicesInfo[i].networkId); + } + } else { + console.info('getAllPeers failed. message = ', err); + } + }); +} +``` + +### getAllPeers + +getAllPeers(): Promise<Array<PeerInfo>>; + +Obtains information about all peer devices. This API uses a promise to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.DistributedCore + +**Return value** + +| Type | Description | +| --------------------------- | ----------------------------- | +| Promise<Array<[PeerInfo](#peerinfo)>> | Promise used to return the peer device list.| + +**Example** + +```ts +async function example() { + console.info('getAllPeersDemo'); + try { + var devicesInfo = await mgr.getAllPeers(); + } catch (err) { + console.info('getAllPeers failed. message = ', err); + } + if (devicesInfo != undefined) { + console.log('getAllPeers succeed.'); + for (let i = 0; i < devicesInfo.length; i++) { + console.info('get distributed info ' + devicesInfo[i].deviceName + devicesInfo[i].networkId); + } + } else { + console.info('get distributed fail'); + } +} +``` + +### release + +release(callback: AsyncCallback<void>): void + +Releases this **UserFileManager** instance. This API uses an asynchronous callback to return the result. +Call this API when the APIs in the **UserFileManager** instance are no longer used. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------- | ---- | -------------------- | +| callback | AsyncCallback<void> | Yes | Callback that returns no value.| + +**Example** + +```ts +async function example() { + console.info('releaseDemo'); + mgr.release((err) => { + if (err != undefined) { + console.info('release failed. message = ', err); + } else { + console.info('release ok.'); + } + }); +} +``` + +### release + +release(): Promise<void> + +Releases this **UserFileManager** instance. This API uses a promise to return the result. +Call this API when the APIs in the **UserFileManager** instance are no longer used. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Return value** + +| Type | Description | +| ------------------- | --------------------------------- | +| Promise<void> | Promise that returns no value.| + +**Example** + +```ts +async function example() { + console.info('releaseDemo'); + try { + await mgr.release(); + console.info('release ok.'); + } catch (err) { + console.info('release failed. message = ', err); + } +} +``` + +## FileAsset + +Provides APIs for encapsulating file asset attributes. + +### Attributes + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +| Name | Type | Readable| Writable| Description | +| ------------------------- | ------------------------ | ---- | ---- | ------------------------------------------------------ | +| uri | string | Yes | No | File asset URI, for example, **dataability:///media/image/2**. | +| fileType | [FileType](#filetype) | Yes | No | Type of the file. | +| displayName | string | Yes | Yes | File name, including the file name extension, to display. | + + +### get + +get(member: string): MemberType; + +Obtains the value of a **FileAsset** parameter. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory | Description | +| -------- | ------------------------- | ---- | ----- | +| member | string | Yes | Name of the parameter to obtain, for example, **ImageVideoKey.URI**.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('fileAssetGetDemo'); + try { + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + let fileAsset = await fetchResult.getFirstObject(); + let title = userFileManager.ImageVideoKey.TITLE; + let fileAssetTitle = fileAsset.get(title.toString()); + console.info('fileAsset Get fileAssetTitle = ', fileAssetTitle); + } catch (err) { + console.info('release failed. message = ', err); + } +} +``` + +### set + +set(member: string, value: string): void; + +Sets a **FileAsset** parameter. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory | Description | +| -------- | ------------------------- | ---- | ----- | +| member | string | Yes | Name of the parameter to set, for example, **ImageVideoKey.URI**.| +| value | string | Yes | Value to set. Only the value of **ImageVideoKey.TITLE** can be changed.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('fileAssetSetDemo'); + try { + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + let fileAsset = await fetchResult.getFirstObject(); + let title = userFileManager.ImageVideoKey.TITLE; + fileAsset.set(title.toString(), "newTitle"); + } catch (err) { + console.info('release failed. message = ', err); + } +} +``` + +### commitModify + +commitModify(callback: AsyncCallback<void>): void + +Commits the modification on the file metadata to the database. This API uses an asynchronous callback to return the result. + +**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.WRITE_AUDIO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory | Description | +| -------- | ------------------------- | ---- | ----- | +| callback | AsyncCallback<void> | Yes | Callback that returns no value.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('commitModifyDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + let fileAsset = await fetchResult.getFirstObject(); + let title = userFileManager.ImageVideoKey.TITLE; + let fileAssetTitle = fileAsset.get(title.toString()); + console.info('fileAsset Get fileAssetTitle = ', fileAssetTitle); + fileAsset.set(title.toString(), "newTitle"); + fileAsset.commitModify((err) => { + if (err == undefined) { + let newFileAssetTitle = fileAsset.get(title.toString()); + console.info('fileAsset Get newFileAssetTitle = ', newFileAssetTitle); + } else { + console.info('commitModify failed, message =', err); + } + }); +} +``` + +### commitModify + +commitModify(): Promise<void> + +Commits the modification on the file metadata to the database. This API uses a promise to return the result. + +**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.WRITE_AUDIO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Return value** + +| Type | Description | +| ------------------- | ---------- | +| Promise<void> | Promise that returns no value.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('commitModifyDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + let fileAsset = await fetchResult.getFirstObject(); + let title = userFileManager.ImageVideoKey.TITLE; + let fileAssetTitle = fileAsset.get(title.toString()); + console.info('fileAsset Get fileAssetTitle = ', fileAssetTitle); + fileAsset.set(title.toString(), "newTitle"); + try { + await fileAsset.commitModify(); + let newFileAssetTitle = fileAsset.get(title.toString()); + console.info('fileAsset Get newFileAssetTitle = ', newFileAssetTitle); + } catch (err) { + console.info('release failed. message = ', err); + } +} +``` + +### open + +open(mode: string, callback: AsyncCallback<number>): void + +Opens this file asset. This API uses an asynchronous callback to return the result. + +>**NOTE** +> +>The write operations are mutually exclusive. After a write operation is complete, you must call **close** to release the resource. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, ohos.permission.WRITE_IMAGEVIDEO, or ohos.permission.WRITE_AUDIO + + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory | Description | +| -------- | --------------------------- | ---- | ----------------------------------- | +| mode | string | Yes | File open mode, which can be **r** (read-only), **w** (write-only), or **rw** (read-write).| +| callback | AsyncCallback<number> | Yes | Callback used to return the file handle. | + +**Example** + +```ts +async function example() { + console.info('openDemo'); + let testFileName = "testFile" + Date.now() + ".jpg"; + const fileAsset = await mgr.createPhotoAsset(testFileName); + fileAsset.open('rw', (err, fd) => { + if (fd != undefined) { + console.info('File fd' + fd); + fileAsset.close(fd); + } else { + console.info('File err' + err); + } + }); +} +``` + +### open + +open(mode: string): Promise<number> + +Opens this file asset. This API uses a promise to return the result. + +>**NOTE** +> +>The write operations are mutually exclusive. After a write operation is complete, you must call **close** to release the resource. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, ohos.permission.WRITE_IMAGEVIDEO, or ohos.permission.WRITE_AUDIO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory | Description | +| ---- | ------ | ---- | ----------------------------------- | +| mode | string | Yes | File open mode, which can be **r** (read-only), **w** (write-only), or **rw** (read-write).| + +**Return value** + +| Type | Description | +| --------------------- | ------------- | +| Promise<number> | Promise used to return the file handle.| + +**Example** + +```ts +async function example() { + console.info('openDemo'); + try { + let testFileName = "testFile" + Date.now() + ".jpg"; + const fileAsset = await mgr.createPhotoAsset(testFileName); + let fd = await fileAsset.open('rw'); + if (fd != undefined) { + console.info('File fd' + fd); + fileAsset.close(fd); + } else { + console.info(' open File fail'); + } + } catch (err) { + console.info('open Demo err' + err); + } +} +``` + +### close + +close(fd: number, callback: AsyncCallback<void>): void + +Closes this file asset. This API uses an asynchronous callback to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory | Description | +| -------- | ------------------------- | ---- | ----- | +| fd | number | Yes | File descriptor.| +| callback | AsyncCallback<void> | Yes | Callback that returns no value.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('closeDemo'); + try { + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + const fileAsset = await fetchResult.getFirstObject(); + let fd = await fileAsset.open('rw'); + console.info('file fd', fd); + fileAsset.close(fd, (err) => { + if (err == undefined) { + console.info('asset close succeed.'); + } else { + console.info('close failed, message = ' + err); + } + }); + } catch (err) { + console.info('close failed, message = ' + err); + } +} +``` + +### close + +close(fd: number): Promise<void> + +Closes this file asset. This API uses a promise to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory | Description | +| ---- | ------ | ---- | ----- | +| fd | number | Yes | File descriptor.| + +**Return value** + +| Type | Description | +| ------------------- | ---------- | +| Promise<void> | Promise that returns no value.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('closeDemo'); + try { + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + const asset = await fetchResult.getFirstObject(); + let fd = await asset.open('rw'); + console.info('file fd', fd); + await asset.close(fd); + console.info('asset close succeed.'); + } catch (err) { + console.info('close failed, message = ' + err); + } +} +``` + +### getThumbnail + +getThumbnail(callback: AsyncCallback<image.PixelMap>): void + +Obtains the thumbnail of this file asset. This API uses an asynchronous callback to return the result. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO or ohos.permission.READ_AUDIO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory | Description | +| -------- | ----------------------------------- | ---- | ---------------- | +| callback | AsyncCallback<[image.PixelMap](js-apis-image.md#pixelmap7)> | Yes | Callback invoked to return the pixel map of the thumbnail.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getThumbnailDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + const asset = await fetchResult.getFirstObject(); + console.info('asset displayName = ', asset.displayName); + asset.getThumbnail((err, pixelMap) => { + if (err == undefined) { + console.info('getThumbnail successful ' + pixelMap); + } else { + console.info('getThumbnail fail', err); + } + }); +} +``` + +### getThumbnail + +getThumbnail(size: image.Size, callback: AsyncCallback<image.PixelMap>): void + +Obtains the file thumbnail of the given size. This API uses an asynchronous callback to return the result. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO or ohos.permission.READ_AUDIO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory | Description | +| -------- | ----------------------------------- | ---- | ---------------- | +| size | [image.Size](js-apis-image.md#size) | Yes | Size of the thumbnail to obtain. | +| callback | AsyncCallback<[image.PixelMap](js-apis-image.md#pixelmap7)> | Yes | Callback invoked to return the pixel map of the thumbnail.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getThumbnailDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let size = { width: 720, height: 720 }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + const asset = await fetchResult.getFirstObject(); + console.info('asset displayName = ', asset.displayName); + asset.getThumbnail(size, (err, pixelMap) => { + if (err == undefined) { + console.info('getThumbnail successful ' + pixelMap); + } else { + console.info('getThumbnail fail', err); + } + }); +} +``` + +### getThumbnail + +getThumbnail(size?: image.Size): Promise<image.PixelMap> + +Obtains the file thumbnail of the given size. This API uses a promise to return the result. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO or ohos.permission.READ_AUDIO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory | Description | +| ---- | -------------- | ---- | ----- | +| size | [image.Size](js-apis-image.md#size) | No | Size of the thumbnail to obtain.| + +**Return value** + +| Type | Description | +| ----------------------------- | --------------------- | +| Promise<[image.PixelMap](js-apis-image.md#pixelmap7)> | Promise used to return the pixel map of the thumbnail.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getThumbnailDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let size = { width: 720, height: 720 }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + const asset = await fetchResult.getFirstObject(); + console.info('asset displayName = ', asset.displayName); + asset.getThumbnail(size).then((pixelMap) => { + console.info('getThumbnail successful ' + pixelMap); + }).catch((err) => { + console.info('getThumbnail fail' + err); + }); +} +``` + +### favorite + +favorite(isFavorite: boolean, callback: AsyncCallback<void>): void + +Favorites or unfavorites this file asset. This API uses an asynchronous callback to return the result. + +**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.WRITE_AUDIO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory | Description | +| ---------- | ------------------------- | ---- | ---------------------------------- | +| isFavorite | boolean | Yes | Operation to perform. The value **true** means to favorite the file asset, and **false** means the opposite.| +| callback | AsyncCallback<void> | Yes | Callback that returns no value. | + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('favoriteDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + const asset = await fetchResult.getFirstObject(); + asset.favorite(true, (err) => { + if (err == undefined) { + console.info("favorite successfully"); + } else { + console.info("favorite failed with error:" + err); + } + }); +} +``` + +### favorite + +favorite(isFavorite: boolean): Promise<void> + +Favorites or unfavorites this file asset. This API uses a promise to return the result. + +**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.WRITE_AUDIO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory | Description | +| ---------- | ------- | ---- | ---------------------------------- | +| isFavorite | boolean | Yes | Operation to perform. The value **true** means to favorite the file asset, and **false** means the opposite.| + +**Return value** + +| Type | Description | +| ------------------- | ---------- | +| Promise<void> | Promise that returns no value.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('favoriteDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + const asset = await fetchResult.getFirstObject(); + asset.favorite(true).then(function () { + console.info("favorite successfully"); + }).catch(function (err) { + console.info("favorite failed with error:" + err); + }); +} +``` + +## FetchResult + +Provides APIs to manage the file retrieval result. + +### getCount + +getCount(): number + +Obtains the total number of files in the result set. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Return value** + +| Type | Description | +| ------ | -------- | +| number | Total number of files.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getCountDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + const fetchCount = fetchResult.getCount(); + console.info('fetchCount = ', fetchCount); +} +``` + +### isAfterLast + +isAfterLast(): boolean + +Checks whether the cursor is in the last row of the result set. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Return value** + +| Type | Description | +| ------- | ---------------------------------- | +| boolean | Returns **true** if the cursor is in the last row of the result set; returns **false** otherwise.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + const fetchCount = fetchResult.getCount(); + console.info('count:' + fetchCount); + let fileAsset = await fetchResult.getLastObject(); + if (!fetchResult.isAfterLast()) { + console.info('fileAsset isAfterLast displayName = ', fileAsset.displayName); + } else { + console.info('fileAsset not isAfterLast '); + } +} +``` + +### close + +close(): void + +Releases and invalidates this **FetchFileResult** instance. After this instance is released, the APIs in this instance cannot be invoked. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('fetchResultCloseDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + try { + let fetchResult = await mgr.getPhotoAssets(fetchOption); + await fetchResult.close(); + console.info('close succeed.'); + } catch (err) { + console.info('close fail. message = ' + err); + } +} +``` + +### getFirstObject + +getFirstObject(callback: AsyncCallback<T>): void + +Obtains the first file asset in the result set. This API uses an asynchronous callback to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | --------------------------------------------- | ---- | ------------------------------------------- | +| callback | AsyncCallback<T> | Yes | Callback invoked to return the first file asset.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getFirstObjectDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + fetchResult.getFirstObject((err, fileAsset) => { + if (fileAsset != undefined) { + console.info('fileAsset displayName: ', fileAsset.displayName); + } else { + console.info("fileAsset failed with err:" + err); + } + }); +} +``` + +### getFirstObject + +getFirstObject(): Promise<T> + +Obtains the first file asset in the result set. This API uses a promise to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Return value** + +| Type | Description | +| --------------------------------------- | -------------------------- | +| Promise<T> | Promise used to return the first file asset.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getFirstObjectDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + let fileAsset = await fetchResult.getFirstObject(); + console.info('fileAsset displayName: ', fileAsset.displayName); +} +``` + +### getNextObject + + getNextObject(callback: AsyncCallback<T>): void + +Obtains the next file asset in the result set. This API uses an asynchronous callback to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| --------- | --------------------------------------------- | ---- | ----------------------------------------- | +| callbacke | AsyncCallback<T> | Yes | Callback invoked to return the next file asset.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getNextObjectDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + await fetchResult.getFirstObject(); + if (fetchResult.isAfterLast()) { + fetchResult.getNextObject((err, fileAsset) => { + if (fileAsset != undefined) { + console.info('fileAsset displayName: ', fileAsset.displayName); + } else { + console.info("fileAsset failed with err:" + err); + } + }); + } +} +``` + +### getNextObject + + getNextObject(): Promise<T> + +Obtains the next file asset in the result set. This API uses a promise to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Return value** + +| Type | Description | +| --------------------------------------- | ----------------- | +| Promise<T> | Promise used to return the next file asset obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getNextObjectDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + await fetchResult.getFirstObject(); + if (fetchResult.isAfterLast()) { + let fileAsset = await fetchResult.getNextObject(); + console.info('fileAsset displayName: ', fileAsset.displayName); + } +} +``` + +### getLastObject + +getLastObject(callback: AsyncCallback<T>): void + +Obtains the last file asset in the result set. This API uses an asynchronous callback to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | --------------------------------------------- | ---- | --------------------------- | +| callback | AsyncCallback<T> | Yes | Callback invoked to return the last file asset obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getLastObjectDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + fetchResult.getLastObject((err, fileAsset) => { + if (fileAsset != undefined) { + console.info('fileAsset displayName: ', fileAsset.displayName); + } else { + console.info("fileAsset failed with err:" + err); + } + }); +} +``` + +### getLastObject + +getLastObject(): Promise<T> + +Obtains the last file asset in the result set. This API uses a promise to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Return value** + +| Type | Description | +| --------------------------------------- | ----------------- | +| Promise<T> | Promise used to return the last file asset obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getLastObjectDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + let fileAsset = await fetchResult.getLastObject(); + console.info('fileAsset displayName: ', fileAsset.displayName); +} +``` + +### getPositionObject + +getPositionObject(index: number, callback: AsyncCallback<T>): void + +Obtains a file asset with the specified index in the result set. This API uses an asynchronous callback to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory | Description | +| -------- | ---------------------------------------- | ---- | ------------------ | +| index | number | Yes | Index of the file asset to obtain. The value starts from **0**. | +| callback | AsyncCallback<T> | Yes | Callback invoked to return the file asset obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getPositionObjectDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + fetchResult.getPositionObject(0, (err, fileAsset) => { + if (fileAsset != undefined) { + console.info('fileAsset displayName: ', fileAsset.displayName); + } else { + console.info("fileAsset failed with err:" + err); + } + }); +} +``` + +### getPositionObject + +getPositionObject(index: number): Promise<T> + +Obtains a file asset with the specified index in the result set. This API uses a promise to return the result. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory | Description | +| ----- | ------ | ---- | -------------- | +| index | number | Yes | Index of the file asset to obtain. The value starts from **0**.| + +**Return value** + +| Type | Description | +| --------------------------------------- | ----------------- | +| Promise<T> | Promise used to return the file asset obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('getPositionObjectDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + let fetchResult = await mgr.getPhotoAssets(fetchOption); + let fileAsset = await fetchResult.getPositionObject(0); + console.info('fileAsset displayName: ', fileAsset.displayName); +} +``` + +## Album + +Provides APIs to manage albums. + +### Attributes + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +| Name | Type | Readable | Writable | Description | +| ------------ | ------ | ---- | ---- | ------- | +| albumName | string | Yes | Yes | Album name. | +| albumUri | string | Yes | No | Album URI. | +| dateModified | number | Yes | No | Date when the album was last modified. | +| count | number | Yes | No | Number of files in the album.| +| coverUri | string | Yes | No | URI of the cover file of the album. + +### getPhotoAssets + +getPhotoAssets(options: FetchOptions, callback: AsyncCallback<FetchResult<FileAsset>>): void; + +Obtains image and video assets. This API uses an asynchronous callback to return the result. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------- | ---- | ---------- | +| options | [FetchOptions](#fetchoptions) | Yes | Options for fetching the image and video assets.| +| callback | AsyncCallback<[FetchResult](#fetchresult)<[FileAsset](#fileasset)>> | Yes | Callback invoked to return the image and video assets obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('albumGetFileAssetsDemoCallback'); + + let predicates = new dataSharePredicates.DataSharePredicates(); + let albumFetchOptions = { + predicates: predicates + }; + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + const albumList = await mgr.getPhotoAlbums(albumFetchOptions); + const album = await albumList.getFirstObject(); + album.getPhotoAssets(fetchOption, (err, albumFetchResult) => { + if (albumFetchResult != undefined) { + console.info("album getPhotoAssets successfully, getCount:" + albumFetchResult.getCount()); + } else { + console.info("album getPhotoAssets failed with error:" + err); + } + }); +} +``` +### getPhotoAssets + +getPhotoAssets(options: FetchOptions): Promise<FetchResult<FileAsset>>; + +Obtains image and video assets. This API uses a promise to return the result. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------- | ---- | ---------- | +| options | [FetchOptions](#fetchoptions) | Yes | Options for fetching the image and video assets.| +| Promise | [FetchResult](#fetchresult)<[FileAsset](#fileasset)> | Yes | Promise used to return the image and video assets obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('albumGetFileAssetsDemoPromise'); + + let predicates = new dataSharePredicates.DataSharePredicates(); + let albumFetchOptions = { + predicates: predicates + }; + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + const albumList = await mgr.getPhotoAlbums(albumFetchOptions); + const album = await albumList.getFirstObject(); + album.getPhotoAssets(fetchOption).then((albumFetchResult) => { + console.info("album getFileAssets successfully, getCount:" + albumFetchResult.getCount()); + }).catch((err) => { + console.info("album getFileAssets failed with error:" + err); + }); +} +``` + +### commitModify + +commitModify(callback: AsyncCallback<void>): void; + +Commits the modification on the album attributes to the database. This API uses an asynchronous callback to return the result. + +**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------- | ---- | ---------- | +| callback | AsyncCallback<void> | Yes | Callback that returns no value.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('albumCommitModifyDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let albumFetchOptions = { + predicates: predicates + }; + const albumList = await mgr.getPhotoAlbums(albumFetchOptions); + const album = await albumList.getFirstObject(); + album.albumName = 'hello'; + album.commitModify((err) => { + if (err != undefined) { + console.info("commitModify failed with error:" + err); + } else { + console.info("commitModify successfully"); + } + }); +} +``` + +### commitModify + +commitModify(): Promise<void>; + +Commits the modification on the album attributes to the database. This API uses a promise to return the result. + +**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Return value** + +| Type | Description | +| ------------------- | ------------ | +| Promise<void> | Promise that returns no value.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('albumCommitModifyDemo'); + let predicates = new dataSharePredicates.DataSharePredicates(); + let albumFetchOptions = { + predicates: predicates + }; + try { + var albumList = await mgr.getPhotoAlbums(albumFetchOptions); + } catch (err) { + console.info('getPhotoAlbums failed. message = ', err); + } + const album = await albumList.getFirstObject(); + album.albumName = 'hello'; + album.commitModify().then(() => { + console.info("commitModify successfully"); + }).catch((err) => { + console.info("commitModify failed with error:" + err); + }); +} +``` + +## PrivateAlbum + +Provides APIs for managing the system albums. + +### Attributes + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +| Name | Type | Readable | Writable | Description | +| ------------ | ------ | ---- | ---- | ------- | +| albumName | string | Yes | Yes | Album name. | +| albumUri | string | Yes | No | Album URI. | +| dateModified | number | Yes | No | Date when the album was last modified. | +| count | number | Yes | No | Number of files in the album.| +| coverUri | string | Yes | No | URI of the cover file of the album. + +### getPhotoAssets + +getPhotoAssets(options: FetchOptions, callback: AsyncCallback<FetchResult<FileAsset>>): void; + +Obtains image and video assets from a system album. This API uses an asynchronous callback to return the result. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------- | ---- | ---------- | +| options | [FetchOptions](#fetchoptions) | Yes | Options for fetching the image and video assets.| +| callback | AsyncCallback<[FetchResult](#fetchresult)<[FileAsset](#fileasset)>> | Yes | Callback invoked to return the image and video assets obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('privateAlbumGetFileAssetsDemoCallback'); + let albumList = await mgr.getPrivateAlbum(userFileManager.PrivateAlbumType.TYPE_TRASH); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + const trashAlbum = await albumList.getFirstObject(); + trashAlbum.getPhotoAssets(fetchOption, (err, fetchResult) => { + if (fetchResult != undefined) { + let count = fetchResult.getCount(); + console.info('fetchResult.count = ', count); + } else { + console.info('getFileAssets failed, message = ', err); + } + }); +} + +``` +### getPhotoAssets + +getPhotoAssets(options: FetchOptions): Promise<FetchResult<FileAsset>>; + +Obtains image and video assets from a system album. This API uses a promise to return the result. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------- | ---- | ---------- | +| options | [FetchOptions](#fetchoptions) | Yes | Options for fetching the image and video assets.| + +**Return value** + +| Type | Description | +| --------------------------------------- | ----------------- | +| Promise:[FetchResult](#fetchresult)<[FileAsset](#fileasset)>| Promise used to return the image and video assets obtained.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('privateAlbumGetFileAssetsDemoPromise'); + let albumList = await mgr.getPrivateAlbum(userFileManager.PrivateAlbumType.TYPE_TRASH); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + const trashAlbum = await albumList.getFirstObject(); + let fetchResult = await trashAlbum.getPhotoAssets(fetchOption); + let count = fetchResult.getCount(); + console.info('fetchResult.count = ', count); +} +``` +### delete + +delete(uri: string, callback: AsyncCallback<void>): void; + +Deletes files from a system album. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------- | ---- | ---------- | +| uri | string | Yes | Album URI.| +| callback | AsyncCallback<void> | Yes | Callback that returns no value.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('privateAlbumDeleteCallback'); + let albumList = await mgr.getPrivateAlbum(userFileManager.PrivateAlbumType.TYPE_TRASH); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + const trashAlbum = await albumList.getFirstObject(); + let fetchResult = await trashAlbum.getPhotoAssets(fetchOption); + const fileAsset = await fetchResult.getFirstObject(); + let deleteFileUri = fileAsset.uri; + trashAlbum.delete(deleteFileUri, (err) => { + if (err != undefined) { + console.info('trashAlbum.delete failed, message = ', err); + } else { + console.info('trashAlbum.delete successfully'); + } + }); +} +``` +### delete + +delete(uri: string): Promise<void>; + +Deletes files from a system album. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------- | ---- | ---------- | +| uri | string | Yes | Album URI.| + +**Return value** + +| Type | Description | +| --------------------------------------- | ----------------- | +| Promise<void>| Promise that returns no value.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('privateAlbumDeleteDemoPromise'); + let albumList = await mgr.getPrivateAlbum(userFileManager.PrivateAlbumType.TYPE_TRASH); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + const trashAlbum = await albumList.getFirstObject(); + let fetchResult = await trashAlbum.getPhotoAssets(fetchOption); + const fileAsset = await fetchResult.getFirstObject(); + let deleteFileUri = fileAsset.uri; + trashAlbum.delete(deleteFileUri).then(() => { + console.info('trashAlbum.delete successfully'); + }).catch((err) => { + console.info('trashAlbum.delete failed, message = ', err); + }); +} +``` + +### recover + +recover(uri: string, callback: AsyncCallback<void>): void; + +Recovers files in a system album. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------- | ---- | ---------- | +| uri | string | Yes | Album URI.| +| callback | AsyncCallback<void> | Yes | Callback that returns no value.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('privateAlbumRecoverDemoCallback'); + let albumList = await mgr.getPrivateAlbum(userFileManager.PrivateAlbumType.TYPE_TRASH); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + const trashAlbum = await albumList.getFirstObject(); + let fetchResult = await trashAlbum.getPhotoAssets(fetchOption); + const fileAsset = await fetchResult.getFirstObject(); + let recoverFileUri = fileAsset.uri; + trashAlbum.recover(recoverFileUri, (err) => { + if (err != undefined) { + console.info('trashAlbum.recover failed, message = ', err); + } else { + console.info('trashAlbum.recover successfully'); + } + }); +} +``` +### recover + +recover(uri: string): Promise<void>; + +Recovers files in a system album. + +**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------- | ---- | ---------- | +| uri | string | Yes | Album URI.| + +**Return value** + +| Type | Description | +| --------------------------------------- | ----------------- | +| Promise<void>| Promise that returns no value.| + +**Example** + +```ts +import dataSharePredicates from '@ohos.data.dataSharePredicates'; + +async function example() { + console.info('privateAlbumRecoverDemoPromise'); + let albumList = await mgr.getPrivateAlbum(userFileManager.PrivateAlbumType.TYPE_TRASH); + let predicates = new dataSharePredicates.DataSharePredicates(); + let fetchOption = { + fetchColumns: [], + predicates: predicates + }; + const trashAlbum = await albumList.getFirstObject(); + let fetchResult = await trashAlbum.getPhotoAssets(fetchOption); + const fileAsset = await fetchResult.getFirstObject(); + let recoverFileUri = fileAsset.uri; + trashAlbum.recover(recoverFileUri).then(() => { + console.info('trashAlbum.recover successfully'); + }).catch((err) => { + console.info('trashAlbum.recover failed, message = ', err); + }); +} +``` + +## MemberType + +Enumerates the member types. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +| Name | Type| Readable | Writable | Description | +| ----- | ---- | ---- | ---- | ---- | +| number | number | Yes| Yes| The member is a number.| +| string | string | Yes| Yes| The member is a string.| +| boolean | boolean | Yes| Yes| The member is a Boolean value.| + +## ChangeEvent + +Enumerates the type of changes to observe. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +| Name | Type| Readable | Writable | Description| +| ----- | ---- | ---- | ---- | ---- | +| deviceChange | string | Yes| Yes| Device.| +| albumChange | string | Yes| Yes| Album.| +| imageChange | string | Yes| Yes| Image.| +| audioChange | string | Yes| Yes| Audio.| +| videoChange | string | Yes| Yes| Video.| +| remoteFileChange | string | Yes| Yes| Remote file.| + +## PeerInfo + +Defines information about a registered device. + +**System capability**: SystemCapability.FileManagement.UserFileManager.DistributedCore + +| Name | Type | Readable| Writable| Description | +| ---------- | -------------------------- | ---- | ---- | ---------------- | +| deviceName | string | Yes | No | Name of the registered device. | +| networkId | string | Yes | No | Network ID of the registered device.| +| isOnline | boolean | Yes | No | Whether the registered device is online. | + + +## FileType + +Enumerates media file types. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +| Name | Value| Description| +| ----- | ---- | ---- | +| IMAGE | 1 | Image.| +| VIDEO | 2 | Video.| +| AUDIO | 3 | Audio.| + +## PrivateAlbumType + +Enumerates the system album types. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +| Name | Value| Description | +| ----- | ---- | ---- | +| TYPE_FAVORITE | 0 | Favorites.| +| TYPE_TRASH | 1 | Recycle bin.| + + + +## AudioKey + +Defines the key information about an audio file. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +| Name | Value | Description | +| ------------- | ------------------- | ---------------------------------------------------------- | +| URI | uri | File URI. | +| DISPLAY_NAME | display_name | File name displayed. | +| DATE_ADDED | date_added | Date when the file was added. The value is the number of seconds elapsed since the Epoch time. | +| DATE_MODIFIED | date_modified | Date when the file was last modified. The value is the number of seconds elapsed since the Epoch time. | +| TITLE | title | Title in the file. | +| ARTIST | artist | Author of the file. | +| AUDIOALBUM | audio_album | Audio album. | +| DURATION | duration | Duration, in ms. | +| FAVORITE | favorite | Whether the file is added to favorites. | + +## ImageVideoKey + +Defines the key information about an image or video file. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +| Name | Value | Description | +| ------------- | ------------------- | ---------------------------------------------------------- | +| URI | uri | File URI. | +| FILE_TYPE | file_type | Type of the file. | +| DISPLAY_NAME | display_name | File name displayed. | +| DATE_ADDED | date_added | Date when the file was added. The value is the number of seconds elapsed since the Epoch time. | +| DATE_MODIFIED | date_modified | Date when the file was last modified. The value is the number of seconds elapsed since the Epoch time. | +| TITLE | title | Title in the file. | +| DURATION | duration | Duration, in ms. | +| WIDTH | width | Image width, in pixels. | +| HEIGHT | height | Image height, in pixels. | +| DATE_TAKEN | date_taken | Date when the file (photo) was taken. The value is the number of seconds elapsed since the Epoch time. | +| ORIENTATION | orientation | Orientation of the image file. | +| FAVORITE | favorite | Whether the file is added to favorites. | + +## AlbumKey + +Defines the key album information. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +| Name | Value | Description | +| ------------- | ------------------- | ---------------------------------------------------------- | +| URI | uri | Album URI. | +| FILE_TYPE | file_type | Type of the file. | +| ALBUM_NAME | album_name | Name of the album. | +| DATE_ADDED | date_added | Date when the file was added. The value is the number of seconds elapsed since the Epoch time. | +| DATE_MODIFIED | date_modified | Date when the file was last modified. The value is the number of seconds elapsed since the Epoch time. | + + +## FetchOptions + +Defines the options for fetching media files. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +| Name | Type | Readable| Writable| Description | +| ---------------------- | ------------------- | ---- |---- | ------------------------------------------------ | +| fetchColumns | Array<string> | Yes | Yes | Columns to fetch. If this parameter is left empty, data is fetched by URI, name, and file type by default. For example,
**fetchColumns: "uri"**.| +| predicates | [dataSharePredicates.DataSharePredicates](js-apis-data-dataSharePredicates.md) | Yes | Yes | Predicates that specify the fetch criteria.| + +## AlbumFetchOptions + +Defines the options for fetching an album. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +| Name | Type | Readable| Writable| Description | +| ---------------------- | ------------------- | ---- |---- | ------------------------------------------------ | +| predicates | [dataSharePredicates.DataSharePredicates](js-apis-data-dataSharePredicates.md) | Yes | Yes | Predicates that specify the fetch criteria.| diff --git a/en/application-dev/reference/apis/js-apis-userfilemanager.md b/en/application-dev/reference/apis/js-apis-userfilemanager.md deleted file mode 100644 index bc02ba6fd6cde0da0b9c81932c60cfe94a3976c0..0000000000000000000000000000000000000000 --- a/en/application-dev/reference/apis/js-apis-userfilemanager.md +++ /dev/null @@ -1,2520 +0,0 @@ -# User Data Management - -> **NOTE**
-> This module is supported since API Version 9. Updates will be marked with a superscript to indicate their earliest API version. - -## Modules to Import - -```js -import userFileManager from '@ohos.filemanagement.userfile_manager'; -``` - -## userFileManager.getUserFileMgr - -getUserFileMgr(context: Context): UserFileManager - -Obtains a **UserFileManager** instance. This instance can be used to access and modify user media data (such as audio and video files, images, and documents). - -**Model restriction**: This API can be used only in the stage model. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| ------- | ------- | ---- | -------------------------- | -| context | [Context](../apis/js-apis-inner-app-context.md) | Yes | Context of the ability instance.| - -**Return value** - -| Type | Description | -| ----------------------------- | :---- | -| [UserFileManager](#userfilemanager) | **UserFileManager** instance obtained.| - -**Example** - -```ts -const context = getContext(this); -let userFileMgr = userfilemanager.getUserFileMgr(context); -``` - -## userFileManager.getUserFileMgr - -getUserFileMgr(): UserFileManager - -Obtains a **UserFileManager** instance.This instance can be used to access and modify user media data (such as audio and video clips, images, and documents). - -**Model restriction**: This API can be used only in the FA model. - -> **NOTE**
You are advised to use [UserFileManager.getUserFileMgr](#userfilemanagergetuserfilemgr), the API used in the stage model. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Return value** - -| Type | Description | -| ----------------------------- | :--------- | -| [UserFileManager](#userfilemanager) | **UserFileManager** instance obtained.| - -**Example** - -```js -let userFileMgr = userfilemanager.getUserFileMgr(); -``` - -## UserFileManager - -### getPublicDirectory - -getPublicDirectory(type: DirectoryType, callback: AsyncCallback<string>): void; - -Obtains the preset public directory. This API uses an asynchronous callback to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | ------------------------ | ---- | ------------------------- | -| type | [DirectoryType](#directorytype) | Yes | Type of the public directory. | -| callback | AsyncCallback<string> | Yes | Callback invoked to return the public directory.| - -**Example** - -```ts -async function getPublicDirectoryDemoCallback() { - console.info('getPublicDirectoryDemo'); - let DIR_CAMERA = directoryType.DIR_CAMERA; - console.info('DIR_CAMERA', DIR_CAMERA); - userFileMgr.getPublicDirectory(DIR_CAMERA, (err, dicResult) => { - if (dicResult == 'Camera/') { - console.info('mediaLibraryTest : getPublicDirectory passed'); - } else { - console.info('mediaLibraryTest : getPublicDirectory failed'); - } - }); -} -``` - -### getPublicDirectory - -getPublicDirectory(type: DirectoryType): Promise<string>; - -Obtains the preset public directory. This API uses a promise to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name| Type | Mandatory| Description | -| ------ | ------------- | ---- | ------------ | -| type | [DirectoryType](#directorytype) | Yes | Type of the public directory.| - -**Return value** - -| Type | Description | -| ---------------- | ---------------- | -| Promise\ | Promise used to return the public directory.| - -**Example** - -```ts -async function getPublicDirectoryDemoPromise() { - console.info('getPublicDirectoryDemo'); - let DIR_CAMERA = directoryType.DIR_CAMERA; - try { - let dicResult = await userFileMgr.getPublicDirectory(DIR_CAMERA); - console.info('mediaLibraryTest : getPublicDirectory passed, result = ', dicResult); - } catch (err) { - console.info('mediaLibraryTest : getPublicDirectory failed, message = ', err); - } -} -``` - -### getFileAssets - -getFileAssets(type: Array<MediaType>, options: MediaFetchOptions, callback: AsyncCallback<FetchFileResult>): void; - -Obtains file assets. This API uses an asynchronous callback to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, or ohos.permission.READ_DOCUMENT - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | ------------------------ | ---- | ------------------------- | -| type | Array<[MediaType](#mediatype)> | Yes | Type of the media data to obtain. | -| options | [MediaFetchOptions](#mediafetchoptions) | Yes | Options for fetching the files. | -| callback | AsyncCallback<string> | Yes | Callback invoked to return the file assets obtained.| - -**Example** - -```ts -async function getFileAssetsDemoCallback() { - console.info('getFileAssets'); - let fileKeyObj = userfile_manager.FileKey - let imageType = userfile_manager.MediaType.IMAGE - let fetchOp = { - selections: '', - selectionArgs: [], - }; - - userFileMgr.getFileAssets([imageType, ], fetchOp, async (err, fetchFileResult) => { - if (fetchFileResult != undefined) { - console.info('fetchFileResult success'); - let fileAsset = await fetchFileResult.getFirstObject(); - if (fileAsset != undefined) { - console.info("fileAsset.displayName :" + fileAsset.displayName); - }; - } - }) -} -``` - -### getFileAssets - -getFileAssets(type: Array<MediaType>, options: MediaFetchOptions): Promise<FetchFileResult>; - -Obtains file assets. This API uses a promise to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, or ohos.permission.READ_DOCUMENT - -**Parameters** - -| Name | Type | Mandatory| Description | -| ------- | ------------------- | ---- | ---------------- | -| type | Array<[MediaType](#mediatype)> | Yes | Type of the media type to obtain.| -| options | [MediaFetchOptions](#mediafetchoptions) | Yes | Options for fetching the files. | - -**Return value** - -| Type | Description | -| --------------------------- | -------------- | -| Promise<[FetchFileResult](#fetchfileresult)> | Promise used to return the file assets obtained.| - -**Example** - -```ts -async function getFileAssetsDemoPromise() { - console.info('getFileAssets'); - let fileKeyObj = userfile_manager.FileKey - let imageType = userfile_manager.MediaType.IMAGE - let fetchOp = { - selections: '', - selectionArgs: [], - }; - try { - var fetchFileResult = await userFileMgr.getFileAssets([imageType, ], fetchOp) - } catch (err) { - console.info('getFileAssets failed, message = ', err); - } - - if (fetchFileResult != undefined) { - console.info('fetchFileResult success'); - let fileAsset = await fetchFileResult.getFirstObject(); - if (fileAsset != undefined) { - console.info("fileAsset.displayName :" + fileAsset.displayName); - }; - } -} -``` - -### on - -on(type: 'deviceChange'|'albumChange'|'imageChange'|'audioChange'|'videoChange'|'fileChange'|'remoteFileChange', callback: Callback<void>): void - -Subscribes to changes of the file management library. This API uses a callback to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | -------------------- | ---- | ------------------------------------------------------------ | -| type | string | Yes | Media type to subscribe to.
**deviceChange** indicates the device change.
**albumChange** indicates the album change.
**imageChange** indicates the image change.
**audioChange** indicates the audio file change.
**videoChange** indicates the video file change.
**fileChange** indicates the file change.
**remoteFileChange** indicates the file change on the registered device.| -| callback | Callback<void> | Yes | Callback that returns no value. | - -**Example** - -```ts -async function onDemo() { - console.info('onDemo') - userFileMgr.on('imageChange', () => { - // Image file changes. Do something. - }); -} -``` - -### off - -off(type: 'deviceChange'|'albumChange'|'imageChange'|'audioChange'|'videoChange'|'fileChange'|'remoteFileChange', callback?: Callback<void>): void - -Unsubscribes from changes of the file management library. This API uses a callback to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | -------------------- | ---- | ------------------------------------------------------------ | -| type | string | Yes | Media type to unsubscribe from.
**deviceChange** indicates the device change.
**albumChange** indicates the album change.
**imageChange** indicates the image change.
**audioChange** indicates the audio file change.
**videoChange** indicates the video file change.
**fileChange** indicates the file change.
**remoteFileChange** indicates the file change on the registered device.| -| callback | Callback<void> | No | Callback that returns no value. | - -**Example** - -```ts -async function offDemo() { - console.info('offDemo') - userFileMgr.off('imageChange', () => { - // stop listening success - }); -} -``` - -### createAsset - -createAsset(mediaType: MediaType, displayName: string, relativePath: string, callback: AsyncCallback<FileAsset>): void - -Creates a file asset. This API uses an asynchronous callback to return the result. - -This is a system API. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO, ohos.permission.WRITE_AUDIO, or ohos.permission.WRITE_DOCUMENT - -**Parameters** - -| Name | Type | Mandatory| Description | -| ------------ | --------------------------- | ---- | ------------------------------------------------------------ | -| mediaType | [MediaType](#mediatype) | Yes | Media type. | -| displayName | string | Yes | File name to display. | -| relativePath | string | Yes | File path. You can use **getPublicDirectory()** to obtain the paths for different types of files.| -| callback | AsyncCallback<[FileAsset](#fileasset)> | Yes | Callback invoked to return the file asset created. | - -**Example** - -```ts -async function createAssetDemoCallback() { - console.info('createAssetDemo') - let mediaType = userfile_manager.MediaType.FILE; - let DIR_DOC = directoryType.DIR_DOCUMENTS; - const path = await userFileMgr.getPublicDirectory(DIR_DOC); - userFileMgr.createAsset(mediaType, 'tesfFile.txt', path + 'myDirectory/', (err, fileAsset) => { - if (err == undefined) { - console.info('createAsset successfully'); - } else { - console.info('createAsset failed, message = ', err); - } - }) -} -``` - -### createAsset - -createAsset(mediaType: MediaType, displayName: string, relativePath: string): Promise<FileAsset>; - -Creates a file asset. This API uses a promise to return the result. - -This is a system API. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO, ohos.permission.WRITE_AUDIO, or ohos.permission.WRITE_DOCUMENT - -**Parameters** - -| Name | Type | Mandatory| Description | -| ------------ | --------- | ---- | ------------------------------------------------------------ | -| mediaType | [MediaType](#mediatype) | Yes | Media type. | -| displayName | string | Yes | File name to display. | -| relativePath | string | Yes | File path. You can use **getPublicDirectory()** to obtain the paths for different types of files.| - -**Return value** - -| Type | Description | -| --------------------- | ----------------- | -| Promise<[FileAsset](#fileasset)> | Promise used to return the file asset created.| - -**Example** - -```ts -async function createAssetDemoPromise() { - console.info('createAssetDemo') - let mediaType = userfile_manager.MediaType.FILE; - let DIR_DOC = directoryType.DIR_DOCUMENTS; - const path = await userFileMgr.getPublicDirectory(DIR_DOC); - try { - let fileAsset = await userFileMgr.createAsset(mediaType, 'tesfFile.txt', path + 'myDirectory/') - console.info('createAsset successfully'); - } catch (err) { - console.info('createAsset failed, message = ', err); - } -} -``` - -### deleteAsset - -deleteAsset(uri: string, callback: AsyncCallback<void>): void; - -Deletes a file asset. This API uses an asynchronous callback to return the result. - -This is a system API. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO, ohos.permission.WRITE_AUDIO, or ohos.permission.WRITE_DOCUMENT - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | --------------------------- | ---- | ---------------------- | -| uri | string | Yes | URI of the file to delete. | -| callback | AsyncCallback<[FileAsset](#fileasset)> | Yes | Callback invoked to return the result.| - -**Example** - -```ts -async function deleteAssetDemoCallback() { - console.info('deleteAssetDemo') - let fileKeyObj = userfile_manager.FileKey - let fileType = userfile_manager.MediaType.FILE - let option = { - selections: '', - selectionArgs: [], - }; - try { - const fetchFileResult = await userFileMgr.getFileAssets([fileType, ], option); - var asset = await fetchFileResult.getFirstObject(); - } catch(err) { - console.info('fetch failed, message =', err) - } - - if (asset == undefined) { - console.error('asset not exist') - return - } - userFileMgr.deleteAsset(asset.uri, (err) => { - if (err == undefined) { - console.info("deleteAsset successfully"); - } else { - console.info("deleteAsset failed with error:"+ err); - } - }); -} -``` - -### deleteAsset - -deleteAsset(uri: string): Promise<void>; - -Deletes a file asset. This API uses a promise to return the result. - -This is a system API. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO, ohos.permission.WRITE_AUDIO, or ohos.permission.WRITE_DOCUMENT - -**Parameters** - -| Name| Type | Mandatory| Description | -| ------ | ------ | ---- | ------- | -| uri | string | Yes | URI of the file to delete.| - -**Return value** - -| Type | Description | -| ---------------- | --------------------------------- | -| Promise<void> | Promise used to return the result.| - -**Example** - -```ts -async function deleteAssetDemoPromise() { - console.info('deleteAssetDemo') - let fileKeyObj = userfile_manager.FileKey - let fileType = userfile_manager.MediaType.FILE - let option = { - selections: '', - selectionArgs: [], - }; - try { - const fetchFileResult = await userFileMgr.getFileAssets([fileType, ], option); - var asset = await fetchFileResult.getFirstObject(); - } catch(err) { - console.info('fetch failed, message =', err) - } - if (asset == undefined) { - console.error('asset not exist') - return - } - try { - await userFileMgr.deleteAsset(asset.uri); - console.info("deleteAsset successfully"); - } catch (err) { - console.info("deleteAsset failed with error:"+ err); - } -} -``` - -### getAlbums - -getAlbums(type: Array<MediaType>, options: MediaFetchOptions, callback: AsyncCallback | Yes | Type of the media data to obtain. | -| options | [MediaFetchOptions](#mediafetchoptions) | Yes | Options for fetching the albums. | -| callback | AsyncCallback<Array<[Album](#album)>> | Yes | Callback invoked to return the album list.| - -**Example** - -```ts -async function getAlbumsDemoCallback() { - console.info('getAlbumsDemo') - let AlbumNoArgsfetchOp = { - selections: '', - selectionArgs: [], - }; - userFileMgr.getAlbums([userfile_manager.MediaType.IMAGE], AlbumNoArgsfetchOp, (err, albumList) => { - if (albumList != undefined) { - const album = albumList[0]; - console.info('first album.albumName = ' + album.albumName); - console.info('album.count = ' + albumList.length); - } else { - console.info('getAlbum fail, message = ' + err); - } - }) -} -``` - -### getAlbums - -getAlbums(type: Array<MediaType>, options: MediaFetchOptions): Promise>; - -Obtains albums. This API uses a promise to return the result. - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, or ohos.permission.READ_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| ------- | ------------------- | ---- | -------------------- | -| type | Array<[MediaType](#mediatype)> | Yes | Type of the media data to obtain.| -| options | [MediaFetchOptions](#mediafetchoptions) | Yes | Options for fetching the albums. | - -**Return value** - -| Type | Description | -| ------------------------ | -------------------------- | -| Promise> | Promise used to return the album list.| - -**Example** - -```ts -async function getAlbumsDemoPromise() { - console.info('getAlbumsDemo') - let AlbumNoArgsfetchOp = { - selections: '', - selectionArgs: [], - }; - try { - let albumList = await userFileMgr.getAlbums([userfile_manager.MediaType.IMAGE], AlbumNoArgsfetchOp); - const album = albumList[0]; - console.info('first album.albumName = ' + album.albumName); - console.info('album.count = ' + albumList.length); - } catch (err) { - console.info('getAlbum fail, message = ' + err); - } -} -``` - -### getPrivateAlbum - -getPrivateAlbum(type: VirtualAlbumType, callback: AsyncCallback): void - -Obtains the system album. This API uses an asynchronous callback to return the result. - -This is a system API. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, or ohos.permission.READ_DOCUMENT - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | ------------------------------------- | ---- | ---------------------------------- | -| type | [VirtualAlbumType](#virtualalbumtype) | Yes | Type of the album to obtain. | -| callback | AsyncCallback> | Yes | Callback invoked to return the system album obtained.| - -**Example** - -```ts -async function getPrivateAlbumDemoCallback() { - console.info('getPrivateAlbumDemo') - userFileMgr.getPrivateAlbum(userfile_manager.VirtualAlbumType.TYPE_TRASH, async (err, albumArray) => { - if (err == undefined) { - console.info('getPrivateAlbum ok'); - try { - let fetchOpt = { - selections: '', - selectionArgs: [], - }; - let trashAlbum = albumArray[0]; - var fetchResult = await trashAlbum.getFileAssets([userfile_manager.MediaType.IMAGE], fetchOpt); - } catch (err) { - console.info('getFileAssets failed. message = ', err); - } - // Get file count in trash album - let count = fetchResult.getCount(); - console.info('fetchResult count = ', count) - // Get fileAssets in trash album - let trashAsset = await fetchResult.getFirstObject(); - // Get file trashed date - let isTrash = trashAsset.isTrash(); - console.info('is trashed', isTrash) - } else { - console.info('getPrivateAlbum failed. message = ', err); - } - }); -} -``` - -### getPrivateAlbum - -getPrivateAlbum(type: VirtualAlbumType): Promise - -Obtains the system album. This API uses a promise to return the result. - -This is a system API. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, or ohos.permission.READ_DOCUMENT - -**Parameters** - -| Name| Type | Mandatory| Description | -| ------ | ---------------- | ---- | ------------ | -| type | [VirtualAlbumType](#virtualalbumtype) | Yes | Type of the album to obtain.| - -**Return value** - -| Type | Description | -| ------------------------------- | --------------------------------- | -| Promise> | Promise used to return the system album obtained.| - -**Example** - -```ts -async function getPrivateAlbumDemoPromise() { - console.info('getPrivateAlbumDemo'); - try { - var albumArray = await userFileMgr.getPrivateAlbum(userfile_manager.VirtualAlbumType.TYPE_TRASH); - } catch(err) { - console.info('getPrivateAlbum failed. message = ', err); - } - try { - let fetchOpt = { - selections: '', - selectionArgs: [], - }; - let trashAlbum = albumArray[0]; - var fetchResult = await trashAlbum.getFileAssets([userfile_manager.MediaType.IMAGE], fetchOpt); - } catch (err) { - console.info('getFileAssets failed. message = ', err); - } - // Get file count in trash album - let count = fetchResult.getCount(); - console.info('fetchResult count = ', count) - // Get fileAssets in trash album - let trashAsset = await fetchResult.getFirstObject(); - - // Get file trashed date - let isTrash = trashAsset.isTrash(); - console.info('is trashed', isTrash) -} -``` - -### getActivePeers - -getActivePeers(callback: AsyncCallback>): void; - -Obtains information about online peer devices. This API uses an asynchronous callback to return the result. - -This is a system API. - -**System capability**: SystemCapability.FileManagement.UserFileManager.DistributedCore - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | --------------------------------- | ---- | ------------ | -| callback | AsyncCallback> | Yes | Callback invoked to return the online device list.| - -**Example** - -```ts -async function getActivePeersDemoCallback() { - console.info('getActivePeersDemo') - var devicesInfo = userFileMgr.getActivePeers((err, devicesInfo) => { - if (err == undefined) { - console.log('getActivePeers succeed.') - for (let i = 0; i < devicesInfo.length; i++) { - console.info('get distributed info ' + devicesInfo[i].deviceName + devicesInfo[i].networkId); - } - } else { - console.info('getActivePeers failed. message = ', err) - } - }); -} -``` - -### getActivePeers - -getActivePeers(): Promise>; - -Obtains information about online peer devices. This API uses a promise to return the result. - -This is a system API. - -**System capability**: SystemCapability.FileManagement.UserFileManager.DistributedCore - -**Return value** - -| Type | Description | -| --------------------------- | ----------------------------- | -| Promise> | Promise used to return the online device list.| - -**Example** - -```ts -async function getActivePeersDemoPromise() { - console.info('getActivePeersDemo') - try { - var devicesInfo = await userFileMgr.getActivePeers(); - } catch (err) { - console.info('getActivePeers failed. message = ', err) - } - if (devicesInfo != undefined) { - console.log('getActivePeers succeed.') - for (let i = 0; i < devicesInfo.length; i++) { - console.info('get distributed info ' + devicesInfo[i].deviceName + devicesInfo[i].networkId); - } - } else { - console.info('get distributed fail') - } -} -``` - -### getAllPeers - -getAllPeers(callback: AsyncCallback>): void; - -Obtains information about all peer devices. This API uses an asynchronous callback to return the result. - -This is a system API. - -**System capability**: SystemCapability.FileManagement.UserFileManager.DistributedCore - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | --------------------------------- | ---- | ------------ | -| callback | AsyncCallback> | Yes | Callback invoked to return the peer device list.| - -**Example** - -```ts -async function getAllPeersDemoCallback() { - console.info('getAllPeersDemo') - var devicesInfo = await userFileMgr.getAllPeers((err, devicesInfo) => { - if (err == undefined) { - console.log('getAllPeers succeed.') - for (let i = 0; i < devicesInfo.length; i++) { - console.info('get distributed info ' + devicesInfo[i].deviceName + devicesInfo[i].networkId); - } - } else { - console.info('getAllPeers failed. message = ', err) - } - }); -} -``` - -### getAllPeers - -getAllPeers(): Promise>; - -Obtains information about all peer devices. This API uses a promise to return the result. - -This is a system API. - -**System capability**: SystemCapability.FileManagement.UserFileManager.DistributedCore - -**Return value** - -| Type | Description | -| --------------------------- | ----------------------------- | -| Promise> | Promise used to return the peer device list.| - -**Example** - -```ts -async function getAllPeersDemoPromise() { - console.info('getAllPeersDemo') - try { - var devicesInfo = await userFileMgr.getAllPeers(); - } catch (err) { - console.info('getAllPeers failed. message = ', err) - } - if (devicesInfo != undefined) { - console.log('getAllPeers succeed.') - for (let i = 0; i < devicesInfo.length; i++) { - console.info('get distributed info ' + devicesInfo[i].deviceName + devicesInfo[i].networkId); - } - } else { - console.info('get distributed fail') - } -} -``` - -### release - -release(callback: AsyncCallback<void>): void - -Releases this **UserFileManager** instance. This API uses an asynchronous callback to return the result. -Call this API when the APIs in the **UserFileManager** instance are no longer used. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | ------------------------- | ---- | -------------------- | -| callback | AsyncCallback<void> | Yes | Callback invoked to return the result.| - -**Example** - -```ts -async function releaseDemoCallback() { - console.info('releaseDemo'); - userFileMgr.release((err) => { - if (err != undefined) { - console.info('release failed. message = ', err); - } else { - console.info('release ok.'); - } - }) -} -``` - -### release - -release(): Promise<void> - -Releases this **UserFileManager** instance. This API uses a promise to return the result. -Call this API when the APIs in the **UserFileManager** instance are no longer used. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Return value** - -| Type | Description | -| ------------------- | --------------------------------- | -| Promise<void> | Promise used to return the result.| - -**Example** - -```ts -async function releaseDemoPromise() { - console.info('releaseDemo'); - try { - await userFileMgr.release(); - console.info('release ok.'); - } catch (err) { - console.info('release failed. message = ', err); - } -} -``` - -## FileAsset - -Provides APIs for encapsulating file asset attributes. - -### Attributes - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -| Name | Type | Readable| Writable| Description | -| ------------------------- | ------------------------ | ---- | ---- | ------------------------------------------------------ | -| uri | string | Yes | No | File asset URI, for example, **dataability:///media/image/2**. | -| mediaType | [MediaType](#mediatype) | Yes | No | Media type. | -| displayName | string | Yes | Yes | File name, including the file name extension, to display. | - - -### isDirectory - -isDirectory(callback: AsyncCallback<boolean>): void - -Checks whether this file asset is a directory. This API uses an asynchronous callback to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| -------- | ---------------------------- | ---- | ------------------- | -| callback | AsyncCallback<boolean> | Yes | Callback invoked to return the result. If the file asset is a directory, **true** will be returned; otherwise, **false** will be returned.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.isDirectory((err, isDirectory) => { - // do something - }); -} -``` - -### isDirectory - -isDirectory():Promise<boolean> - -Checks whether this file asset is a directory. This API uses a promise to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Return value** - -| Type | Description | -| ---------------------- | ---------------------------- | -| Promise<boolean> | Promise used to return the result. If the file asset is a directory, **true** will be returned; otherwise, **false** will be returned.| - -**Example** - -```js -async function example() { - let fileKeyObj = userfile_manager.FileKey - let imageType = userfile_manager.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.isDirectory().then(function(isDirectory){ - console.info("isDirectory result:"+ isDirectory); - }).catch(function(err){ - console.info("isDirectory failed with error:"+ err); - }); -} -``` - -### commitModify - -commitModify(callback: AsyncCallback<void>): void - -Commits the modification on the file metadata to the database. This API uses an asynchronous callback to return the result. - -**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO, ohos.permission.WRITE_AUDIO, or ohos.permission.WRITE_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| -------- | ------------------------- | ---- | ----- | -| callback | AsyncCallback<void> | Yes | Callback that returns no value.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.title = 'newtitle'; - asset.commitModify(() => { - console.info('commitModify success'); - }); -} -``` - -### commitModify - -commitModify(): Promise<void> - -Commits the modification on the file metadata to the database. This API uses a promise to return the result. - -**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO, ohos.permission.WRITE_AUDIO, or ohos.permission.WRITE_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Return value** - -| Type | Description | -| ------------------- | ---------- | -| Promise<void> | Promise that returns no value.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.title = 'newtitle'; - asset.commitModify(); -} -``` - -### open - -open(mode: string, callback: AsyncCallback<number>): void - -Opens this file asset. This API uses an asynchronous callback to return the result. - -**NOTE**
Currently, the write operations are mutually exclusive. After a write operation is complete, you must call **close** to release the resource. - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, ohos.permission.READ_DOCUMENT, ohos.permission.WRITE_MEDIA, ohos.permission.WRITE_IMAGEVIDEO, ohos.permission.WRITE_AUDIO, or ohos.permission.WRITE_DOCUMENT - - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| -------- | --------------------------- | ---- | ----------------------------------- | -| mode | string | Yes | File open mode, which can be **r** (read-only), **w** (write-only), or **rw** (read-write).| -| callback | AsyncCallback<number> | Yes | Callback used to return the file handle. | - -**Example** - -```js -async function example() { - let mediaType = mediaLibrary.MediaType.IMAGE; - let DIR_IMAGE = mediaLibrary.DirectoryType.DIR_IMAGE; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const path = await userFileMgr.getPublicDirectory(DIR_IMAGE); - const asset = await userFileMgr.createAsset(mediaType, "image00003.jpg", path); - asset.open('rw', (openError, fd) => { - if(fd > 0){ - asset.close(fd); - }else{ - console.info('File Open Failed!' + openError); - } - }); -} -``` - -### open - -open(mode: string): Promise<number> - -Opens this file asset. This API uses a promise to return the result. - -**NOTE**
Currently, the write operations are mutually exclusive. After a write operation is complete, you must call **close** to release the resource. - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, ohos.permission.READ_DOCUMENT, ohos.permission.WRITE_MEDIA, ohos.permission.WRITE_IMAGEVIDEO, ohos.permission.WRITE_AUDIO, or ohos.permission.WRITE_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| ---- | ------ | ---- | ----------------------------------- | -| mode | string | Yes | File open mode, which can be **r** (read-only), **w** (write-only), or **rw** (read-write).| - -**Return value** - -| Type | Description | -| --------------------- | ------------- | -| Promise<number> | Promise used to return the file handle.| - -**Example** - -```js -async function example() { - let mediaType = mediaLibrary.MediaType.IMAGE; - let DIR_IMAGE = mediaLibrary.DirectoryType.DIR_IMAGE; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const path = await userFileMgr.getPublicDirectory(DIR_IMAGE); - const asset = await userFileMgr.createAsset(mediaType, "image00003.jpg", path); - asset.open('rw') - .then((fd) => { - console.info('File fd!' + fd); - }) - .catch((err) => { - console.info('File err!' + err); - }); -} -``` - -### close - -close(fd: number, callback: AsyncCallback<void>): void - -Closes this file asset. This API uses an asynchronous callback to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| -------- | ------------------------- | ---- | ----- | -| fd | number | Yes | File descriptor.| -| callback | AsyncCallback<void> | Yes | Callback that returns no value.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.open('rw').then((fd) => { - console.info('File fd!' + fd); - asset.close(fd, (closeErr) => { - if (closeErr != undefined) { - console.info('mediaLibraryTest : close : FAIL ' + closeErr); - console.info('mediaLibraryTest : ASSET_CALLBACK : FAIL'); - } else { - console.info("=======asset.close success====>"); - } - }); - }) - .catch((err) => { - console.info('File err!' + err); - }); -} -``` - -### close - -close(fd: number): Promise<void> - -Closes this file asset. This API uses a promise to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| ---- | ------ | ---- | ----- | -| fd | number | Yes | File descriptor.| - -**Return value** - -| Type | Description | -| ------------------- | ---------- | -| Promise<void> | Promise that returns no value.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.open('rw').then((fd) => { - console.info('File fd!' + fd); - asset.close(fd).then((closeErr) => { - if (closeErr != undefined) { - console.info('mediaLibraryTest : close : FAIL ' + closeErr); - console.info('mediaLibraryTest : ASSET_CALLBACK : FAIL'); - - } else { - console.info("=======asset.close success====>"); - } - }); - }) - .catch((err) => { - console.info('File err!' + err); - }); -} -``` - -### getThumbnail - -getThumbnail(callback: AsyncCallback<image.PixelMap>): void - -Obtains the thumbnail of this file asset. This API uses an asynchronous callback to return the result. - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, or ohos.permission.READ_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| -------- | ----------------------------------- | ---- | ---------------- | -| callback | AsyncCallback<[image.PixelMap](../apis/js-apis-image.md#pixelmap7)> | Yes | Callback invoked to return the pixel map of the thumbnail.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.getThumbnail((err, pixelmap) => { - console.info('mediaLibraryTest : getThumbnail Successfull '+ pixelmap); - }); -} -``` - -### getThumbnail - -getThumbnail(size: Size, callback: AsyncCallback<image.PixelMap>): void - -Obtains the file thumbnail of the given size. This API uses an asynchronous callback to return the result. - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, or ohos.permission.READ_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| -------- | ----------------------------------- | ---- | ---------------- | -| size | [Size](#size) | Yes | Size of the thumbnail to obtain. | -| callback | AsyncCallback<[image.PixelMap](../apis/js-apis-image.md#pixelmap7)> | Yes | Callback invoked to return the pixel map of the thumbnail.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let size = { width: 720, height: 720 }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.getThumbnail(size, (err, pixelmap) => { - console.info('mediaLibraryTest : getThumbnail Successfull '+ pixelmap); - }); -} -``` - -### getThumbnail - -getThumbnail(size?: Size): Promise<image.PixelMap> - -Obtains the file thumbnail of the given size. This API uses a promise to return the result. - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, or ohos.permission.READ_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| ---- | -------------- | ---- | ----- | -| size | [Size](#size) | No | Size of the thumbnail to obtain.| - -**Return value** - -| Type | Description | -| ----------------------------- | --------------------- | -| Promise<[image.PixelMap](../apis/js-apis-image.md#pixelmap7)> | Promise used to return the pixel map of the thumbnail.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let size = { width: 720, height: 720 }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.getThumbnail(size) - .then((pixelmap) => { - console.info('mediaLibraryTest : getThumbnail Successfull '+ pixelmap); - }) - .catch((err) => { - console.info('mediaLibraryTest : getThumbnail fail'+ err); - }); -} -``` - -### favorite - -favorite(isFavorite: boolean, callback: AsyncCallback<void>): void - -Favorites or unfavorites this file asset. This API uses an asynchronous callback to return the result. - -**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO, ohos.permission.WRITE_AUDIO, or ohos.permission.WRITE_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| ---------- | ------------------------- | ---- | ---------------------------------- | -| isFavorite | boolean | Yes | Operation to perform. The value **true** means to favorite the file asset, and **false** means the opposite.| -| callback | AsyncCallback<void> | Yes | Callback that returns no value. | - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.favorite(true,function(err){ - // Do something. - }); -} -``` - -### favorite - -favorite(isFavorite: boolean): Promise<void> - -Favorites or unfavorites this file asset. This API uses a promise to return the result. - -**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO, ohos.permission.WRITE_AUDIO, or ohos.permission.WRITE_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| ---------- | ------- | ---- | ---------------------------------- | -| isFavorite | boolean | Yes | Operation to perform. The value **true** means to favorite the file asset, and **false** means the opposite.| - -**Return value** - -| Type | Description | -| ------------------- | ---------- | -| Promise<void> | Promise that returns no value.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.favorite(true).then(function() { - console.info("favorite successfully"); - }).catch(function(err){ - console.info("favorite failed with error:"+ err); - }); -} -``` - -### isFavorite - -isFavorite(callback: AsyncCallback<boolean>): void - -Checks whether this file asset is favorited. This API uses an asynchronous callback to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| -------- | ---------------------------- | ---- | ----------- | -| callback | AsyncCallback<boolean> | Yes | Callback invoked to return the result. If the file asset is favorited, **true** will be returned; otherwise, **false** will be returned.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.isFavorite((err, isFavorite) => { - if (isFavorite) { - console.info('FileAsset is favorite'); - }else{ - console.info('FileAsset is not favorite'); - } - }); -} -``` - -### isFavorite - -isFavorite():Promise<boolean> - -Checks whether this file asset is favorited. This API uses a promise to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Return value** - -| Type | Description | -| ---------------------- | ------------------ | -| Promise<boolean> | Promise used to return the result. If the file asset is favorited, **true** will be returned; otherwise, **false** will be returned.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.isFavorite().then(function(isFavorite){ - console.info("isFavorite result:"+ isFavorite); - }).catch(function(err){ - console.info("isFavorite failed with error:"+ err); - }); -} -``` - -### trash - -trash(isTrash: boolean, callback: AsyncCallback<void>): void - -Moves this file asset to the trash. This API uses an asynchronous callback to return the result. - -Files in the trash are not actually deleted. You can set **isTrash** to **false** to restore the files from the trash. - -**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO, ohos.permission.WRITE_AUDIO, or ohos.permission.WRITE_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| -------- | ------------------------- | ---- | --------- | -| isTrash | boolean | Yes | Whether to move the file asset to the trash. The value **true** means to move the file asset to the trash, and **false** means the opposite.| -| callback | AsyncCallback<void> | Yes | Callback that returns no value. | - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.trash(true, trashCallBack); - function trashCallBack(err, trash) { - console.info('mediaLibraryTest : ASSET_CALLBACK ASSET_CALLBACK trash'); - } -} -``` - -### trash - -trash(isTrash: boolean): Promise<void> - -Moves this file asset to the trash. This API uses a promise to return the result. - -Files in the trash are not actually deleted. You can set **isTrash** to **false** to restore the files from the trash. - -**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO, ohos.permission.WRITE_AUDIO, or ohos.permission.WRITE_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| ------- | ------- | ---- | --------- | -| isTrash | boolean | Yes | Whether to move the file asset to the trash. The value **true** means to move the file asset to the trash, and **false** means the opposite.| - -**Return value** - -| Type | Description | -| ------------------- | ---------- | -| Promise<void> | Promise that returns no value.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.trash(true).then(function() { - console.info("trash successfully"); - }).catch(function(err){ - console.info("trash failed with error:"+ err); - }); -} -``` - -### isTrash - -isTrash(callback: AsyncCallback<boolean>): void - -Checks whether this file asset is in the trash. This API uses an asynchronous callback to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| -------- | ---------------------------- | ---- | --------------- | -| callback | AsyncCallback<boolean> | Yes | Callback invoked to return the result. If the file asset is in the trash, **true** will be returned; otherwise, **false** will be returned.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.isTrash((err, isTrash) => { - if (isTrash == undefined) { - console.error('Failed to get trash state: ' + err); - return; - } - console.info('Get trash state success: ' + isTrash); - }); -} -``` - -### isTrash - -isTrash():Promise<boolean> - -Checks whether this file asset is in the trash. This API uses a promise to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Return value** - -| Type | Description | -| ------------------- | -------------------- | -| Promise<void> | Promise used to return the result. If the file asset is in the trash, **true** will be returned; otherwise, **false** will be returned.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - const fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const asset = await fetchFileResult.getFirstObject(); - asset.isTrash().then(function(isTrash){ - console.info("isTrash result: " + isTrash); - }).catch(function(err){ - console.error("isTrash failed with error: " + err); - }); -} -``` - -## FetchFileResult - -Provides APIs to manage the file retrieval result. - -### getCount - -getCount(): number - -Obtains the total number of files in the result set. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Return value** - -| Type | Description | -| ------ | -------- | -| number | Total number of files.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let fileType = mediaLibrary.MediaType.FILE; - let getFileCountOneOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [fileType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - let fetchFileResult = await userFileMgr.getFileAssets(getFileCountOneOp); - const fetchCount = fetchFileResult.getCount(); -} -``` - -### isAfterLast - -isAfterLast(): boolean - -Checks whether the cursor is in the last row of the result set. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Return value** - -| Type | Description | -| ------- | ---------------------------------- | -| boolean | Returns **true** if the cursor is in the last row of the result set; returns **false** otherwise.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - let fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const fetchCount = fetchFileResult.getCount(); - console.info('mediaLibraryTest : count:' + fetchCount); - let fileAsset = await fetchFileResult.getFirstObject(); - for (var i = 1; i < fetchCount; i++) { - fileAsset = await fetchFileResult.getNextObject(); - if(i == fetchCount - 1) { - console.info('mediaLibraryTest : isLast'); - var result = fetchFileResult.isAfterLast(); - console.info('mediaLibraryTest : isAfterLast:' + result); - console.info('mediaLibraryTest : isAfterLast end'); - fetchFileResult.close(); - } - } -} -``` - -### close - -close(): void - -Releases and invalidates this **FetchFileResult** instance. After this instance is released, the APIs in this instance cannot be invoked. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - let fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - fetchFileResult.close(); -} -``` - -### getFirstObject - -getFirstObject(callback: AsyncCallback<FileAsset>): void - -Obtains the first file asset in the result set. This API uses an asynchronous callback to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | --------------------------------------------- | ---- | ------------------------------------------- | -| callback | AsyncCallback<[FileAsset](#fileasset)> | Yes | Callback invoked to return the first file asset.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - let fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - fetchFileResult.getFirstObject((err, fileAsset) => { - if (err) { - console.error('Failed '); - return; - } - console.log('fileAsset.displayName : ' + fileAsset.displayName); - }) -} -``` - -### getFirstObject - -getFirstObject(): Promise<FileAsset> - -Obtains the first file asset in the result set. This API uses a promise to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Return value** - -| Type | Description | -| --------------------------------------- | -------------------------- | -| Promise<[FileAsset](#fileasset)> | Promise used to return the first file asset.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - let fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - fetchFileResult.getFirstObject().then(function(fileAsset){ - console.info("getFirstObject successfully:"+ JSON.stringify(fileAsset)); - }).catch(function(err){ - console.info("getFirstObject failed with error:"+ err); - }); -} -``` - -### getNextObject - - getNextObject(callback: AsyncCallback<FileAsset>): void - -Obtains the next file asset in the result set. This API uses an asynchronous callback to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| --------- | --------------------------------------------- | ---- | ----------------------------------------- | -| callbacke | AsyncCallback<[FileAsset](#fileasset)> | Yes | Callback invoked to return the next file asset.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - let fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - fetchFileResult.getNextObject((err, fileAsset) => { - if (err) { - console.error('Failed '); - return; - } - console.log('fileAsset.displayName : ' + fileAsset.displayName); - }) -} -``` - -### getNextObject - - getNextObject(): Promise<FileAsset> - -Obtains the next file asset in the result set. This API uses a promise to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Return value** - -| Type | Description | -| --------------------------------------- | ----------------- | -| Promise<[FileAsset](#fileasset)> | Promise used to return the next file asset.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - let fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - const fetchCount = fetchFileResult.getCount(); - console.info('mediaLibraryTest : count:' + fetchCount); - let fileAsset = await fetchFileResult.getNextObject(); -} -``` - -### getLastObject - -getLastObject(callback: AsyncCallback<FileAsset>): void - -Obtains the last file asset in the result set. This API uses an asynchronous callback to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | --------------------------------------------- | ---- | --------------------------- | -| callback | AsyncCallback<[FileAsset](#fileasset)> | Yes | Callback invoked to return the last file asset.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - let fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - fetchFileResult.getLastObject((err, fileAsset) => { - if (err) { - console.error('Failed '); - return; - } - console.log('fileAsset.displayName : ' + fileAsset.displayName); - }) -} -``` - -### getLastObject - -getLastObject(): Promise<FileAsset> - -Obtains the last file asset in the result set. This API uses a promise to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Return value** - -| Type | Description | -| --------------------------------------- | ----------------- | -| Promise<[FileAsset](#fileasset)> | Promise used to return the last file asset.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - let fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - let lastObject = await fetchFileResult.getLastObject(); -} -``` - -### getPositionObject - -getPositionObject(index: number, callback: AsyncCallback<FileAsset>): void - -Obtains a file asset with the specified index in the result set. This API uses an asynchronous callback to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| -------- | ---------------------------------------- | ---- | ------------------ | -| index | number | Yes | Index of the file asset to obtain. The value starts from **0**. | -| callback | AsyncCallback<[FileAsset](#fileasset)> | Yes | Callback invoked to return the file asset obtained.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - let fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - fetchFileResult.getPositionObject(0, (err, fileAsset) => { - if (err) { - console.error('Failed '); - return; - } - console.log('fileAsset.displayName : ' + fileAsset.displayName); - }) -} -``` - -### getPositionObject - -getPositionObject(index: number): Promise<FileAsset> - -Obtains a file asset with the specified index in the result set. This API uses a promise to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory | Description | -| ----- | ------ | ---- | -------------- | -| index | number | Yes | Index of the file asset to obtain. The value starts from **0**.| - -**Return value** - -| Type | Description | -| --------------------------------------- | ----------------- | -| Promise<[FileAsset](#fileasset)> | Promise used to return the file asset obtained.| - -**Example** - -```js -async function example() { - let fileKeyObj = mediaLibrary.FileKey; - let imageType = mediaLibrary.MediaType.IMAGE; - let getImageOp = { - selections: fileKeyObj.MEDIA_TYPE + '= ?', - selectionArgs: [imageType.toString()], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let userFileMgr = userfile_manager.getUserFileMgr(context); - let fetchFileResult = await userFileMgr.getFileAssets(getImageOp); - fetchFileResult.getPositionObject(1) .then(function (fileAsset){ - console.log('fileAsset.displayName : ' + fileAsset.displayName); - }).catch(function (err) { - console.info("getFileAssets failed with error:" + err); - }); -} -``` - -## Album - -Provides APIs to manage albums. - -### Attributes - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -| Name | Type | Readable | Writable | Description | -| ------------ | ------ | ---- | ---- | ------- | -| albumName | string | Yes | Yes | Album name. | -| albumUri | string | Yes | No | Album URI. | -| dateModified | number | Yes | No | Date when the album was last modified. | -| count | number | Yes | No | Number of files in the album.| -| relativePath | string | Yes | No | Relative path of the album. | -| coverUri | string | Yes | No | URI of the cover file of the album. - -### commitModify - -commitModify(callback: AsyncCallback<void>): void; - -Commits the modification on the album attributes to the database. This API uses an asynchronous callback to return the result. - -**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO, ohos.permission.WRITE_AUDIO, or ohos.permission.WRITE_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | ------------------------- | ---- | ---------- | -| callback | AsyncCallback<void> | Yes | Callback that returns no value.| - -**Example** - -```ts -async function commitModifyDemoCallback() { - console.info('commitModifyDemo') - let fileKeyObj = userfile_manager.FileKey - let imageType = userfile_manager.MediaType.IMAGE; - let getImageOp = { - selections: '', - selectionArgs: [], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let fetchFileResult = await userFileMgr.getFileAssets([imageType], getImageOp); - let asset = await fetchFileResult.getFirstObject(); - console.info('old displayName:', asset.displayName) - asset.displayName = 'newDisplayName'; - console.info('new displayName:', asset.displayName) - asset.commitModify((err) => { - if (err == undefined) { - console.info('commitModify succeed.') - } else { - console.info('commitModify failed, message =', err); - } - }); -} -``` - -### commitModify - -commitModify(): Promise<void>; - -Commits the modification on the album attributes to the database. This API uses a promise to return the result. - -**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO, ohos.permission.WRITE_AUDIO, or ohos.permission.WRITE_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Return value** - -| Type | Description | -| ------------------- | ------------ | -| Promise<void> | Promise that returns no value.| - -**Example** - -```ts -async function commitModifyDemoPromise() { - console.info('commitModifyDemo') - let fileKeyObj = userfile_manager.FileKey - let imageType = userfile_manager.MediaType.IMAGE; - let getImageOp = { - selections: '', - selectionArgs: [], - order: fileKeyObj.DATE_ADDED + " DESC", - extendArgs: "", - }; - let fetchFileResult = await userFileMgr.getFileAssets([imageType], getImageOp); - let asset = await fetchFileResult.getFirstObject(); - console.info('old displayName:', asset.displayName) - asset.displayName = 'newDisplayName'; - console.info('new displayName:', asset.displayName) - try { - await asset.commitModify(); - console.info('commitModify succeed.') - } catch (err) { - console.info('commitModify failed, message =', err); - } -} -``` - -### getFileAssets - -getFileAssets(type: Array<MediaType>, callback: AsyncCallback<FetchFileResult>): void; - -Obtains the file assets in this album. This API uses an asynchronous callback to return the result. - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, or ohos.permission.READ_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | --------------------------------------------------- | ---- | ----------------------------------- | -| type | Array<[MediaType](#mediatype)> | Yes | Type of the media data to obtain. | -| callback | AsyncCallback<[FetchFileResult](#fetchfileresult)> | Yes | Callback invoked to return the file assets obtained.| - -**Example** - -```ts -async function albumGetFileAssetsDemoCallback() { - console.info('albumGetFileAssetsDemoCallback2') - let imageType = userfile_manager.MediaType.IMAGE; - let AlbumNoArgsfetchOp = { - selections: '', - selectionArgs: [], - }; - const albumList = await userFileMgr.getAlbums([imageType], AlbumNoArgsfetchOp); - const album = albumList[0]; - album.getFileAssets([imageType], (err, albumFetchFileResult) => { - if (err == undefined) { - console.info("getFileAssets successfully:"+ JSON.stringify(albumFetchFileResult)); - } else { - console.info("getFileAssets failed with error:"+ err); - } - }); -} -``` - -### getFileAssets - -getFileAssets(type: Array<MediaType>, options: MediaFetchOptions, callback: AsyncCallback<FetchFileResult>): void; - -Obtains the file assets in this album. This API uses an asynchronous callback to return the result. - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, or ohos.permission.READ_DOCUMENT - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | --------------------------------------------------- | ---- | ----------------------------------- | -| type | Array<[MediaType](#mediatype)> | Yes | Type of the media data to obtain. | -| options | [MediaFetchOptions](#mediafetchoptions) | Yes | Options for fetching the media data. | -| callback | AsyncCallback<[FetchFileResult](#fetchfileresult)> | Yes | Callback invoked to return the file assets obtained.| - -**Example** - -```ts -async function albumGetFileAssetsDemoCallback() { - console.info('albumGetFileAssetsDemoCallback') - let imageType = userfile_manager.MediaType.IMAGE; - let AlbumNoArgsfetchOp = { - selections: '', - selectionArgs: [], - }; - let fileNoArgsfetchOp = { - selections: '', - selectionArgs: [], - } - const albumList = await userFileMgr.getAlbums([imageType], AlbumNoArgsfetchOp); - const album = albumList[0]; - album.getFileAssets([imageType], fileNoArgsfetchOp, (err, albumFetchFileResult) => { - if (err == undefined) { - console.info("getFileAssets successfully:"+ JSON.stringify(albumFetchFileResult)); - } else { - console.info("getFileAssets failed with error:"+ err); - } - }); - } -``` - -### getFileAssets - -getFileAssets(type: Array<MediaType>, options?: MediaFetchOptions): Promise<FetchFileResult>; - -Obtains the file assets in this album. This API uses a promise to return the result. - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, or ohos.permission.READ_DOCUMENT - - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| ------- | ---------------------------------------- | ---- | -------------- | -| type | Array<[MediaType](#mediatype)> | Yes | Type of the media data to obtain. | -|options | [MediaFetchOptions](#mediafetchoptions) | No | Options for fetching the media data.| - -**Return value** - -| Type | Description | -| --------------------------------------------- | ------------------------- | -| Promise<[FetchFileResult](#fetchfileresult)> | Promise used to return the file assets obtained.| - -**Example** - -```ts -async function albumGetFileAssetsDemoPromise() { - console.info('albumGetFileAssetsDemoPromise') - let imageType = userfile_manager.MediaType.IMAGE; - let AlbumNoArgsfetchOp = { - selections: '', - selectionArgs: [], - }; - let fileNoArgsfetchOp = { - selections: '', - selectionArgs: [], - } - const albumList = await userFileMgr.getAlbums([imageType], AlbumNoArgsfetchOp); - const album = albumList[0]; - album.getFileAssets([imageType], fileNoArgsfetchOp).then(function(albumFetchFileResult){ - console.info("getFileAssets successfully:"+ JSON.stringify(albumFetchFileResult)); - }).catch(function(err){ - console.info("getFileAssets failed with error:"+ err); - }); -} -``` -## VirtualAlbum -Provides APIs for managing a virtual album. - -### getFileAssets - -getFileAssets(type: Array<MediaType>, options: MediaFetchOptions, callback: AsyncCallback<FetchFileResult>): void; - -Obtains file assets in the virtual album. This API uses an asynchronous callback to return the result. - -This is a system API. - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, or ohos.permission.READ_DOCUMENT - -> **NOTE**
-> The ability privilege level (APL) of the permissions required by this API is **system_basic**. Applications of the **normal** APL need to apply for these permissions through the Access Control List (ACL). For details, see [ACL](../../security/accesstoken-overview.md#acl). -> -> You are advised to use the **options** parameter to explicitly specify the type of the file access. If the file type cannot be determined, the file asset result set is returned based on the permissions of the application. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** -| Name | Type | Mandatory| Description | -| -------- | --------------------------------------------------- | ---- | ----------------------------------- | -| type | Array<[MediaType](#mediatype)> | Yes | Type of the media data to obtain. | -| options | [MediaFetchOptions](#mediafetchoptions) | Yes | Options for fetching the files. | -| callback | AsyncCallback<[FetchFileResult](#fetchfileresult)> | Yes | Callback invoked to return the file assets obtained.| - -**Example** - -```ts -async function virtualAlbumGetFileAssetsDemoCallback() { - console.info('virtualAlbumGetFileAssetsDemoCallback') - try { - var albumArray = await userFileMgr.getPrivateAlbum(userfile_manager.VirtualAlbumType.TYPE_TRASH); - } catch (err) { - console.info('getPrivateAlbum failed, message = ', err); - } - let fetchOpt = { - selections: '', - selectionArgs: [], - }; - let trashAlbum = albumArray[0]; - - trashAlbum.getFileAssets([userfile_manager.MediaType.IMAGE], fetchOpt, (err, fetchResult) => { - if (err == undefined) { - let count = fetchResult.getCount(); - console.info('fetchResult.count = ', count); - } else { - console.info('getFileAssets failed, message = ', err); - } - }); -} -``` - -### getFileAssets -getFileAssets(type: Array<MediaType>, options: MediaFetchOptions): Promise<FetchFileResult>; - -Obtains file assets in the virtual album. This API uses a promise to return the result. - -This is a system API. - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.READ_AUDIO, or ohos.permission.READ_DOCUMENT - -> **NOTE**
-> The APL of the permissions required by this API is **system_basic**. Applications of the **normal** APL need to apply for these permissions through the ACL. For details, see [ACL](../../security/accesstoken-overview.md#acl). -> -> You are advised to use the **options** parameter to explicitly specify the type of the file access. If the file type cannot be determined, the file asset result set is returned based on the permissions of the application. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| ------- | ---------------------------------------- | ---- | -------------- | -| type | Array<[MediaType](#mediatype)> | Yes | Type of the media data to obtain. | -|options | [MediaFetchOptions](#mediafetchoptions) | No | Options for fetching the files.| - -**Return value** - -| Type | Description | -| --------------------------------------------- | ------------------------- | -| Promise<[FetchFileResult](#fetchfileresult)> | Promise used to return the file assets obtained.| - -**Example** - -```ts -async function virtualAlbumGetFileAssetsDemoPromise() { - console.info('virtualAlbumGetFileAssetsDemoPromise') - let albumArray = await userFileMgr.getPrivateAlbum(userfile_manager.VirtualAlbumType.TYPE_TRASH); - let fetchOpt = { - selections: '', - selectionArgs: [], - }; - let trashAlbum = albumArray[0]; - - let fetchResult = await trashAlbum.getFileAssets([userfile_manager.MediaType.IMAGE], fetchOpt); - let count = fetchResult.getCount(); - console.info('fetchResult.count = ', count); -} -``` - -## PeerInfo - -Describes information about a registered device. -This is a system API. - -**System capability**: SystemCapability.FileManagement.UserFileManager.DistributedCore - -| Name | Type | Readable| Writable| Description | -| ---------- | -------------------------- | ---- | ---- | ---------------- | -| deviceName | string | Yes | No | Name of the registered device. | -| networkId | string | Yes | No | Network ID of the registered device.| -| isOnline | boolean | Yes | No | Whether the registered device is online. | - -## MediaType - -Enumerates the media types. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -| Name | Description| -| ----- | ---- | -| FILE | File.| -| IMAGE | Image.| -| VIDEO | Video.| -| AUDIO | Audio.| - -## FileKey - -Defines the key file information. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -| Name | Default Value | Description | -| ------------- | ------------------- | ---------------------------------------------------------- | -| URI | uri | File URI. | -| RELATIVE_PATH | relative_path | Relative public directory of the file. | -| DISPLAY_NAME | display_name | File name displayed. | -| DATE_ADDED | date_added | Date when the file was added. The value is the number of seconds elapsed since the Epoch time. | -| DATE_MODIFIED | date_modified | Date when the file was last modified. The value is the number of seconds elapsed since the Epoch time. | -| TITLE | title | Title in the file. | - -## AudioKey - -Defines the key information about an audio file. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -| Name | Default Value | Description | -| ------------- | ------------------- | ---------------------------------------------------------- | -| URI | uri | Promise used to return the URI of the file created. | -| RELATIVE_PATH | relative_path | Relative public directory of the file. | -| DISPLAY_NAME | display_name | File name displayed. | -| DATE_ADDED | date_added | Date when the file was added. The value is the number of seconds elapsed since the Epoch time. | -| DATE_MODIFIED | date_modified | Date when the file was last modified. The value is the number of seconds elapsed since the Epoch time. | -| TITLE | title | Title in the file. | -| ARTIST | artist | Author of the file. | -| AUDIOALBUM | audio_album | Audio album. | -| DURATION | duration | Duration, in ms. | - -## ImageVideoKey - -Defines the key information about an image or video file. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -| Name | Default Value | Description | -| ------------- | ------------------- | ---------------------------------------------------------- | -| URI | uri | File URI. | -| RELATIVE_PATH | relative_path | Relative public directory of the file. | -| DISPLAY_NAME | display_name | File name displayed. | -| DATE_ADDED | date_added | Date when the file was added. The value is the number of seconds elapsed since the Epoch time. | -| DATE_MODIFIED | date_modified | Date when the file was last modified. The value is the number of seconds elapsed since the Epoch time. | -| DURATION | duration | Duration, in ms. | -| WIDTH | width | Image width, in pixels. | -| HEIGHT | height | Image height, in pixels. | -| DATE_TAKEN | date_taken | Date when the file (photo) was taken. The value is the number of seconds elapsed since the Epoch time. | - -## AlbumKey - -Defines the key album information. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -| Name | Default Value | Description | -| ------------- | ------------------- | ---------------------------------------------------------- | -| URI | uri | Album URI. | -| RELATIVE_PATH | relative_path | Relative public directory of the album. | -| DISPLAY_NAME | display_name | Album name displayed. | -| DATE_ADDED | date_added | Date when the album was added. The value is the number of seconds elapsed since the Epoch time. | -| DATE_MODIFIED | date_modified | Date when the album was last modified. The value is the number of seconds elapsed since the Epoch time. | - -## DirectoryType - -Enumerates directory types. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -| Name | Description | -| ------------- | ------------------ | -| DIR_CAMERA | Directory of camera files.| -| DIR_VIDEO | Directory of video files. | -| DIR_IMAGE | Directory of image files. | -| DIR_AUDIO | Directory of audio files. | -| DIR_DOCUMENTS | Directory of documents. | -| DIR_DOWNLOAD | Download directory. | - -## MediaFetchOptions - -Defines the options for fetching media files. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -| Name | Type | Readable| Writable| Mandatory| Description | -| ----------------------- | ------------------- | ---- | ---- | ---- | ------------------------------------------------------------ | -| selections | string | Yes | Yes | Yes | Conditions for fetching files. The values in [FileKey](#filekey) are used as the column names of the conditions. Example:
selections: mediaLibrary.FileKey.MEDIA_TYPE + '= ? OR' +mediaLibrary.FileKey.MEDIA_TYPE + '= ?',| -| selectionArgs | Array<string> | Yes | Yes | Yes | Values of the conditions specified in **selections**.
Example:
selectionArgs: [mediaLibrary.MediaType.IMAGE.toString(), mediaLibrary.MediaType.VIDEO.toString()], | - -## Size - -Defines the image size. -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -| Name | Type | Readable | Writable | Description | -| ------ | ------ | ---- | ---- | -------- | -| width | number | Yes | Yes | Image width, in pixels.| -| height | number | Yes | Yes | Image height, in pixels.| - -## VirtualAlbumType -Enumerates the system or virtual album types. - -This is a system API. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -| Name | Description | -| ------------- | ------------------ | -| TYPE_FAVORITE | Favorites album.
This is a system API.| -| TYPE_TRASH | Trash album.
This is a system API.| diff --git a/en/application-dev/reference/arkui-js/Readme-EN.md b/en/application-dev/reference/arkui-js/Readme-EN.md index d14e06d8a3a83329a2a6e2b508508e03c93aea4c..c46abd3bd91d1acbf99bb15152d3f55f636483eb 100644 --- a/en/application-dev/reference/arkui-js/Readme-EN.md +++ b/en/application-dev/reference/arkui-js/Readme-EN.md @@ -96,10 +96,9 @@ - Custom Components - [Basic Usage](js-components-custom-basic-usage.md) - - [Style Inheritance](js-components-custom-style.md) - - [Custom Events](js-components-custom-events.md) - [props](js-components-custom-props.md) - - [Event Parameter](js-components-custom-event-parameter.md) + - [Style Inheritance](js-components-custom-style.md) - [slot](js-components-custom-slot.md) - [Lifecycle Definition](js-components-custom-lifecycle.md) -- [Data Type Attributes](js-appendix-types.md) +- [Dynamic Component Creation](js-components-create-elements.md) +- [Data Type Attributes](js-appendix-types.md) diff --git a/en/application-dev/reference/arkui-js/figures/animate-4.gif b/en/application-dev/reference/arkui-js/figures/en-us_image_0000001127125126.gif similarity index 100% rename from en/application-dev/reference/arkui-js/figures/animate-4.gif rename to en/application-dev/reference/arkui-js/figures/en-us_image_0000001127125126.gif diff --git a/en/application-dev/reference/arkui-js/en-us_image_0000001127284938.gif b/en/application-dev/reference/arkui-js/figures/en-us_image_0000001127284938.gif similarity index 100% rename from en/application-dev/reference/arkui-js/en-us_image_0000001127284938.gif rename to en/application-dev/reference/arkui-js/figures/en-us_image_0000001127284938.gif diff --git a/en/application-dev/reference/arkui-js/en-us_image_0000001167662852.gif b/en/application-dev/reference/arkui-js/figures/en-us_image_0000001167662852.gif similarity index 100% rename from en/application-dev/reference/arkui-js/en-us_image_0000001167662852.gif rename to en/application-dev/reference/arkui-js/figures/en-us_image_0000001167662852.gif diff --git a/en/application-dev/reference/arkui-js/en-us_image_0000001173324703.gif b/en/application-dev/reference/arkui-js/figures/en-us_image_0000001173324703.gif similarity index 100% rename from en/application-dev/reference/arkui-js/en-us_image_0000001173324703.gif rename to en/application-dev/reference/arkui-js/figures/en-us_image_0000001173324703.gif diff --git a/en/application-dev/reference/arkui-js/js-components-common-customizing-font.md b/en/application-dev/reference/arkui-js/js-components-common-customizing-font.md index 4054548e00f9e9b80e8d3fff5abc9d3cf209c2b4..f57ab118948791263a353c2d1da63d08ecc6466e 100644 --- a/en/application-dev/reference/arkui-js/js-components-common-customizing-font.md +++ b/en/application-dev/reference/arkui-js/js-components-common-customizing-font.md @@ -11,8 +11,8 @@ The custom font can be loaded from the font file in a project. The font file mus ``` @font-face { - font-family: HWfont; - src: url('/common/HWfont.ttf'); + font-family: font; + src: url('/common/font.ttf'); } ``` @@ -48,10 +48,10 @@ Page style: ```css /*xxx.css*/ @font-face { - font-family: HWfont; - src: url("/common/HWfont.ttf"); + font-family: font; + src: url("/common/font.ttf"); } .demo-text { - font-family: HWfont; + font-family: font; } ``` diff --git a/en/application-dev/reference/arkui-js/js-components-create-elements.md b/en/application-dev/reference/arkui-js/js-components-create-elements.md new file mode 100644 index 0000000000000000000000000000000000000000..b0afebfa68e40737f66361e501c67536472df8ac --- /dev/null +++ b/en/application-dev/reference/arkui-js/js-components-create-elements.md @@ -0,0 +1,145 @@ +# Dynamic Component Creation + +You can dynamically add components with specified attributes and styles to pages. + +> **NOTE** +> +> This API is supported since API version 8. Updates will be marked with a superscript to indicate their earliest API version. + + +## createElement + +createElement(tag: string): Element + +Creates a component object. + +**Parameters** + +| Name | Type | Mandatory | Description | +| ------- | ------------ | ---- | ------- | +| tag | string | Yes | Component name.| + +**Return value** + +| Type | Description | +| ----------- | ------------- | +| Element | Component object corresponding to the value of **tag**.| + +```js +let newImage = dom.createElement('image') +``` + + +## setAttribute + +setAttribute(name: string, value: string): void + +Dynamically sets the attributes of this component. + +**Parameters** + +| Name | Type | Mandatory | Description | +| ------- | ------------ | ---- | ------- | +| name | string | Yes | Attribute name.| +| value | string | Yes | Attribute value.| + +```js +newImage.setAttribute('src', 'common/testImage.jpg') +``` + + +## setStyle + +setStyle(name: string, value: string): boolean + +Dynamically sets the style of this component. + +**Parameters** + +| Name | Type | Mandatory | Description | +| ------- | ------------ | ---- | ------- | +| name | string | Yes | Style name.| +| value | string | Yes | Style value.| + +**Return value** + +| Type | Description | +| ----------- | ------------- | +| boolean | Returns **true** if the setting is successful; returns **false** otherwise.| + +```js +newImage.setStyle('width', '120px') +``` + + +## addChild + +addChild(child: Element): void + +Adds a dynamically created component to the parent component. + +**Parameters** + +| Name | Type | Mandatory | Description | +| ------- | ------------ | ---- | ------- | +| child | Element | Yes | Component object.| + +```js +newDiv.addChild(newImage) +``` + + +## Example + +```html + +
+
+ + +
+``` + +```css +/* xxx.css */ +.container { + flex-direction: column; + align-items: center; + width: 100%; +} + +.parent { + flex-direction: column; +} + +.btn { + width: 70%; + height: 60px; + margin: 15px; +} +``` + +```js +// xxx.js +let newDiv = null +let newImage = null + +export default { + appendDiv() { + let parent = this.$element('parentDiv') + newDiv = dom.createElement('div') + newDiv.setStyle('width', '150px') + newDiv.setStyle('height', '150px') + newDiv.setStyle('backgroundColor', '#AEEEEE') + newDiv.setStyle('marginTop', '15px') + parent.addChild(newDiv) + }, + appendImage() { + newImage = dom.createElement('image') + newImage.setAttribute('src', 'common/testImage.jpg') + newImage.setStyle('width', '120px') + newImage.setStyle('height', '120px') + newDiv.addChild(newImage) + } +} +``` diff --git a/en/application-dev/reference/arkui-js/js-components-custom-basic-usage.md b/en/application-dev/reference/arkui-js/js-components-custom-basic-usage.md index 8ae629cba3025d8d6b6d9f3ea4597678a6c1d138..b6f659f069b4e7c5f6dc6347664552a8c6a82e4d 100644 --- a/en/application-dev/reference/arkui-js/js-components-custom-basic-usage.md +++ b/en/application-dev/reference/arkui-js/js-components-custom-basic-usage.md @@ -1,6 +1,7 @@ -# Basic Usage +# Basic Usage of Custom Components + +Custom components are existing components encapsulated based on service requirements. A custom component can be invoked multiple times in a project to improve the code readability. You can import a custom component to the host page through **element** as shown in the following code snippet: -Custom components are existing components encapsulated based on service requirements. A custom component can be invoked multiple times in a project to improve the code readability. You can introduce a custom component to the host page through **element** as shown in the following code snippet: ```html
@@ -8,8 +9,8 @@ Custom components are existing components encapsulated based on service requirem
``` +The following is an example of using a custom component with **if-else**, which displays **comp1** when **showComp1** is set to **true** and displays **comp2** otherwise. -The following is an example of using a custom component with **if-else**: ```html @@ -19,18 +20,142 @@ The following is an example of using a custom component with **if-else**: ``` +The **name** attribute indicates the custom component name (optional), which is case-insensitive and is in lowercase by default. The **src** attribute indicates the **.hml** file path (mandatory) of the custom component. If **name** is not set, the **.hml** file name is used as the component name by default. + + +## Custom Events + +To bind an event to a custom child component, use the **(on|@)event-name="bindParentVmMethod"** syntax. **this.$emit('eventName', { params: 'passedParameters' })** is used in the child component to trigger the event and pass parameters to the parent component. The parent component then calls the **bindParentVmMethod** API and receives parameters passed by the child component. + +> **NOTE** +> +> For child component events that are named in camel case, convert the names to kebab case when binding the events to the parent component. For example, use **\@children-event** in the parent component instead of **childrenEvent** used in the child component. + +**Example 1 with parameters passed** + +The following example describes how to define a child component **comp**: + +```html + +
+ Click here to view the hidden text. + hello world +
+``` + +```css +/* comp.css */ +.item { + width: 700px; + flex-direction: column; + height: 300px; + align-items: center; + margin-top: 100px; +} +.text-style { + font-weight: 500; + font-family: Courier; + font-size: 40px; +} +``` + +```js +// comp.js +export default { + data: { + showObj: false, + }, + childClicked () { + this.$emit('eventType1'); + this.showObj = !this.showObj; + }, +} +``` + +The following example describes how to import **comp** to the parent component: + +```html + + +
+ +
+``` + +```css +/* xxx.css */ +.container { + background-color: #f8f8ff; + flex: 1; + flex-direction: column; + align-content: center; +} +``` + +```js +// xxx.js +export default { + textClicked () {} +} +``` + +**Example 2 with no parameters passed** + +The following example describes how to define a child component **comp**: + +```html + +
+ Click here to view the hidden text. + hello world +
+``` + +```js +// comp.js +export default { + childClicked () { + this.$emit('eventType1', { text: 'Receive the parameters from the child component.' }); + this.showObj = !this.showObj; + }, +} +``` + +In the following example, the child component passes the **text** parameter to the parent component, and the parent component obtains the parameter through **e.detail**: + +```html + + +
+ Parent component: {{text}} + +
+``` + +```js +// xxx.js +export default { + data: { + text: 'Start' + }, + textClicked (e) { + this.text = e.detail.text; + }, +} +``` + +![EventParameters](figures/EventParameters.gif) + + +## Custom Component Data -- The **name** attribute indicates the custom component name (optional), which is case-insensitive and is in lowercase by default. The **src** attribute indicates the **.hml** file path (mandatory) of the custom component. If **name** is not set, the **.hml** file name is used as the component name by default. -- Event binding: Use **(on|@)***child1* syntax to bind a child component event to a custom component. In the child component, use **this.$emit('***child1***', {params:'***parameter to pass***'})** for event triggering and value transferring. In the parent component, call **bindParentVmMethod** method and receive the parameters passed from the child component. - > **NOTE** - > - > For child component events that are named in camel case, convert the names to kebab case when binding the events to the parent component. For example, use **\@children-event** instead of **childrenEvent**: **\@children-event="bindParentVmMethod"**. +In the JS file of a custom component, you can define, pass, and process data by declaring fields such as **data**, **props**, and **computed**. For details about how to use **props** and **computed**, see [Data Transfer and Processing](js-components-custom-props.md). -**Table 1** Objects +**Table 1** Custom component data -| Name | Type | Description | +| Name | Type | Description | | -------- | --------------- | ---------------------------------------- | -| data | Object/Function | Data model of the page. If the attribute is of the function type, the return value must be of the object type. The attribute name cannot start with a dollar sign ($) or underscore (_). Do not use reserved words (**for**, **if**, **show**, and **tid**).
Do not use this attribute and **private** or **public** at the same time.(Rich) | -| props | Array/Object | Used for communication between components. This attribute can be transferred to components via **\**. A **props** name must be in lowercase and cannot start with a dollar sign ($) or underscore (\_). Do not use reserved words (**for**, **if**, **show**, and **tid**). Currently, **props** does not support functions.| -| computed | Object | Used for pre-processing an object for reading and setting. The result is cached. The name cannot start with a dollar sign ($) or underscore (\_). Do not use reserved words.| +| data | Object \| Function | Data model of the page. If the attribute is of the function type, the return value must be of the object type. The name cannot start with a dollar sign ($) or underscore (\_). Do not use reserved words (**for**, **if**, **show**, and **tid**).
Do not use this attribute and **private** or **public** at the same time.| +| props | Array \| Object | Used for communication between components. This attribute can be passed to components through **\**. A **props** name must be in lowercase and cannot start with a dollar sign ($) or underscore (_). Do not use reserved words (**for**, **if**, **show**, and **tid**) in the name. Currently, **props** does not support functions.| +| computed | Object | Used for pre-processing for reading and setting parameters. The result is cached. The name cannot start with a dollar sign ($) or underscore (\_). Do not use reserved words.| diff --git a/en/application-dev/reference/arkui-js/js-components-custom-event-parameter.md b/en/application-dev/reference/arkui-js/js-components-custom-event-parameter.md deleted file mode 100644 index 55131eddc7e7613ae7fa58086ca5c59cc9ee35c9..0000000000000000000000000000000000000000 --- a/en/application-dev/reference/arkui-js/js-components-custom-event-parameter.md +++ /dev/null @@ -1,51 +0,0 @@ -# Event Parameter - -A child component can also pass parameters to an upper-layer component through the bound event. The following example describes how to pass parameters through the custom event: - - -```html - -
- Click to View Hidden Text - hello world -
-``` - - -```js -// comp.js -export default { - childClicked () { - this.$emit('eventType1', {text: 'Received parameters from the child component.'}); - this.showObj = !this.showObj; - }, -} -``` - - -In the following example, the child component passes the **text** parameter to the parent component, and the parent component obtains the parameter through **e.detail**: - - -```html - - -
- Parent component: {{text}} - -
-``` - - -```js -// xxx.js -export default { - data: { - text: 'Start' - }, - textClicked (e) { - this.text = e.detail.text; - }, -} -``` - -![EventParameters](figures/EventParameters.gif) diff --git a/en/application-dev/reference/arkui-js/js-components-custom-events.md b/en/application-dev/reference/arkui-js/js-components-custom-events.md deleted file mode 100644 index cf2f81a31dc62c4023a2a85591f9468e6fca097d..0000000000000000000000000000000000000000 --- a/en/application-dev/reference/arkui-js/js-components-custom-events.md +++ /dev/null @@ -1,76 +0,0 @@ -# Custom Events - -The following example describes how to define a child component **comp**: - - -```html - -
- Click here to view the hidden text. - hello world -
-``` - - -```css -/* comp.css */ -.item { - width: 700px; - flex-direction: column; - height: 300px; - align-items: center; - margin-top: 100px; -} -.text-style { - font-weight: 500; - font-family: Courier; - font-size: 40px; -} -``` - - -```js -// comp.js -export default { - data: { - showObj: false, - }, - childClicked () { - this.$emit('eventType1'); - this.showObj = !this.showObj; - }, -} -``` - - -The following example describes how to introduce the child component: - - -```html - - -
- -
-``` - - -```css -/* xxx.css */ -.container { - background-color: #f8f8ff; - flex: 1; - flex-direction: column; - align-content: center; -} -``` - - -```js -// xxx.js -export default { - textClicked () {}, -} -``` - -For more information, see [Basic Usage](./js-components-custom-basic-usage.md). diff --git a/en/application-dev/reference/arkui-js/js-components-custom-props.md b/en/application-dev/reference/arkui-js/js-components-custom-props.md index f2a3a4c4faf87d3230de6d128c9c55ad20548f9d..c9c496b57842c628eabb96377c8096c6a9cc1f9c 100644 --- a/en/application-dev/reference/arkui-js/js-components-custom-props.md +++ b/en/application-dev/reference/arkui-js/js-components-custom-props.md @@ -1,22 +1,25 @@ -# props +# Data Transfer and Processing -You can use **props** to declare attributes of a custom component and pass the attributes to the child component. The supported types of **props** include String, Number, Boolean, Array, Object, and Function. Note that a camel case attribute name \(**compProp**\) should be converted to the kebab case format \(**comp-prop**\) when you reference the attribute in an external parent component. You can add **props** to a custom component, and pass the attribute to the child component. -``` +## props + +You can use **props** to declare attributes of a custom component and pass the attributes to the child component. The supported types of **props** include String, Number, Boolean, Array, Object, and Function. Note that a camel case attribute name (**compProp**) should be converted to the kebab case format (**comp-prop**) when you reference the attribute in an external parent component. The following is sample for adding **props** to a custom component and passing the attribute to the child component. + +```html
{{compProp}}
``` -``` +```js // comp.js export default { props: ['compProp'], } ``` -``` +```html
@@ -24,21 +27,22 @@ export default {
``` ->![](../../public_sys-resources/icon-note.gif) **NOTE:** ->The name of a custom attribute cannot start with reserved keywords such as **on**, **@**, **on:**, and **grab:**. +> **NOTE** +> +> The name of a custom attribute cannot start with reserved keywords such as **on**, **@**, **on:**, and **grab:**. -## Default Value +### Default Value -You can set the default value for a child component attribute via **default**. The default value is used if the parent component does not have **default** set. In this case, the **props** attribute must be in object format instead of an array. +You can set the default value for a child component attribute via **default**. The default value is used if the parent component does not have **default** set. In this case, the **props** attribute must be in object format instead of an array. -``` +```html
{{title}}
``` -``` +```js // comp.js export default { props: { @@ -49,21 +53,21 @@ export default { } ``` -In this example, a **** component is added to display the title. The title content is a custom attribute, which displays the text specified by a user. If the user has not set a title, the default text will be displayed. Add the attribute when referencing the custom component. +In this example, a **\** component is added to display the title. The title content is a custom attribute, which displays the text specified by a user. If the user has not set a title, the default text will be displayed. Add the attribute when referencing the custom component. -``` +```html
- +
``` -## Unidirectional Value Transfer +### Unidirectional Value Transfer -Data can be transferred only from the parent component to child components. You are not allowed to change the value passed to the child component. However, you can receive the value passed by **props** as a default value in **data**, and then change the **data** value. +Data can be transferred only from the parent component to child components. You are not allowed to change the value passed to the child component. However, you can receive the value passed by **props** as a default value in **data**, and then change the **data** value. -``` +```js // comp.js export default { props: ['defaultCount'], @@ -78,11 +82,11 @@ export default { } ``` -## Monitoring Data Changes by **$watch** +### Monitoring Data Changes by **$watch** -To listen for attribute changes in a component, you can use the **$watch** method to add a callback. The following code snippet shows how to use **$watch**: +To listen for attribute changes in a component, you can use the **$watch** method to add a callback. The following code snippet shows how to use **$watch**: -``` +```js // comp.js export default { props: ['title'], @@ -90,16 +94,17 @@ export default { this.$watch('title', 'onPropertyChange'); }, onPropertyChange(newV, oldV) { - console.info('title attribute changed'+ newV + ' ' + oldV) + console.info('title attribute changed'+ newV + ' ' + oldV) }, } ``` -## Computed Property -To improve the development efficiency, you can use a computed property to pre-process an attribute in a custom component before reading or setting the attribute. In the **computed** field, you can set a getter or setter to be triggered when the attribute is read or written, respectively. The following is an example: +## computed -``` +To improve the development efficiency, you can use a computed property to pre-process an attribute in a custom component before reading or setting the attribute. In the **computed** field, you can set a getter or setter to be triggered when the attribute is read or written, respectively. The following is an example: + +```js // comp.js export default { props: ['title'], @@ -129,5 +134,4 @@ export default { } ``` -The first computed property **message** has only a getter. The value of **message** changes depending on the **objTitle** value. The getter can only read but cannot set the value. You need a setter \(such as **notice** in the sample code\) to set the value of the computed property. - +The first computed property **message** has only a getter. The value of **message** changes depending on the **objTitle** value. The getter can only read but cannot set the value (such as **time** defined during initialization in **data**). You need a setter (such as **notice** in the sample code) to set the value of the computed property. diff --git a/en/application-dev/reference/arkui-js/js-components-custom-slot.md b/en/application-dev/reference/arkui-js/js-components-custom-slot.md index b65cfd01d2603195100ed8c0709289dd7b59b692..50c5b9ed0d1ad181567945134be95e0f9c229fed 100644 --- a/en/application-dev/reference/arkui-js/js-components-custom-slot.md +++ b/en/application-dev/reference/arkui-js/js-components-custom-slot.md @@ -1,13 +1,15 @@ -# slot +# slot ->![](../../public_sys-resources/icon-note.gif) **NOTE:** ->The APIs of this module are supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version. +> **NOTE** +> +> The APIs of this module are supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version. -## Default Slot -You can use the **** tag to create a slot inside a custom component to fill the content defined in the parent component. The sample code is as follows: +## Default Slot -``` +You can use the **\** tag to create a slot inside a custom component to fill the content defined in the parent component. The sample code is as follows: + +```html
The following uses the content defined in the parent component. @@ -16,22 +18,22 @@ You can use the **** tag to create a slot inside a custom component to ``` The following references the custom component: - -``` +```html
- Content defined in the parent component + Content defined in the parent component
``` -## Named Slot -When multiple slots are need inside a custom component, you can name them, so that you can specify the slot in which you want to fill content by setting the **** attribute. +## Named Slot -``` +When multiple slots are need inside a custom component, you can name them, so that you can specify the slot in which you want to fill content by setting the **** attribute. + +```html
The following uses the content defined in the parent component. @@ -41,8 +43,7 @@ When multiple slots are need inside a custom component, you can name them, so th ``` The following references the custom component: - -``` +```html
@@ -53,6 +54,6 @@ The following references the custom component:
``` ->![](../../public_sys-resources/icon-note.gif) **NOTE:** ->**** and **** do not support dynamic data binding. - +> **NOTE** +> +> **\** and **\** do not support dynamic data binding. diff --git a/en/application-dev/reference/arkui-js/js-components-custom-style.md b/en/application-dev/reference/arkui-js/js-components-custom-style.md index 37e0770cdeec8de1e3bd3c89360c56973353cea4..ba8644e3e347e700b523ea0c7f2ab02159faeca7 100644 --- a/en/application-dev/reference/arkui-js/js-components-custom-style.md +++ b/en/application-dev/reference/arkui-js/js-components-custom-style.md @@ -1,16 +1,19 @@ # Style Inheritance + > **NOTE**
-> The APIs of this module are supported since API 9. Updates will be marked with a superscript to indicate their earliest API version. +> +> The APIs of this module are supported since API version 9. Updates will be marked with a superscript to indicate their earliest API version. A custom component has the **inherit-class** attribute, which is defined in the following table. -| Name | Type | Default Value| Mandatory| Description | -| ------------ | ------ | ------ | ---- | ------------------------------------------------------ | -| inherit-class | string | - | No | Class styles inherited from the parent component, seperated by spaces.| +| Name | Type | Default Value | Mandatory | Description | +| ------------- | ------ | ---- | ---- | -------------------------------- | +| inherit-class | string | - | No | Class styles inherited from the parent component, separated by spaces.| To enable a custom component to inherit the styles of its parent component, set the **inherit-calss** attribute for the custom component. -The example below is a code snippet in the HML file of the parent page that references a custom component named **comp**. This component uses the **inherit-class** attribute to inherit the styles of its parent component: **parent-class1** and **parent-class2**. +The example below is a code snippet in the HML file of the parent component that references a custom component named **comp**. This component uses the **inherit-class** attribute to inherit the styles of its parent component: **parent-class1** and **parent-class2**. + ```html @@ -20,9 +23,10 @@ The example below is a code snippet in the HML file of the parent page that refe
``` -Code snippet in the CSS file of the parent page: -```html -// xxx.css +Code snippet in the CSS file of the parent component: + +```css +/* xxx.css */ .parent-class1 { background-color:red; border:2px; @@ -34,6 +38,7 @@ Code snippet in the CSS file of the parent page: ``` Code snippet in the HML file of the custom component, where **parent-class1** and **parent-class2** are styles inherited from the parent component: + ```html
diff --git a/en/application-dev/reference/arkui-js/js-components-svg-animate.md b/en/application-dev/reference/arkui-js/js-components-svg-animate.md index 0d298e588c1de3e69e0eea10aed2a3381688ff32..e90d520cb36057ac385917e4df3d532c8669e97d 100644 --- a/en/application-dev/reference/arkui-js/js-components-svg-animate.md +++ b/en/application-dev/reference/arkui-js/js-components-svg-animate.md @@ -52,7 +52,7 @@ Not supported ``` -![zh-cn_image_0000001173324703](figures/en-us_image_0000001173324703.gif) +![en-us_image_0000001173324703](figures/en-us_image_0000001173324703.gif) ```html @@ -68,7 +68,7 @@ Not supported ``` -![zh-cn_image_0000001167662852](figures/en-us_image_0000001167662852.gif) +![en-us_image_0000001167662852](figures/en-us_image_0000001167662852.gif) ```html @@ -83,7 +83,7 @@ Not supported ``` -![zh-cn_image_0000001127284938](figures/en-us_image_0000001127284938.gif) +![en-us_image_0000001127284938](figures/en-us_image_0000001127284938.gif) ```html @@ -117,4 +117,4 @@ Not supported ``` -![animate-4](figures/animate-4.gif) +![en-us_image_0000001127125126](figures/en-us_image_0000001127125126.gif) diff --git a/en/application-dev/reference/arkui-ts/figures/align.png b/en/application-dev/reference/arkui-ts/figures/align.png index beed805dbff1ec1526bf034c011cf2c7b926eae8..ffabc26d3ee59984dda6cb375f8b18bb319b4fc7 100644 Binary files a/en/application-dev/reference/arkui-ts/figures/align.png and b/en/application-dev/reference/arkui-ts/figures/align.png differ diff --git a/en/application-dev/reference/arkui-ts/figures/en-us_image_0000001219864159.gif b/en/application-dev/reference/arkui-ts/figures/en-us_image_0000001219864159.gif new file mode 100644 index 0000000000000000000000000000000000000000..badadbdb856c478fdb2ec53f70015b29bb10041f Binary files /dev/null and b/en/application-dev/reference/arkui-ts/figures/en-us_image_0000001219864159.gif differ diff --git a/en/application-dev/reference/arkui-ts/figures/en-us_image_0000001257138339.gif b/en/application-dev/reference/arkui-ts/figures/en-us_image_0000001257138339.gif deleted file mode 100644 index 557213e5ff5c63c5f3b3db7ffbd56e80eef688f1..0000000000000000000000000000000000000000 Binary files a/en/application-dev/reference/arkui-ts/figures/en-us_image_0000001257138339.gif and /dev/null differ diff --git a/en/application-dev/reference/arkui-ts/ts-container-gridcol.md b/en/application-dev/reference/arkui-ts/ts-container-gridcol.md index e808617b90335ce1aaa8dddbb8304124a85a3540..33870e0f047cd048aad3f5e1e049da82cbe1202c 100644 --- a/en/application-dev/reference/arkui-ts/ts-container-gridcol.md +++ b/en/application-dev/reference/arkui-ts/ts-container-gridcol.md @@ -1,6 +1,6 @@ # GridCol -The **\** component must be used as a child component of the [GridRow](ts-container-gridrow.md) container. +The **\** component must be used as a child component of the **[\](ts-container-gridrow.md)** container. > **NOTE** > @@ -15,11 +15,11 @@ GridCol(option?:{span?: number | GridColColumnOption, offset?: number | GridColC **Parameters** -| Name| Type | Mandatory| Description | -| ------ | ----------------------------- | ---- | ------------------------------------------------------------ | -| span | number \| GridColColumnOption | No | Number of occupied columns. If it is set to **0**, the element is not involved in layout calculation, that is, the element is not rendered.
Default value: **1**| -| offset | number \| GridColColumnOption | No | Number of offset columns relative to the previous child component of the grid
Default value: **0** | -| order | number \| GridColColumnOption | No | Sequence number of the element. Child components of the grid are sorted in ascending order based on their sequence numbers.
Default value: **0**| +| Name| Type | Mandatory| Description | +| ------ | ----------------------------------------------------- | ---- | ------------------------------------------------------------ | +| span | number \| [GridColColumnOption](#gridcolcolumnoption) | No | Number of occupied columns. If it is set to **0**, the element is not involved in layout calculation, that is, the element is not rendered.
Default value: **1**| +| offset | number \| [GridColColumnOption](#gridcolcolumnoption) | No | Number of offset columns relative to the previous child component of the grid
Default value: **0** | +| order | number \| [GridColColumnOption](#gridcolcolumnoption) | No | Sequence number of the element. Child components of the grid are sorted in ascending order based on their sequence numbers.
Default value: **0**| ## Attributes diff --git a/en/application-dev/reference/arkui-ts/ts-container-listitem.md b/en/application-dev/reference/arkui-ts/ts-container-listitem.md index ae044f9ddfddc305898c6c6bc65fb1dd90b845de..9de0b8a25a4bf88c91c0883561cc9ff61b63c086 100644 --- a/en/application-dev/reference/arkui-ts/ts-container-listitem.md +++ b/en/application-dev/reference/arkui-ts/ts-container-listitem.md @@ -22,20 +22,21 @@ In addition to the [universal attributes](ts-universal-attributes-size.md), the | Name| Type| Description| | -------- | -------- | -------- | -| sticky | [Sticky](#sticky)| Sticky effect of the list item.
Default value: **Sticky.None**| -| editable | boolean \| [EditMode](#editmode)| Whether to enter editing mode, where the list item can be deleted or moved.
Default value: **false**| +| sticky(deprecated) | [Sticky](#stickydeprecated) | Sticky effect of the list item.
Default value: **Sticky.None**
This API is deprecated since API version 9. You are advised to use **sticky** of the [\](ts-container-list.md#attributes) component. | +| editable(deprecated) | boolean \| [EditMode](#editmodedeprecated) | Whether to enter editing mode, where the list item can be deleted or moved.
This API is deprecated since API version 9.
Default value: **false**| | selectable8+ | boolean | Whether the current list item is selectable by mouse drag.
**NOTE**
This attribute takes effect only when mouse frame selection is enabled for the parent **\** container.
Default value: **true**| | swipeAction9+ | {
start?: CustomBuilder,
end?:CustomBuilder,
edgeEffect?: [SwipeEdgeEffect](#swipeedgeeffect9),
} | Component displayed when the list item is swiped out from the screen edge.
- **start**: component on the left of the list item when the item is swiped to the right (in vertical list layout) or component above the list item when the item is swiped down (in horizontal list layout).
- **end**: component on the right of the list item when the item is swiped to the left (in vertical list layout) or component below the list item when the item is swiped up (in horizontal list layout).
- **edgeEffect**: scroll effect.
| -## Sticky +## Sticky(deprecated) +This API is deprecated since API version 9. You are advised to use [stickyStyle](ts-container-list.md#stickystyle9) of the **\** component. | Name| Description| | -------- | -------- | | None | The list item is not sticky.| | Normal | The list item is sticky with no special effects.| | Opacity | The list item is sticky with opacity changes.| -## EditMode - +## EditMode(deprecated) +This API is deprecated since API version 9. | Name | Description | | ------ | --------- | | None | The editing operation is not restricted. | @@ -63,41 +64,24 @@ In addition to the [universal attributes](ts-universal-attributes-size.md), the @Component struct ListItemExample { private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - @State editFlag: boolean = false build() { Column() { List({ space: 20, initialIndex: 0 }) { - ListItem() { - Text('sticky:Normal , click me edit list') - .width('100%').height(40).fontSize(12).fontColor(0xFFFFFF) - .textAlign(TextAlign.Center).backgroundColor(0x696969) - .onClick(() => { - this.editFlag = !this.editFlag - }) - }.sticky(Sticky.Normal) - ForEach(this.arr, (item) => { ListItem() { Text('' + item) .width('100%').height(100).fontSize(16) .textAlign(TextAlign.Center).borderRadius(10).backgroundColor(0xFFFFFF) - }.editable(this.editFlag) + } }, item => item) - } - .editMode(true) - .onItemDelete((index: number) => { - console.info(this.arr[index - 1] + 'Delete') - this.arr.splice(index - 1,1) - this.editFlag = false - return true - }).width('90%') + }.width('90%') }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 }) } } ``` -![en-us_image_0000001257138339](figures/en-us_image_0000001257138339.gif) +![en-us_image_0000001219864159](figures/en-us_image_0000001219864159.gif) ```ts // xxx.ets diff --git a/en/application-dev/reference/arkui-ts/ts-container-swiper.md b/en/application-dev/reference/arkui-ts/ts-container-swiper.md index 24021435e468e24216d765a0d60ffad2e2d3824c..dc3c3e9859a27813299a3ccb9e1ddaff47b88cea 100644 --- a/en/application-dev/reference/arkui-ts/ts-container-swiper.md +++ b/en/application-dev/reference/arkui-ts/ts-container-swiper.md @@ -76,7 +76,7 @@ Stops an animation. **Parameters** -| Name | Type | Mandatory.| Description| +| Name | Type | Mandatory | Description| | --------- | ---------- | ------ | -------- | | callback | () => void | No | Callback invoked when the animation stops.| @@ -88,6 +88,10 @@ onChange(event: (index: number) => void) Triggered when the index of the currently displayed child component changes. +> **NOTE** +> +> When the **\** component is used together with **LazyForEach**, the subpage UI cannot be refreshed in the **onChange** event. + **Return value** | Name | Type | Description| diff --git a/en/application-dev/reference/arkui-ts/ts-universal-attributes-location.md b/en/application-dev/reference/arkui-ts/ts-universal-attributes-location.md index 0670ab7d107bc99606d151b229b470b7a42a27a7..8425cf29444183671c4fd8e3389bd0ffa28840f9 100644 --- a/en/application-dev/reference/arkui-ts/ts-universal-attributes-location.md +++ b/en/application-dev/reference/arkui-ts/ts-universal-attributes-location.md @@ -46,7 +46,7 @@ struct PositionExample1 { .fontSize(16) .backgroundColor(0xFFE4C4) - // To arrange the child components from left to right, set direction of the parent container to Direction.Auto or Direction.Ltr, or leave it to the default value. + // To arrange the child components from left to right, set direction of the parent container to Direction.Ltr. Text('direction').fontSize(9).fontColor(0xCCCCCC).width('90%') Row() { Text('1').height(50).width('25%').fontSize(16).backgroundColor(0xF5DEB3) @@ -55,19 +55,19 @@ struct PositionExample1 { Text('4').height(50).width('25%').fontSize(16).backgroundColor(0xD2B48C) } .width('90%') - .direction(Direction.Auto) + .direction(Direction.Ltr) // To arrange the child components from right to left, set direction of the parent container to Direction.Rtl. Row() { - Text('1').height(50).width('25%').fontSize(16).backgroundColor(0xF5DEB3) - Text('2').height(50).width('25%').fontSize(16).backgroundColor(0xD2B48C) - Text('3').height(50).width('25%').fontSize(16).backgroundColor(0xF5DEB3) - Text('4').height(50).width('25%').fontSize(16).backgroundColor(0xD2B48C) + Text('1').height(50).width('25%').fontSize(16).backgroundColor(0xF5DEB3).textAlign(TextAlign.End) + Text('2').height(50).width('25%').fontSize(16).backgroundColor(0xD2B48C).textAlign(TextAlign.End) + Text('3').height(50).width('25%').fontSize(16).backgroundColor(0xF5DEB3).textAlign(TextAlign.End) + Text('4').height(50).width('25%').fontSize(16).backgroundColor(0xD2B48C).textAlign(TextAlign.End) } .width('90%') .direction(Direction.Rtl) } } - .width('100%').margin({ top: 5 }).direction(Direction.Rtl) + .width('100%').margin({ top: 5 }) } } ``` diff --git a/en/application-dev/reference/arkui-ts/ts-universal-events-show-hide.md b/en/application-dev/reference/arkui-ts/ts-universal-events-show-hide.md index 6230df00006aae28708d76f6662ced618a3a8351..7b1db0758f125113d863399d75a7672db10c302a 100644 --- a/en/application-dev/reference/arkui-ts/ts-universal-events-show-hide.md +++ b/en/application-dev/reference/arkui-ts/ts-universal-events-show-hide.md @@ -12,14 +12,14 @@ The show/hide event is triggered when a component is mounted or unmounted from t | Name | Bubbling Supported| Description | | ------------------------------------------------ | -------- | -------------------------- | | onAppear(event: () => void) | No | Triggered when the component is displayed.| -| onDisappear(event: () => void) | No | Triggered when the component is hidden. | +| onDisAppear(event: () => void) | No | Triggered when the component is hidden.| ## Example ```ts // xxx.ets -import prompt from '@ohos.prompt' +import promptAction from '@ohos.promptAction' @Entry @Component @@ -38,14 +38,14 @@ struct AppearExample { Text(this.myText).fontSize(26).fontWeight(FontWeight.Bold) .onAppear(() => { this.changeAppear = 'Hide Text' - prompt.showToast({ + promptAction.showToast({ message: 'The text is shown', duration: 2000 }) }) .onDisAppear(() => { this.changeAppear = 'Show Text' - prompt.showToast({ + promptAction.showToast({ message: 'The text is hidden', duration: 2000 }) diff --git a/en/application-dev/reference/errorcodes/Readme-EN.md b/en/application-dev/reference/errorcodes/Readme-EN.md index c7321b0cf5becf80f21786e52ae8d807ae892049..b286cbf232d6d334444b164117fa289b79f9a6c4 100644 --- a/en/application-dev/reference/errorcodes/Readme-EN.md +++ b/en/application-dev/reference/errorcodes/Readme-EN.md @@ -37,6 +37,8 @@ - [RDB Error Codes](errorcode-data-rdb.md) - [Distributed KV Store Error Codes](errorcode-distributedKVStore.md) - [Preferences Error Codes](errorcode-preferences.md) +- File Management + - [File Management Error Codes](errorcode-filemanagement.md) - Network Management - [Upload and Download Error Codes](errorcode-request.md) - Connectivity diff --git a/en/application-dev/reference/errorcodes/errorcode-filemanagement.md b/en/application-dev/reference/errorcodes/errorcode-filemanagement.md new file mode 100644 index 0000000000000000000000000000000000000000..42192691a4127493dfe94fbef0d67135f870a253 --- /dev/null +++ b/en/application-dev/reference/errorcodes/errorcode-filemanagement.md @@ -0,0 +1,721 @@ +# File Management Error Codes +The error codes of the file management subsystem consist of the following: + +- Basic file I/O error codes +- User data management error codes +- User file access error codes +- Spatial statistics error codes + +## Basic File I/O Error Codes + +### 13900001 Operation Not Permitted + +**Error Message** +Operation not permitted + +**Possible Causes** +The current operation on the file is not allowed. + +**Solution** +Check the permission for the file. + +### 13900002 File or Directory Not Exist + +**Error Message** +No such file or directory + +**Possible Causes** +The file or directory does not exist. + +**Solution** +Check whether the file directory exists. + +### 13900003 Process Not Exist + +**Error Message** +No such process + +**Possible Causes** +The process does not exist. + +**Solution** +1. Check whether the process is killed unexpectedly. +2. Check whether the service related to the process has started. + +### 13900004 System Call Interrupted + +**Error Message** +Interrupted system call + +**Possible Causes** +The system call is interrupted by another thread. + +**Solution** +1. Check the multi-thread code logic. +2. Invoke the system call again. + +### 13900005 I/O Error + +**Error Message** +I/O error + +**Possible Causes** +The I/O request is invalid. + +**Solution** +Initiate the I/O request again. + +### 13900006 Device or Address Not Exist + +**Error Message** +No such device or address + +**Possible Causes** +The device information or address is incorrect. + +**Solution** +Check that the device information or address is correct. + +### 13900007 Long Parameter List + +**Error Message** +Arg list too long + +**Possible Causes** +The parameter list is too long. + +**Solution** +Reduce the number of parameters. + +### 13900008 Invalid File Descriptor + +**Error Message** +Bad file descriptor + +**Possible Causes** +This file descriptor is closed. + +**Solution** +Check whether the file descriptor is closed. + +### 13900009 Child Process Not Exist + +**Error Message** +No child processes + +**Possible Causes** +The child process cannot be created. + +**Solution** +Check the maximum number of processes in the system. + +### 13900010 Resource Unavailable + +**Error Message** +Try again + +**Possible Causes** +The resources are blocked. + +**Solution** +Request resources. + +### 13900011 Memory Overflow + +**Error Message** +Out of memory + +**Possible Causes** +A memory overflow occurs. + +**Solution** +1. Check the memory overhead. +2. Control the memory overhead. + +### 13900012 Permission Denied + +**Error Message** +Permission denied + +**Possible Causes** +1. You do not have the permission to operate the file. +2. The file sandbox path is incorrect. + +**Solution** +1. Check that you have the permission to operate the file. +2. Check that the file sandbox path is correct. + +### 13900013 Incorrect Address + +**Error Message** +Bad address + +**Possible Causes** +The address is incorrect. + +**Solution** +Check that the address is correct. + +### 13900014 Device or Resource Not Available + +**Error Message** +Device or resource busy + +**Possible Causes** +The requested resource is unavailable. + +**Solution** +Request the resource again. + +### 13900015 File Already Exists + +**Error Message** +File exists + +**Possible Causes** +The file to be created already exists. + +**Solution** +Check whether the file path is correct. + +### 13900016 Invalid Cross-Device Link + +**Error Message** +Cross-device link + +**Possible Causes** +The link between devices is incorrect. + +**Solution** +Check the devices and create the link correctly. + +### 13900017 Device Not Exist + +**Error Message** +No such device + +**Possible Causes** +The device is not identified. + +**Solution** +Check the connection to the target device. + +### 13900018 Invalid Directory + +**Error Message** +Not a directory + +**Possible Causes** +The specified directory is invalid. + +**Solution** +Check that the directory is correct. + +### 13900019 The Specified Object Is a Directory + +**Error Message** +Is a directory + +**Possible Causes** +The specified object is a directory. + +**Solution** +Check that the specified data is correct. + +### 13900020 Invalid Parameter + +**Error Message** +Invalid argument + +**Possible Causes** +Invalid input parameter is detected. + +**Solution** +Check that the input parameters are valid. + +### 13900021 Too Many File Descriptors Opened + +**Error Message** +File table overflow + +**Possible Causes** +The number of file descriptors opened has reached the limit. + +**Solution** +Close the file descriptors that are no longer required. + +### 13900022 Too Many Files Opened + +**Error Message** +Too many open files + +**Possible Causes** +The number of files opened has reached the limit. + +**Solution** +Close the files that are not required. + +### 13900023 Text File Not Respond + +**Error Message** +Text file busy + +**Possible Causes** +The executable file of the program is in use. + +**Solution** +Close the program that is being debugged. + +### 13900024 File Oversized + +**Error Message** +File too large + +**Possible Causes** +The file size exceeds the limit. + +**Solution** +Check whether the file size exceeds the limit. + +### 13900025 Insufficient Space on the Device + +**Error Message** +No space left on device + +**Possible Causes** +The device storage space is insufficient. + +**Solution** +Clear the space of the device. + +### 13900026 Invalid Shift + +**Error Message** +Illegal seek + +**Possible Causes** +Seek is used in pipe or FIFO. + +**Solution** +Check the use of seek. + +### 13900027 Read-Only File System + +**Error Message** +Read-only file system + +**Possible Causes** +The file system allows read operations only. + +**Solution** +Check whether the file is read-only. + +### 13900028 Links Reach the Limit + +**Error Message** +Too many links + +**Possible Causes** +The number of links to the file has reached the limit. + +**Solution** +Delete the links that are no longer required. + +### 13900029 Resource Deadlock + +**Error Message** +Resource deadlock would occur + +**Possible Causes** +Resource deadlock occurs. + +**Solution** +Terminate the deadlock process. + +### 13900030 Long File Name + +**Error Message** +Filename too Long + +**Possible Causes** +The length of the path or file name exceeds the limit. + +**Solution** +Modify the path or file name. + +### 13900031 Function Not Implemented + +**Error Message** +Function not implemented + +**Possible Causes** +The function is not supported by the system. + +**Solution** +Check the system version and update the system if required. + +### 13900032 Directory Not Empty + +**Error Message** +Directory not empty + +**Possible Causes** +The specified directory is not empty. + +**Solution** +1. Check the directory. +2. Ensure that the directory is empty. + +### 13900033 Too Many Symbol Links + +**Error Message** +Too many symbolic links + +**Possible Causes** +There are too many symbolic links. + +**Solution** +Delete unnecessary symbol links. + +### 13900034 Operation Blocked + +**Error Message** +Operation would block + +**Possible Causes** +The operation is blocked. + +**Solution** +Perform the operation again. + +### 13900035 Invalid File Descriptor + +**Error Message** +Invalid request desecriptor + +**Possible Causes** +The requested file descriptor is invalid. + +**Solution** +Check that the file descriptor is valid. + +### 13900036 Target Is Not a Character Stream Device + +**Error Message** +Device not a stream + +**Possible Causes** +The device pointed to by the file descriptor is not a character stream device. + +**Solution** +Check whether the file descriptor points to a stream device. + +### 13900037 No Data Available + +**Error Message** +No data available + +**Possible Causes** +The required data is not available. + +**Solution** +Request the data again. + +### 13900038 Value Mismatches the Data Type + +**Error Message** +Value too large for defined data type + +**Possible Causes** +The specified value is out of the range defined for the data type. + +**Solution** +Modify the data type. + +### 13900039 File Descriptor Corrupted + +**Error Message** +File descriptor in bad state + +**Possible Causes** +The file descriptor is corrupted. + +**Solution** +Check that the file descriptor is valid. + +### 13900040 System Call Interrupted + +**Error Message** +Interrupted systen call should be restarted + +**Possible Causes** +The system call is interrupted. + +**Solution** +Invoke the system call again. + +### 13900041 Disk Quota Exceeded + +**Error Message** +Quota exceeded + +**Possible Causes** +The disk space is insufficient. + +**Solution** +Clear disk space. + +### 13900042 Unknown Error + +**Error Message** +Unknown error + +**Possible Causes** +The error is unidentified. + +**Solution** +1. Call the API again. +2. Restart the service. + +## User Data Management Error Codes + +### 14000001 Invalid File Name + +**Error Message** +Invalid display name + +**Possible Causes** +The file name contains invalid characters. + +**Solution** +Modify the file name. + +### 14000002 Invalid URI + +**Error Message** +Invalid uri + +**Possible Causes** +The URI is invalid. + +**Solution** +Use the obtained URI. + +### 14000003 Invalid File Name Extension + +**Error Message** +Invalid file extension + +**Possible Causes** +The file name extension is incorrect. + +**Solution** +Modify the file name extension. + +### 14000004 File in Recycle Bin + +**Error Message** +File has been put into trash bin + +**Possible Causes** +The file is moved to the Recycle Bin. + +**Solution** +Check whether the file is in the Recycle Bin. + +## Spatial Statistics Error Codes + +### 13600001 IPC Failed + +**Error Message** +IPC error + +**Possible Causes** +The called service does not exist. + +**Solution** +Check whether the service is started. + +### 13600002 File System Not Supported + +**Error Message** +Not supported filesystem + +**Possible Causes** +The file system is not supported. + +**Solution** +Use a supported file system. + +### 13600003 Mount Failed + +**Error Message** +Failed to mount + +**Possible Causes** +The **mount** command fails. + +**Solution** +Remove the card and run the **mount** command again. + +### 13600004 Unmount Failed + +**Error Message** +Failed to unmount + +**Possible Causes** +The device does not respond. + +**Solution** +Check whether the file is being used. If yes, kill the thread that uses the file. + +### 13600005 Incorrect Volume State + +**Error Message** +Incorrect volume state + +**Possible Causes** +The volume state is incorrect. + +**Solution** +Check whether the current volume state is correct. + +### 13600006 Failed to Create a Directory or Node + +**Error Message** +Prepare directory or node error + +**Possible Causes** +The directory or node to be created already exists. + +**Solution** +Check whether the directory or node to be created already exists. + +### 13600007 Failed to Delete a Directory or Node + +**Error Message** +Delete directory or node error + +**Possible Causes** +The specified directory or node has been deleted. + +**Solution** +Check whether the specified directory or node exists. + +### 13600008 Object Not Exist + +**Error Message** +No such object + +**Possible Causes** +1. The specified volume ID is incorrect. +2. The specified bundle name is incorrect. + +**Solution** +1. Check whether the specified volume exists. +2. Check whether the specified bundle name exists. + +### 13600009 Invalid User ID + +**Error Message** +User id out of range + +**Possible Causes** +The specified user ID is incorrect. + +**Solution** +Check that the user ID is correct. + +## User File Access Error Codes + +### 14300001 IPC Failed + +**Error Message** +IPC error + +**Possible Causes** +1. The server service does not exist. +2. The extension mechanism is abnormal. + +**Solution** +Check that the server service exists. + +### 14300002 Incorrect URI Format + +**Error Message** +Invalid uri + +**Possible Causes** +The URI is invalid. + +**Solution** +Check that the URI is in correct format. + +### 14300003 Failed to Obtain the Server Ability Information + +**Error Message** +Fail to get fileextension info + +**Possible Causes** +The BMS interface is abnormal. + +**Solution** +Check for basic system capability errors. + +### 14300004 Incorrect Result Returned by js-server + +**Error Message** +Get wrong result + +**Possible Causes** +The data returned by the server is incorrect. + +**Solution** +Check the data returned by the server. + +### 14300005 Failed to Register Notify + +**Error Message** +Fail to register notification + +**Possible Causes** +1. The server service does not exist. +2. The extension mechanism is abnormal. + +**Solution** +Check that the server service exists. + +### 14300006 Failed to Unregister Notify + +**Error Message** +Fail to remove notification + +**Possible Causes** +1. The server service does not exist. +2. The extension mechanism is abnormal. + +**Solution** +Check that the server service exists. + +### 14300007 Failed to Initialize the Notify Agent + +**Error Message** +Fail to init notification agent + +**Possible Causes** +The specified Notify agent has not been registered. + +**Solution** +Check whether the specified Notify agent is registered. + +### 14300008 Failed to Notify the Agent + +**Error Message** +Fail to notify agent + +**Possible Causes** +1. The service does not exist. +2. The extension mechanism is abnormal. + +**Solution** +Check whether the client is normal. diff --git a/en/application-dev/security/Readme-EN.md b/en/application-dev/security/Readme-EN.md index ce9f1dd695f62073424c5b967207ba316cd079b5..05d2d2864de5dc34947f43d1b54ab2480e039747 100644 --- a/en/application-dev/security/Readme-EN.md +++ b/en/application-dev/security/Readme-EN.md @@ -8,7 +8,7 @@ - User Authentication - [User Authentication Overview](userauth-overview.md) - [User Authentication Development](userauth-guidelines.md) -- Key Management +- HUKS - [HUKS Overview](huks-overview.md) - [HUKS Development](huks-guidelines.md) - Crypto Framework @@ -20,3 +20,4 @@ - hapsigner - [hapsigner Overview](hapsigntool-overview.md) - [hapsigner Guide](hapsigntool-guidelines.md) + - [HarmonyAppProvision Configuration File](app-provision-structure.md) \ No newline at end of file diff --git a/en/application-dev/security/accesstoken-guidelines.md b/en/application-dev/security/accesstoken-guidelines.md index c46c8fc8283271764986d20659276cf9f64aa555..0e45400d14daae6417908bf13ed0127d1ccb7284 100644 --- a/en/application-dev/security/accesstoken-guidelines.md +++ b/en/application-dev/security/accesstoken-guidelines.md @@ -2,58 +2,46 @@ ## When to Use -In this example, the app requires the **ohos.permission.PERMISSION1** and **ohos.permission.PERMISSION2** permissions to implement core functions. +The [Ability Privilege Level (APL)](accesstoken-overview.md#app-apls) of an application can be **normal**, **system_basic**, or **system_core**. The default APL is **normal**. The [permission types](accesstoken-overview.md#permission-types) include **system_grant** and **user_grant**. For details about the permissions for apps, see the [App Permission List](permission-list.md). -- The ability privilege level (APL) of the app is **normal**. -- The level of **ohos.permission.PERMISSION1** is **normal**, and the authorization mode is **system_grant**. -- The level of **ohos.permission.PERMISSION2** is **system_basic**, and the authorization mode is **user_grant**. +This document describes the following operations: -> **CAUTION** -> -> In this scenario, the required permissions include a **user_grant** permission. You can check whether the caller has the required permission through permission verification. -> -> If the permission verification result indicates that the app has not obtained that permission, dynamic user authorization is required. +- [Declaring Permissions in the Configuration File](#declaring-permissions-in-the-configuration-file) +- [Declaring Permissions in the ACL](#declaring-permissions-in-the-acl) +- [Requesting User Authorization](#requesting-user-authorization) +- [Pre-Authorizing user_grant Permissions](#pre-authorizing-user_grant-permissions) -## Available APIs +## Declaring Permissions in the Configuration File -The table below lists only the API used in this guide. For more information, see [Ability Access control](../reference/apis/js-apis-ability-context.md). +During the development, you need to declare the permissions required by your application one by one in the project configuration file. The application cannot obtain the permissions that are not declared in the configuration file. OpenHarmony provides two application models: FA model and stage model. For more information, see Application Models. The application bundle and configuration file vary with the application model. -| API | Description | -| ------------------------------------------------------------ | --------------------------------------------------- | -| requestPermissionsFromUser(permissions: Array<string>, requestCallback: AsyncCallback<PermissionRequestResult>) : void; | Requests permissions from the user by displaying a dialog box. This API uses an asynchronous callback to return the result.| +> **NOTE**
The default APL of an application is **normal**. When an application needs the **system_basic** or **system_core** APL, you must declare the permission in the configuration file and the [Access Control List (ACL)](#declaring-permissions-in-the-acl). -## Declaring Permissions +The following table describes the fields in the configuration file. -Declare the permissions required by the app one by one in the project configuration file. The app cannot obtain the permissions that are not declared in the configuration file. The ability framework provides two models: Feature Ability (FA) model and stage model. For more information, see [Ability Framework Overview](../ability/ability-brief.md). +| Field | Mandatory| Description | +| --------- | -------- | ------------------------------------------------------------ | +| name | Yes | Name of the permission. | +| reason | No | Reason for requesting the permission.
This field is mandatory when the requested permission needs user authorization (user_grant).| +| usedScene | No | Application scenario of the permission.
This field is mandatory when the requested permission needs user authorization (user_grant).| +| abilities | No | Abilities that require the permission. The value is an array.
**Applicable model**: stage| +| ability | No | Abilities that require the permission. The value is an array.
**Applicable model**: FA| +| when | No | Time when the permission is used.
Value:
- **inuse**: The permission applies only to a foreground application.
- **always**: The permission applies to both the foreground and background applications.| -Note that the app bundle structure and configuration file vary with the ability framework model. - -The following table describes the tags in the configuration file. - -| Field | Description | -| --------- | ------------------------------------------------------------ | -| name | Name of the permission. | -| reason | Reason for requesting the permission. This field is mandatory for a user_grant permission.| -| usedScene | Scenario of the permission. This field is mandatory for a user_grant permission.| -| ability | Abilities that use the permission. The value is an array.
**Applicable model**: FA | -| abilities | Abilities that use the permission. The value is an array.
**Applicable model**: stage | -| when | Time when the permission is used. The value can be **inuse** (the permission can be used only in the foreground) or **always** (the permission can be used in foreground and background).| - -### FA Model - -For the apps based on the FA model, declare the required permissions in the **config.json** file. +### Stage Model -**Example** +If the application is based on the stage model, declare the permissions in [**module.json5**](../quick-start/module-configuration-file.md). ```json { "module" : { - "reqPermissions":[ + // ... + "requestPermissions":[ { "name" : "ohos.permission.PERMISSION1", "reason": "$string:reason", "usedScene": { - "ability": [ + "abilities": [ "FormAbility" ], "when":"inuse" @@ -63,7 +51,7 @@ For the apps based on the FA model, declare the required permissions in the **co "name" : "ohos.permission.PERMISSION2", "reason": "$string:reason", "usedScene": { - "ability": [ + "abilities": [ "FormAbility" ], "when":"always" @@ -74,21 +62,20 @@ For the apps based on the FA model, declare the required permissions in the **co } ``` -### Stage Model - -For the apps based on the stage model, declare the required permissions in the **module.json5** file. +### FA Model -**Example** +If the application is based on the FA model, declare the required permissions in **config.json**. ```json { "module" : { - "requestPermissions":[ + // ... + "reqPermissions":[ { "name" : "ohos.permission.PERMISSION1", "reason": "$string:reason", "usedScene": { - "abilities": [ + "ability": [ "FormAbility" ], "when":"inuse" @@ -98,7 +85,7 @@ For the apps based on the stage model, declare the required permissions in the * "name" : "ohos.permission.PERMISSION2", "reason": "$string:reason", "usedScene": { - "abilities": [ + "ability": [ "FormAbility" ], "when":"always" @@ -109,60 +96,152 @@ For the apps based on the stage model, declare the required permissions in the * } ``` -## Declaring the ACL - -The permission level of **ohos.permission.PERMISSION2** is **system_basic**, which is higher than the app's APL. In this case, use the ACL. +## Declaring Permissions in the ACL -In addition to declaring all the permissions in the configuration file, you must declare the permissions whose levels are higher that the app's APL in the app's profile. For details about the fields in the profile, see [HarmonyAppProvision Configuration File](../quick-start/app-provision-structure.md). +If an application of the **normal** level requires permissions corresponding to the **system_basic** or **system_core** level, you need to declare the required permissions in the ACL. -For example, declare the required permission in the **acls** field: +For example, if an application needs to access audio files of a user and capture screenshots, it requires the **ohos.permission.WRITE_AUDIO** permission (of the **system_basic** level) and the **ohos.permission.CAPTURE_SCREEN** permission (of the **system_core** level). In this case, you need to add the related permissions to the **acl** field in the [HarmonyAppProvision configuration file](app-provision-structure.md). ```json { - "acls": { - "allowed-acls": [ - "ohos.permission.PERMISSION2" - ] - } + // ... + "acls":{ + "allowed-acls":[ + "ohos.permission.WRITE_AUDIO", + "ohos.permission.CAPTURE_SCREEN" + ] + } } ``` -## Applying for the user_grant Permission - -After the permissions are declared, the system grants the system_grant permission during the installation of the app. The user_grant permission must be authorized by the user. +## Requesting User Authorization -Therefore, before allowing the app to call the API protected by the **ohos.permission.PERMISSION2** permission, the system needs to verify whether the app has the permission to do so. +If an application needs to access user privacy information or use system abilities, for example, accessing location or calendar information or using the camera to take photos or record videos, it must request the permission from users. A permission verification is performed first to determine whether the current invoker has the corresponding permission. If the application has not obtained that permission, a dialog box will be displayed to request user authorization. The following figure shows an example. + -If the verification result indicates that the app has the permission, the app can access the target API. Otherwise, the app needs to request user authorization and then proceeds based on the authorization result. For details, see [Access Control Overview](accesstoken-overview.md). +> **NOTE**
Each time before an API protected by a permission is accessed, the **requestPermissionsFromUser()** API will be called to request user authorization. After a permission is dynamically granted, the user may revoke the permission. Therefore, the previously granted authorization status cannot be persistent. -> **CAUTION** -> -> The permission authorized by a user is not permanent, because the user may revoke the authorization at any time. Each time before the API protected by the permission is called, call **requestPermissionsFromUser()** to request the permission. +### Stage Model -## Example +Example: Request the permission to read calendar information for an app. + +1. Apply for the **ohos.permission.READ_CALENDAR** permission. For details, see [Declaring Permissions in the Configuration File](#declaring-permissions-in-the-configuration-file). + +2. Call **requestPermissionsFromUser()** in the **onWindowStageCreate()** callback of the UIAbility to dynamically apply for the permission, or request user authorization on the UI based on service requirements. The return value of **requestPermissionsFromUser()** indicates whether the application has the target permission. If yes, the target API can be called normally. + + Request user authorization in UIAbility. + + ```typescript + import UIAbility from '@ohos.app.ability.UIAbility'; + import Window from '@ohos.window'; + import abilityAccessCtrl from '@ohos.abilityAccessCtrl'; + import { Permissions } from '@ohos.abilityAccessCtrl'; + + export default class EntryAbility extends UIAbility { + // ... + + onWindowStageCreate(windowStage: Window.WindowStage) { + // Main window is created, set main page for this ability + let context = this.context; + let AtManager = abilityAccessCtrl.createAtManager(); + // The return value of requestPermissionsFromUser determines whether to display a dialog box to request user authorization. + const permissions: Array = ['ohos.permission.READ_CALENDAR']; + AtManager.requestPermissionsFromUser(context, permissions).then((data) => { + console.info(`[requestPermissions] data: ${JSON.stringify(data)}`); + let grantStatus: Array = data.authResults; + if (grantStatus[0] === -1) { + // The authorization fails. + } else { + // The authorization is successful. + } + }).catch((err) => { + console.error(`[requestPermissions] Failed to start request permissions. Error: ${JSON.stringify(err)}`); + }) + + // ... + } + } + ``` + + Request user authorization on the UI. + ```typescript + import abilityAccessCtrl from '@ohos.abilityAccessCtrl'; + import { Permissions } from '@ohos.abilityAccessCtrl'; + import common from '@ohos.app.ability.common'; + + @Entry + @Component + struct Index { + reqPermissions() { + let context = getContext(this) as common.UIAbilityContext; + let AtManager = abilityAccessCtrl.createAtManager(); + // The return value of requestPermissionsFromUser determines whether to display a dialog box to request user authorization. + const permissions: Array = ['ohos.permission.READ_CALENDAR']; + AtManager.requestPermissionsFromUser(context, permissions).then((data) => { + console.info(`[requestPermissions] data: ${JSON.stringify(data)}`); + let grantStatus: Array = data.authResults; + if (grantStatus[0] === -1) { + // The authorization fails. + } else { + // The authorization is successful. + } + }).catch((err) => { + console.error(`[requestPermissions] Failed to start request permissions. Error: ${JSON.stringify(err)}`); + }) + } + + // Page display. + build() { + // ... + } + } + ``` -The procedure for requesting user authorization is as follows: +### FA Model -1. Obtain the ability context. -2. Call **requestPermissionsFromUser()** to request user authorization. The API determines whether to display a dialog box to request user authorization based on whether the app has the permission. -3. Check whether the app has the permission based on the return value. If the app has the permission, the API can be invoked. +Call [requestPermissionsFromUser()](../reference/apis/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7) to request user authorization. ```js - // OnWindowStageCreate of the ability - onWindowStageCreate() { - var context = this.context +// onWindowStageCreate() of Ability +onWindowStageCreate() { + let context = this.context; let array:Array = ["ohos.permission.PERMISSION2"]; - // requestPermissionsFromUser determines whether to display a dialog box based on the permission authorization status. + // The return value of requestPermissionsFromUser determines whether to display a dialog box to request user authorization. context.requestPermissionsFromUser(array).then(function(data) { - console.log("data type:" + typeof(data)); - console.log("data:" + data); - console.log("data permissions:" + data.permissions); - console.log("data result:" + data.authResults); + console.log("data:" + JSON.stringify(data)); + console.log("data permissions:" + JSON.stringify(data.permissions)); + console.log("data result:" + JSON.stringify(data.authResults)); }, (err) => { - console.error('Failed to start ability', err.code); + console.error('Failed to start ability', err.code); }); - } +} +``` +## Pre-Authorizing user_grant Permissions +By default, the **user_grant** permissions must be dynamically authorized by the user through a dialog box. However, for pre-installed apps, you can pre-authroize the permissions, for example, the **ohos.permission.MICROPHONE** permission, in the [**install_list_permission.json**](https://gitee.com/openharmony/vendor_hihope/blob/master/rk3568/preinstall-config/install_list_permissions.json) file to prevent the user authorization dialog box from being displayed. The **install_list_permissions.json** file is in the **/system/etc/app/** directory on a device. When the device is started, the **install_list_permissions.json** file is loaded. When the application is installed, the **user_grant** permissions in the file are granted. The **install_list_permissions.json** file contains the following fields: +- **bundleName**: bundle name of the application. +- `app_signature`: fingerprint information of the application. For details, see [Application Privilege Configuration Guide](../../device-dev/subsystems/subsys-app-privilege-config-guide.md#configuration-in-install-list-capabilityjson). +- **permissions**: **name** specifies the name of the **user_grant** permission to pre-authorize. **userCancellable** specifies whether the user can revoke the pre-authorization. The value **true** means the user can revoke the pre-authorization; the vaue **false** means the opposite. + +> **NOTE**
This file is available only for preinstalled applications. + +```json +[ + // ... + { + "bundleName": "com.example.myapplication", // Bundle Name. + "app_signature": ["****"], // Fingerprint information. + "permissions":[ + { + "name": "ohos.permission.PERMISSION_X", // Permission to pre-authorize. + "userCancellable": false // The user cannot revoke the authorization. + }, + { + "name": "ohos.permission.PERMISSION_X", // Permission to pre-authorize. + "userCancellable": true // The user can revoke the authorization. + } + ] + } +] ``` -> **NOTE**
-> For details about the APIs, see [AbilityContext](../reference/apis/js-apis-ability-context.md). + \ No newline at end of file diff --git a/en/application-dev/security/accesstoken-overview.md b/en/application-dev/security/accesstoken-overview.md index 9e8aa2a655ecdfbd3ebc4133230f12fb9cf46d67..e42543a356fb71dee1c6eea6e84a2115ca1518be 100644 --- a/en/application-dev/security/accesstoken-overview.md +++ b/en/application-dev/security/accesstoken-overview.md @@ -2,14 +2,14 @@ OpenHarmony AccessTokenManager (ATM) implements unified app permission management based on access tokens. -By default, apps can access limited system resources. However, in some cases, an app needs to access excess data (including personal data) and functions of the system or another app to implement extended functions. The system or apps must also explicitly share their data or functions through APIs. OpenHarmony uses app permissions to perform access control and prevent improper or malicious use of these data or functions. +By default, apps can access limited system resources. However, to provide extended features, an app may need to access excess data (including personal data) and functions of the system or another app. The system or apps must also explicitly share their data or functions through APIs. OpenHarmony uses app permissions to perform access control and prevent improper or malicious use of these data or functions. App permissions are used to protect the following objects: - Data: personal data (such as photos, contacts, calendar, and location), device data (such as device ID, camera, and microphone), and app data. - Functions: device functions (such as making calls, sending SMS messages, and connecting to the Internet) and app functions (such as displaying windows and creating shortcuts). -Without the required permissions, an app cannot access or perform operations on the target object. Permissions must be clearly defined for apps. With well-defined app permissions, the system can standardize the behavior of apps and protect user privacy. Before an app accesses the target object, the target object verifies the app's permissions and denies the access if the app does not have required permissions. +Without the required permissions, an app cannot access or perform operations on the target object. Permissions must be clearly defined for apps. With well-defined app permissions, the system can standardize app behavior and protect user privacy. Before an app accesses the target object, the target object verifies the app's permissions and denies the access if the app does not have required permissions. Currently, ATM verifies app permissions based on the token identity (token ID). A token ID identifies an app. ATM manages app permissions based on the app's token ID. @@ -17,13 +17,13 @@ Currently, ATM verifies app permissions based on the token identity (token ID). Observe the following principles for permission management: -- Provide clear description about the app functions and scenarios for each permission required by the app so that users can clearly know why and when these permissions are required. Do not induce or mislead users' authorization. The permissions on an app must comply with the description provided in the app. +- Provide clear description about the functions and scenarios for each permission required by the app so that users can clearly know why and when these permissions are needed. Do not induce or mislead users' authorization. The permissions on an app must comply with the description provided in the app. - Use the principle of least authority for user permissions. Allow only necessary permissions for service functions. - When an app is started for the first time, avoid frequently displaying dialog boxes to request multiple permissions. Allow the app to apply for the permission only when it needs to use the corresponding service function. - If a user rejects to grant a permission, the user can still use functions irrelevant to this permission and can register and access the app. - Provide no more message if a user rejects the authorization required by a function. Provide onscreen instructions to direct the user to grant the permission in **Settings** if the user triggers this function again or needs to use this function. -- All the permissions granted to apps must come from the [App Permission List](permission-list.md). Custom permissions are not allowed for apps currently. +- All the permissions granted to apps must come from the [App Permission List](permission-list.md). Custom permissions are not allowed currently. ## Permission Workflows @@ -50,7 +50,9 @@ The figure below illustrates the process. 3. A low-APL app can have a high-level permission by using the Access Control List (ACL). For details, see [ACL](#acl). ### Permission Verification -To protect sensitive data and eliminate security threads on core abilities, you can use the permissions in the [App Permission List](permission-list.md) to protect the related API from unauthorized calling. Each time before the API is called, a permission verification is performed to check whether the caller has the required permission. The API can be called only after the permission verification is successful. +To protect sensitive data and eliminate security threads on core abilities, you can use the permissions in the [App Permission List](permission-list.md) to protect an API from unauthorized calling. Each time before the API is called, a permission verification is performed to check whether the caller has the required permission. + +The API can be called only after the permission verification is successful. The figure below shows the permission verification process. @@ -58,7 +60,7 @@ The figure below shows the permission verification process. 1: An app permission can be used to control the access to an API that has sensitive data involved or security threats on the core abilities. -2: Select the permission from the [App Permission List](permission-list.md). For example, if contact information is involved in an API provided by an app, you can use the contact-related permissions to protect the API. +2: The API can be protected by a permission in the [ACL](#acl). For example, if contact information is involved in an API provided by an app, you can use the contact-related permissions to protect the API. 3: Use **verifyAccessToken()** to check whether the caller has the required permission. For details, see [Permission Verification Guide](permission-verify-guidelines.md). @@ -88,7 +90,7 @@ Then, use the [hapsigner](hapsigntool-overview.md) tool to generate a certificat The following is an example. -This example shows only the modification of the **apl** field. Set other fields based on your requirements. For details about the fields in the profile, see [HarmonyAppProvision Configuration File](../quick-start/app-provision-structure.md). +This example shows only the modification of the **apl** field. Set other fields based on your requirements. For details about the fields in the profile, see [HarmonyAppProvision Configuration File](app-provision-structure.md). ```json { @@ -123,7 +125,7 @@ The permissions open to apps vary with the permission level. The permission leve The system_core permission allows access to core resources of the OS. These resources are underlying core services of the system. If these resources are corrupted, the OS cannot run properly. - The system_core permissions are not open to third-party apps currently. + The system_core permissions are not open to third-party apps. ## Permission Types @@ -131,19 +133,19 @@ Permissions can be classified into the following types based on the authorizatio - **system_grant** - The app permissions are authorized by the system. This type of apps cannot access user or device sensitive information. The allowed operations have minor impact on the system or other apps. + The app permissions are authorized by the system. Apps granted with this type of permission cannot access user or device sensitive information, and the operations allowed for them have minor impact on the system or other apps. - For a system_grant app, the system automatically grants the required permissions to the app when the app is installed. The system_grant permission list must be presented to users on the details page of the app in the app store. + For a system_grant app, the system automatically grants the required permissions to the app when the app is installed. The system_grant permission list must be presented to users on the details page of the app in the app market. - **user_grant** - The app permissions must be authorized by users. This type of apps may access user or device sensitive information. The allowed operations may have a critical impact on the system or other apps. + The app permissions must be authorized by users. Apps granted with this type of permissions may access user or device sensitive information, and the operations allowed for them may have a critical impact on the system or other apps. This type of permissions must be declared in the app installation package and authorized by users dynamically during the running of the app. The app has the permission only after user authorization. - For example, in the [App Permission List](permission-list.md), the permissions for microphones and cameras are user_grant. The list provides reasons for using the permissions. + For example, as described in the [App Permission List](permission-list.md), the permissions for microphones and cameras are user_grant. The list provides reasons for using the permissions. - The user_grant permission list must also be presented on the details page of the app in the app store. + The user_grant permission list must also be presented on the details page of the app in the app market. ### Authorization Processes @@ -173,7 +175,7 @@ The procedure is as follows: **Precautions** - Check the app's permission each time before the operation requiring the permission is performed. -- To check whether a user has granted specific permissions to an app, use the [verifyAccessToken](../reference/apis/js-apis-abilityAccessCtrl.md) method. This method returns [PERMISSION_GRANTED](../reference/apis/js-apis-abilityAccessCtrl.md) or [PERMISSION_DENIED](../reference/apis/js-apis-abilityAccessCtrl.md). For details about the sample code, see [Access Control Development](accesstoken-guidelines.md). +- To check whether a user has granted specific permissions to an app, use the [verifyAccessToken](../reference/apis/js-apis-abilityAccessCtrl.md) API. This API returns [PERMISSION_GRANTED](../reference/apis/js-apis-abilityAccessCtrl.md) or [PERMISSION_DENIED](../reference/apis/js-apis-abilityAccessCtrl.md). For details about the sample code, see [Access Control Development](accesstoken-guidelines.md). - Users must be able to understand and control the authorization of user_grant permissions. During the running process, the app requiring user authorization must proactively call an API to dynamically request the authorization. Then, the system displays a dialog box asking the user to grant the permission. The user will determine whether to grant the permission based on the running context of the app. - The permission authorized is not permanent, because the user may revoke the authorization at any time. Therefore, even if the user has granted the requested permission to the app, the app must check for the permission before calling the API controlled by this permission. @@ -190,15 +192,15 @@ The APL of app A is **normal**. App A needs to have permission B (system_basic l In this case, you can use the ACL to grant permission B to app A. For details, see [Using the ACL](#using-the-acl). -For details about whether a permission can be enabled through the ACL, see the [App Permission List](permission-list.md). +For details about whether a permission can be enabled through the ACL, see [App Permission List](permission-list.md). ### Using the ACL -If the permission required by an app has higher level than the app's APL, you can use the ACL to grant the permission required. +If the permission required by an app has a higher level than the app's APL, you can use the ACL to grant the permission required. In addition to the preceding [authorization processes](#authorization-processes), you must declare the ACL. -That is, you need to declare the required permissions in the app's configuration file, and [declare the ACL](accesstoken-guidelines.md#declaring-the-acl) in the app's profile. The subsequent steps of authorization are the same. +That is, you need to declare the required permissions in the app's configuration file, and [declare the ACL](accesstoken-guidelines.md#declaring-permissions-in-the-acl) in the app's profile. The subsequent steps of authorization are the same. **NOTICE** @@ -216,4 +218,4 @@ When developing an app installation package, you must declare the ACL in the **a } ``` -For details about the fields in the profile, see [HarmonyAppProvision Configuration File](../quick-start/app-provision-structure.md). +For details about the fields in the profile, see [HarmonyAppProvision Configuration File](app-provision-structure.md). diff --git a/en/application-dev/quick-start/app-provision-structure.md b/en/application-dev/security/app-provision-structure.md similarity index 61% rename from en/application-dev/quick-start/app-provision-structure.md rename to en/application-dev/security/app-provision-structure.md index df74f5fc03327cfa876d0bc329b16ec1f26dc8cb..d31cd6c690769d9a3ec6767a7f8187f5d9bfc4e7 100644 --- a/en/application-dev/quick-start/app-provision-structure.md +++ b/en/application-dev/security/app-provision-structure.md @@ -4,19 +4,19 @@ The **HarmonyAppProvision** configuration file (also called profile) is the file ## Configuration File Internal Structure The **HarmonyAppProvision** file consists of several parts, which are described in the table below. -**Table 1** Internal structure of the HarmonyAppProvision file -| Name | Description | Data Type| Mandatory| Initial Value Allowed| +| Name | Description | Data Type| Yes | Initial Value Allowed| | ----------- | ---------------------------------------------------------------------------------------- | -------- | -------- | -------- | | version-code | Version number of the **HarmonyAppProvision** file format. The value is a positive integer containing 32 or less digits.| Number | Yes| No | | version-name | Description of the version number. It is recommended that the value consist of three segments, for example, **A.B.C**. | String | Yes| No| -| uuid | Unique ID of the **HarmonyAppProvision** file. | String | Yes| No| +| uuid | Unique ID of the **HarmonyAppProvision** file. | String | Yes | No| | type | Type of the **HarmonyAppProvision** file. The value can be **debug** (for application debugging) or **release** (for application release). The recommended value is **debug**.| String | Yes| No| -| issuer | Issuer of the **HarmonyAppProvision** file. | String | Yes| No| +| issuer | Issuer of the **HarmonyAppProvision** file. | String | Yes | No| | validity | Validity period of the **HarmonyAppProvision** file. For details, see [Internal Structure of the validity Object](#internal-structure-of-the-validity-object). | Object | Yes | No | -| bundle-info | Information about the application bundle and developer. For details, see [Internal Structure of the bundle-info Object](#internal-structure-of-the-bundle-info-object). | Object | Yes| No | -| acls | Information about the Access Control Lists (ACLs). For details, see [Internal Structure of the acls Object](#internal-structure-of-the-acls-object). | Object | No| No | -| permissions | Permissions required for your application. For details, see [Internal Structure of the permissions Object](#internal-structure-of-the-permissions-object). | Object | No| No | -| debug-info | Additional information for application debugging. For details, see [Internal Structure of the debug-info Object](#internal-structure-of-the-debug-info-object). | Object | No| No | +| bundle-info | Information about the application bundle and developer. For details, see [Internal Structure of the bundle-info Object](#internal-structure-of-the-bundle-info-object). | Object | Yes | No | +| acls | Information about the Access Control Lists (ACLs). For details, see [Internal Structure of the acls Object](#internal-structure-of-the-acls-object). | Object | No | Yes | +| permissions | Permissions required for your application. For details, see [Internal Structure of the permissions Object](#internal-structure-of-the-permissions-object). | Object | No | Yes | +| debug-info | Additional information for application debugging. For details, see [Internal Structure of the debug-info Object](#internal-structure-of-the-debug-info-object). | Object | No | Yes | +| app-privilege-capabilities | Privilege information required by the application bundle. For details, see the [Application Privilege Configuration Guide](../../device-dev/subsystems/subsys-app-privilege-config-guide.md). | String array| No | Yes | An example of the **HarmonyAppProvision** file is as follows: ```json @@ -47,6 +47,7 @@ An example of the **HarmonyAppProvision** file is as follows: "device-id-type": "udid", "device-ids": ["string"] }, + "app-privilege-capabilities":["AllowAppUsePrivilegeExtension"], "issuer": "OpenHarmony" } @@ -54,46 +55,57 @@ An example of the **HarmonyAppProvision** file is as follows: ### Internal Structure of the validity Object -| Name | Description | Data Type| Mandatory| Initial Value Allowed| + +| Name | Description | Data Type| Mandatory | Initial Value Allowed| | ---------- | ------------------------------- | ------- | ------- | --------- | | not-before | Start time of the file validity period. The value is a Unix timestamp, which is a non-negative integer.| Number | Yes| No | | not-after | End time of the file validity period. The value is a Unix timestamp, which is a non-negative integer.| Number | Yes| No | ### Internal Structure of the bundle-info Object -| Name | Description | Data Type| Mandatory| Initial Value Allowed| + +| Name | Description | Data Type| Mandatory | Initial Value Allowed| | ------------------------ | ------------------------------- | ------- | -------- | --------- | -| developer-id | Unique ID of the developer.| String | Yes| No | -| development-certificate | Information about the [debug certificate](../security/hapsigntool-guidelines.md).| Number | Yes if **type** is set to **debug** and no otherwise | No | -| distribution-certificate | Information about the [release certificate](../security/hapsigntool-guidelines.md).| Number | Yes if **type** is set to **release** and no otherwise| No | -| bundle-name | Bundle name of the application.| String | Yes| No | -| apl | [Ability privilege level (APL)](../security/accesstoken-overview.md) of your application. The value can be **normal**, **system_basic**, or **system_core**.| String | Yes| No | -| app-feature | Type of your application. The value can be **hos_system_app** (system application) or **hos_normal_app** (non-system application).| String | Yes| No | +| developer-id | Unique ID of the developer.| String | Yes | No | +| development-certificate | Information about the [debug certificate](hapsigntool-guidelines.md).| Number | Yes if **type** is set to **debug** and no otherwise | No | +| distribution-certificate | Information about the [release certificate](hapsigntool-guidelines.md).| Number | Yes if **type** is set to **release** and no otherwise| No | +| bundle-name | Bundle name of the application.| String | Yes | No | +| apl | [Ability privilege level (APL)](accesstoken-overview.md) of your application. The value can be **normal**, **system_basic**, or **system_core**.| String | Yes | No | +| app-feature | Type of your application. The value can be **hos_system_app** (system application) or **hos_normal_app** (normal application). Only system applications are allowed to call system APIs. If a normal application calls a system API, the call cannot be successful or the application may run abnormally.| String | Yes | No | ### Internal Structure of the acls Object -The **acls** object contains the [ACLs](../security/accesstoken-overview.md) configured for your application. It should be noted that you still need to fill the ACL information in the **reqPermissions** attribute in the [config.json](package-structure.md) file. - -**Table 4** Internal structure of the acls object +The **acls** object contains the [ACL](accesstoken-overview.md) configured for your application. It should be noted that you still need to add the ACL information to the **requestPermissions** attribute in the application configuration file. -| Name | Description | Data Type| Mandatory| Initial Value Allowed| +| Name | Description | Data Type| Mandatory | Initial Value Allowed| | ------------------------ | ------------------------------- | ------- | ------- | --------- | | allowed-acls | [ACLs](../security/accesstoken-overview.md) configured for your application.| String array | No| No | ### Internal Structure of the permissions Object -The **permissions** object contains restricted permissions required for your application. Different from the ACLs set in the **acls** object, these permissions need user authorization during the running of your application. It should be noted that you still need to fill the permission information in the **reqPermissions** attribute in the [config.json](package-structure.md) file. +The **permissions** object contains restricted permissions required for your application. Different from the ACLs set in the **acls** object, these permissions need user authorization during the running of your application. It should be noted that you still need to add the ACL information to the **requestPermissions** attribute in the application configuration file. -**Table 5** Internal structure of the permissions object - -| Name | Description | Data Type| Mandatory| Initial Value Allowed| +| Name | Description | Data Type| Mandatory | Initial Value Allowed| | ------------------------ | ------------------------------- | ------- | ------- | --------- | -| restricted-permissions | [Restricted permissions](../security/accesstoken-overview.md) required for your application.| String array | No| No | +| restricted-permissions | [Restricted permissions](accesstoken-overview.md) required for your application.| String array | No | No | ### Internal Structure of the debug-info Object The **debug-info** object contains debugging information of your application, mainly device management and control information. -**Table 6** Internal structure of the debug-info object - -| Name | Description | Data Type| Mandatory| Initial Value Allowed| +| Name | Description | Data Type| Mandatory | Initial Value Allowed| | ------------------------ | ------------------------------- | ------- | ------- | --------- | -| device-id-type | Type of the device ID. Currently, only the udid type is supported.| String | No| No | -| device-ids | IDs of devices on which your application can be debugged.| String array | No| No | +| device-id-type | Type of the device ID. Currently, only the udid type is supported.| String | No | No | +| device-ids | IDs of devices on which your application can be debugged.| String array | Optional| No | + +## Modifying the HarmonyAppProvision Configuration File + +When a development project is created, the default application type is **hos_normal_app** and the default APL level is **normal**. + +To enable the application to use system APIs, you need to change the **app-feature** field to **hos_system_app** (system application). To apply for high-level permissions, you need to modify fields such as **apl** and **acl**. For details, see [Access Control Overview](accesstoken-overview.md). + + +To modify the HarmonyAppProvision configuration file, perform the following steps: + +1. Open the directory where the OpenHarmony SDK is located. (You can choose **File** > **Settings** > **OpenHarmony SDK** on the menu bar of DevEco Studio to query the directory.) +2. In the SDK directory, go to the **Toolchains** > {Version} > **lib** directory and open the **UnsgnedReleasedProfileTemplate.json** file. +3. Modify the related fields as required. + +After modifying the configuration file, [sign the application](hapsigntool-guidelines.md). diff --git a/en/application-dev/security/figures/permission-read_calendar.png b/en/application-dev/security/figures/permission-read_calendar.png new file mode 100644 index 0000000000000000000000000000000000000000..8236bcf2f28531c88362f1210cf70101740394bf Binary files /dev/null and b/en/application-dev/security/figures/permission-read_calendar.png differ diff --git a/en/application-dev/ui/js-framework-resource-restriction.md b/en/application-dev/ui/js-framework-resource-restriction.md index 6e171b3b42fafc7cf778799ae5cc32a0f4eeddd3..7af4d2d06d10b2ab50e907cf0ca7bb90bebef0a7 100644 --- a/en/application-dev/ui/js-framework-resource-restriction.md +++ b/en/application-dev/ui/js-framework-resource-restriction.md @@ -45,10 +45,10 @@ You can use the $r syntax in the application development files .hml and .js to f Example of res-defaults.json:
-``` +```json { - strings: { - hello: 'hello world' + "strings": { + "hello": "hello world" } } ``` @@ -57,7 +57,7 @@ Example of res-defaults.json:
resources/res-dark.json: -``` +```json { "image": { "clockFace": "common/dark_face.png" @@ -70,7 +70,7 @@ resources/res-dark.json: resources/res-defaults.json: -``` +```json { "image": { "clockFace": "common/face.png" @@ -81,7 +81,7 @@ resources/res-defaults.json: } ``` -``` +```html
diff --git a/en/application-dev/ui/js-framework-syntax-js.md b/en/application-dev/ui/js-framework-syntax-js.md index 89d85d5814100080b40c0279ee787586c6545a9d..0450f6991483ac42bada328c9bab0b1266da44a5 100644 --- a/en/application-dev/ui/js-framework-syntax-js.md +++ b/en/application-dev/ui/js-framework-syntax-js.md @@ -13,7 +13,7 @@ The ES6 syntax is supported. Import functionality modules. ```js - import router from '@system.router'; + import router from '@ohos.router'; ``` - Code reference diff --git a/en/application-dev/ui/ui-js-animate-svg.md b/en/application-dev/ui/ui-js-animate-svg.md index 815e0b619bc2f337957aad6bd9fb4e92b40a99b7..ad811ea02b8f0ad5d540e5ef41fcdcb8759e0ab3 100644 --- a/en/application-dev/ui/ui-js-animate-svg.md +++ b/en/application-dev/ui/ui-js-animate-svg.md @@ -62,7 +62,7 @@ In the [animateMotion](../reference/arkui-js/js-components-svg-animatemotion.md) ## animateTransform Animation -In the [animateMotion](../reference/arkui-js/js-components-svg-animatetransform.md) child component of the **\** component, set attributeName to bind the corresponding attribute to the **transform** attribute, and set **type** to the animation type, **from** to the start value, and **to** to the end value. +In the [animateTransform](../reference/arkui-js/js-components-svg-animatetransform.md) child component of the **\** component, set attributeName to bind the corresponding attribute to the **transform** attribute, and set **type** to the animation type, **from** to the start value, and **to** to the end value. ```html diff --git a/en/application-dev/ui/ui-js-animate-transform.md b/en/application-dev/ui/ui-js-animate-transform.md index 202e2ad96201bfd3e2273dd9841000378cd50f85..29882f56200d45615534142f4b2fdcac60a0c77b 100644 --- a/en/application-dev/ui/ui-js-animate-transform.md +++ b/en/application-dev/ui/ui-js-animate-transform.md @@ -6,7 +6,7 @@ Set the transform attribute for component rotation, scaling, translation, and sk ## Designing Static Animation -Create a square and rotate it by 90 degrees to form a rhombus. Cover the lower part of the rhombus with a rectangle to form a roof. Set the translate attribute of the rectangle to the coordinate (150px, -150px) to form a door, use the position attribute to translate the horizontal and vertical axes to the specified coordinates of the parent component (square), set the scale attribute to scale up the parent and child components together to determine the window size, and use the skewX attribute to skew the component and set the coordinate translate(200px,-830px) to form a chimney. +Create a square and rotate it by 90 degrees to form a rhombus. Cover the lower part of the rhombus with a rectangle to form a roof. Set the **translate** attribute of the rectangle to the coordinate (150px, -150px) to form a door, use the **position** attribute to translate the horizontal and vertical axes to the specified coordinates of the parent component (square), set the **scale** attribute to scale up the parent and child components together to determine the window size, and use the **skewX** attribute to skew the component and set the coordinate translate(200px,-830px) to form a chimney. ```html @@ -174,7 +174,7 @@ Decrease the y-coordinate over a time frame to make the ball bounce back. Gradua ## Designing Rotation Animation -Set the rotation center around an element in different transform-origin positions. Of the rotate3d values, the first three values are the rotation vectors of the x-axis, y-axis, and z-axis, respectively; the fourth value is the rotation angle, which can be a negative value to indicate that the rotation is performed counterclockwise. +Set the rotation center around an element in different transform-origin positions. Of the **rotate3d** values, the first three values are the rotation vectors of the x-axis, y-axis, and z-axis, respectively; the fourth value is the rotation angle, which can be a negative value to indicate that the rotation is performed counterclockwise. ```html @@ -222,7 +222,7 @@ Set the rotation center around an element in different transform-origin position } .rect3 { background-color: #6081f7; - /* Chhange the origin position.*/ + /* Change the origin position.*/ transform-origin: right bottom; } @keyframes rotate { @@ -304,15 +304,16 @@ Set the rotation center around an element in different transform-origin position ![en-us_image_0000001222807776](figures/en-us_image_0000001222807776.gif) -> **NOTE**
-> transform-origin specifies the origin of an element's transformation. If only one value is set, the other value is 50%. If both values are set, the first value indicates the position on the x-axis, and the second value indicates the position on the y-axis. +> **NOTE** +> +> **transform-origin** specifies the origin of an element's transformation. If only one value is set, the other value is 50%. If both values are set, the first value indicates the position on the x-axis, and the second value indicates the position on the y-axis. ## Designing Scaling Animation This example implements a ripple animation with the scale attribute. Here is the overall procedure: First, use the positioning function to determine the coordinates of the element's position. Then, create multiple components to achieve the overlapping effect. After that, set the opacity attribute to hide or display the components. To scale and hide/display a component at the same time, set both the scale and opacity attributes. Finally, set different animation durations for different components to achieve the diffusion effect. -Set the scaling values for the x-axis, y-axis, and z-axis in scale3d to implement the animation. +Set the scaling values for the x-axis, y-axis, and z-axis in **scale3d** to implement the animation. ```html @@ -419,7 +420,7 @@ text{ > **NOTE** > -> After the transform attributes are set, the child element changes with the parent element. Value changing of other attributes (such as height and width) of the parent element will not affect the child element. +> After the **transform** attributes are set, the child element changes with the parent element. Value changing of other attributes (such as height and width) of the parent element will not affect the child element. ## Setting matrix @@ -467,9 +468,9 @@ The matrix attribute defines a transformation matrix with six input parameters: ![en-us_image_0000001267767853](figures/en-us_image_0000001267767853.gif) -## Integrating Transform Attributes +## Integrating transform Attributes -You can set multiple transform attributes at the same time to apply different transformations to a component. The following example applies the scale, translate, and rotate attributes simultaneously. +You can set multiple **transform** attributes at the same time to apply different transformations to a component. The following example applies the **scale**, **translate**, and **rotate** attributes simultaneously. ```html @@ -578,8 +579,8 @@ You can set multiple transform attributes at the same time to apply different tr > **NOTE** > -> - When multiple transform attributes are set, the later one overwrites the previous one. To apply multiple transform styles at the same time, use the shorthand notation; that is, write multiple style values in one transform, for example, transform: scale(1) rotate(0) translate(0,0). +> - When multiple **transform** attributes are set, the later one overwrites the previous one. To apply multiple transform styles at the same time, use the shorthand notation; that is, write multiple style values in one transform, for example, transform: scale(1) rotate(0) translate(0,0). > -> - When using the shorthand notion, note that the animation effect varies according to the sequence of the style values. +> - When using the shorthand notation, note that the animation effect varies according to the sequence of the style values. > -> - The style values in the transform attribute used when the animation starts and ends must be in one-to-one mapping. Only the styles that have value mappings are played. \ No newline at end of file +> - The style values in the **transform** attribute used when the animation starts and ends must be in one-to-one mapping. Only the styles that have value mappings are played. \ No newline at end of file diff --git a/en/application-dev/ui/ui-js-component-tabs.md b/en/application-dev/ui/ui-js-component-tabs.md index 8fe90f809bd4e428da0dfc117b0f667849b577ab..1099ff21b8556e73b99e7b722689b51745de3123 100644 --- a/en/application-dev/ui/ui-js-component-tabs.md +++ b/en/application-dev/ui/ui-js-component-tabs.md @@ -16,7 +16,7 @@ Create a **<tabs>** component in the .hml file under **pages/index**. item1 item2 - +
content1
@@ -36,6 +36,10 @@ Create a **<tabs>** component in the .hml file under **pages/index**. align-items: center; background-color: #F1F3F5; } +.tabContent{ + width: 100%; + height: 100%; +} .text{ width: 100%; height: 100%; @@ -179,10 +183,10 @@ Add the **change** event for the **<tabs>** component to display the index ```js // xxx.js -import prompt from '@system.prompt'; +import promptAction from '@ohos.promptAction'; export default { tabChange(e){ - prompt.showToast({ + promptAction.showToast({ message: "Tab index: " + e.index }) } @@ -269,7 +273,7 @@ background-color:#F1F3F5; ```js // xxx.js -import prompt from '@system.prompt'; +import promptAction from '@ohos.promptAction'; export default { data() { return { diff --git a/en/application-dev/ui/ui-js-components-button.md b/en/application-dev/ui/ui-js-components-button.md index b543a415b84bbfb56248be1249d7bb5aeceda799..b06939fc09af8898fc736f7be7147ff3374aa84a 100644 --- a/en/application-dev/ui/ui-js-components-button.md +++ b/en/application-dev/ui/ui-js-components-button.md @@ -121,7 +121,7 @@ Add the **progress** method to the **\