提交 1de6ee7a 编写于 作者: M mgceshuang 提交者: Gitee

Merge branch 'master' of gitee.com:openharmony/docs into master

Signed-off-by: Nmgceshuang <mashuang13@huawei.com>

要显示的变更太多。

To preserve performance only 1000 of 1000+ files are displayed.
...@@ -338,7 +338,7 @@ zh-cn/application-dev/reference/apis/js-apis-distributedMissionManager.md @chenm ...@@ -338,7 +338,7 @@ zh-cn/application-dev/reference/apis/js-apis-distributedMissionManager.md @chenm
zh-cn/application-dev/reference/apis/js-apis-document.md @panqinxu @zengyawen @bubble_mao @jinhaihw zh-cn/application-dev/reference/apis/js-apis-document.md @panqinxu @zengyawen @bubble_mao @jinhaihw
zh-cn/application-dev/reference/apis/js-apis-effectKit.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee zh-cn/application-dev/reference/apis/js-apis-effectKit.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee
zh-cn/application-dev/reference/apis/js-apis-emitter.md @jayleehw @RayShih @li-weifeng2 @currydavids zh-cn/application-dev/reference/apis/js-apis-emitter.md @jayleehw @RayShih @li-weifeng2 @currydavids
zh-cn/application-dev/reference/apis/js-apis-EnterpriseAdminExtensionAbility.md @Buda-Liu @ningningW @budda-wang @yangqing3 zh-cn/application-dev/reference/apis/js-apis-EnterpriseAdminExtensionAbility.md @liuzuming @ningningW @yangqing3
zh-cn/application-dev/reference/apis/js-apis-environment.md @panqinxu @zengyawen @bubble_mao @jinhaihw zh-cn/application-dev/reference/apis/js-apis-environment.md @panqinxu @zengyawen @bubble_mao @jinhaihw
zh-cn/application-dev/reference/apis/js-apis-errorManager.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen zh-cn/application-dev/reference/apis/js-apis-errorManager.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen
zh-cn/application-dev/reference/apis/js-apis-eventhub.md @jayleehw @RayShih @li-weifeng2 @currydavids zh-cn/application-dev/reference/apis/js-apis-eventhub.md @jayleehw @RayShih @li-weifeng2 @currydavids
...@@ -384,7 +384,7 @@ zh-cn/application-dev/reference/apis/js-apis-lightweightmap.md @gongjunsong @ge- ...@@ -384,7 +384,7 @@ zh-cn/application-dev/reference/apis/js-apis-lightweightmap.md @gongjunsong @ge-
zh-cn/application-dev/reference/apis/js-apis-lightweightset.md @gongjunsong @ge-yafang @flyingwolf @BlackStone zh-cn/application-dev/reference/apis/js-apis-lightweightset.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
zh-cn/application-dev/reference/apis/js-apis-linkedlist.md @gongjunsong @ge-yafang @flyingwolf @BlackStone zh-cn/application-dev/reference/apis/js-apis-linkedlist.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
zh-cn/application-dev/reference/apis/js-apis-list.md @gongjunsong @ge-yafang @flyingwolf @BlackStone zh-cn/application-dev/reference/apis/js-apis-list.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
zh-cn/application-dev/reference/apis/js-apis-logs.md @huaweimaxuchu @ningningW @niulihua @tomatodevboy zh-cn/application-dev/reference/apis/js-apis-logs.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
zh-cn/application-dev/reference/apis/js-apis-media.md @liuyuehua1 @zengyawen @xxb-wzy @currydavids zh-cn/application-dev/reference/apis/js-apis-media.md @liuyuehua1 @zengyawen @xxb-wzy @currydavids
zh-cn/application-dev/reference/apis/js-apis-medialibrary.md @panqinxu @zengyawen @bubble_mao @jinhaihw zh-cn/application-dev/reference/apis/js-apis-medialibrary.md @panqinxu @zengyawen @bubble_mao @jinhaihw
zh-cn/application-dev/reference/apis/js-apis-mediaquery.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy zh-cn/application-dev/reference/apis/js-apis-mediaquery.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy
...@@ -397,7 +397,7 @@ zh-cn/application-dev/reference/apis/js-apis-notification.md @jayleehw @RayShih ...@@ -397,7 +397,7 @@ zh-cn/application-dev/reference/apis/js-apis-notification.md @jayleehw @RayShih
zh-cn/application-dev/reference/apis/js-apis-observer.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 zh-cn/application-dev/reference/apis/js-apis-observer.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785
zh-cn/application-dev/reference/apis/js-apis-osAccount.md @nianCode @zengyawen @JiDong-CS @murphy1984 zh-cn/application-dev/reference/apis/js-apis-osAccount.md @nianCode @zengyawen @JiDong-CS @murphy1984
zh-cn/application-dev/reference/apis/js-apis-particleAbility.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen zh-cn/application-dev/reference/apis/js-apis-particleAbility.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen
zh-cn/application-dev/reference/apis/js-apis-pasteboard.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 zh-cn/application-dev/reference/apis/js-apis-pasteboard.md @han-zhengshi @ge-yafang @logic42
zh-cn/application-dev/reference/apis/js-apis-permissionrequestresult.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen zh-cn/application-dev/reference/apis/js-apis-permissionrequestresult.md @littlejerry1 @RayShih @gwang2008 @chengxingzhen
zh-cn/application-dev/reference/apis/js-apis-plainarray.md @gongjunsong @ge-yafang @flyingwolf @BlackStone zh-cn/application-dev/reference/apis/js-apis-plainarray.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
zh-cn/application-dev/reference/apis/js-apis-pointer.md @yuanxinying @ningningW @cococoler @alien0208 zh-cn/application-dev/reference/apis/js-apis-pointer.md @yuanxinying @ningningW @cococoler @alien0208
...@@ -415,7 +415,7 @@ zh-cn/application-dev/reference/apis/js-apis-resource-manager.md @Buda-Liu @ning ...@@ -415,7 +415,7 @@ zh-cn/application-dev/reference/apis/js-apis-resource-manager.md @Buda-Liu @ning
zh-cn/application-dev/reference/apis/js-apis-router.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy zh-cn/application-dev/reference/apis/js-apis-router.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy
zh-cn/application-dev/reference/apis/js-apis-rpc.md @xuepianpian @RayShih @zhaopeng_gitee @vagrant_world zh-cn/application-dev/reference/apis/js-apis-rpc.md @xuepianpian @RayShih @zhaopeng_gitee @vagrant_world
zh-cn/application-dev/reference/apis/js-apis-runninglock.md @aqxyjay @zengyawen @aqxyjay @alien0208 zh-cn/application-dev/reference/apis/js-apis-runninglock.md @aqxyjay @zengyawen @aqxyjay @alien0208
zh-cn/application-dev/reference/apis/js-apis-screen-lock.md @feng-aiwen @ningningW @wangzhangjun @murphy1984
zh-cn/application-dev/reference/apis/js-apis-screen.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee zh-cn/application-dev/reference/apis/js-apis-screen.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee
zh-cn/application-dev/reference/apis/js-apis-screenshot.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee zh-cn/application-dev/reference/apis/js-apis-screenshot.md @zhangqiang183 @ge-yafang @zhouyaoying @zxg-gitee
zh-cn/application-dev/reference/apis/js-apis-securityLabel.md @panqinxu @zengyawen @bubble_mao @jinhaihw zh-cn/application-dev/reference/apis/js-apis-securityLabel.md @panqinxu @zengyawen @bubble_mao @jinhaihw
...@@ -435,6 +435,7 @@ zh-cn/application-dev/reference/apis/js-apis-system-bluetooth.md @cheng_guohong ...@@ -435,6 +435,7 @@ zh-cn/application-dev/reference/apis/js-apis-system-bluetooth.md @cheng_guohong
zh-cn/application-dev/reference/apis/js-apis-system-brightness.md @aqxyjay @zengyawen @aqxyjay @alien0208 zh-cn/application-dev/reference/apis/js-apis-system-brightness.md @aqxyjay @zengyawen @aqxyjay @alien0208
zh-cn/application-dev/reference/apis/js-apis-system-cipher.md @gaoyong @zengyawen @niejiteng @jumozhanjiang zh-cn/application-dev/reference/apis/js-apis-system-cipher.md @gaoyong @zengyawen @niejiteng @jumozhanjiang
zh-cn/application-dev/reference/apis/js-apis-system-configuration.md @Buda-Liu @ningningW @budda-wang @tomatodevboy zh-cn/application-dev/reference/apis/js-apis-system-configuration.md @Buda-Liu @ningningW @budda-wang @tomatodevboy
zh-cn/application-dev/reference/apis/js-apis-system-date-time.md @feng-aiwen @ningningW @illybyy @murphy1984
zh-cn/application-dev/reference/apis/js-apis-system-device.md @mupceet @zengyawen @handyohos @nan-xiansen zh-cn/application-dev/reference/apis/js-apis-system-device.md @mupceet @zengyawen @handyohos @nan-xiansen
zh-cn/application-dev/reference/apis/js-apis-system-fetch.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 zh-cn/application-dev/reference/apis/js-apis-system-fetch.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785
zh-cn/application-dev/reference/apis/js-apis-system-file.md @panqinxu @zengyawen @bubble_mao @jinhaihw zh-cn/application-dev/reference/apis/js-apis-system-file.md @panqinxu @zengyawen @bubble_mao @jinhaihw
...@@ -455,7 +456,7 @@ zh-cn/application-dev/reference/apis/js-apis-system-vibrate.md @hellohyh001 @nin ...@@ -455,7 +456,7 @@ zh-cn/application-dev/reference/apis/js-apis-system-vibrate.md @hellohyh001 @nin
zh-cn/application-dev/reference/apis/js-apis-telephony-data.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785 zh-cn/application-dev/reference/apis/js-apis-telephony-data.md @zhang-hai-feng @zengyawen @jyh926 @gaoxi785
zh-cn/application-dev/reference/apis/js-apis-testRunner.md @inter515 @littlejerry1 @RayShih @inter515 @jiyong zh-cn/application-dev/reference/apis/js-apis-testRunner.md @inter515 @littlejerry1 @RayShih @inter515 @jiyong
zh-cn/application-dev/reference/apis/js-apis-thermal.md @aqxyjay @zengyawen @aqxyjay @alien0208 zh-cn/application-dev/reference/apis/js-apis-thermal.md @aqxyjay @zengyawen @aqxyjay @alien0208
zh-cn/application-dev/reference/apis/js-apis-timer.md @huaweimaxuchu @HelloCrease @niulihua @tomatodevboy zh-cn/application-dev/reference/apis/js-apis-timer.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
zh-cn/application-dev/reference/apis/js-apis-touchevent.md @mayunteng_1 @ningningW @cococoler @alien0208 zh-cn/application-dev/reference/apis/js-apis-touchevent.md @mayunteng_1 @ningningW @cococoler @alien0208
zh-cn/application-dev/reference/apis/js-apis-treemap.md @gongjunsong @ge-yafang @flyingwolf @BlackStone zh-cn/application-dev/reference/apis/js-apis-treemap.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
zh-cn/application-dev/reference/apis/js-apis-treeset.md @gongjunsong @ge-yafang @flyingwolf @BlackStone zh-cn/application-dev/reference/apis/js-apis-treeset.md @gongjunsong @ge-yafang @flyingwolf @BlackStone
...@@ -520,7 +521,7 @@ zh-cn/application-dev/reference/apis/js-apis-bundleManager.md @shuaytao @RayShih ...@@ -520,7 +521,7 @@ zh-cn/application-dev/reference/apis/js-apis-bundleManager.md @shuaytao @RayShih
zh-cn/application-dev/reference/apis/js-apis-bundleMonitor.md @shuaytao @RayShih @wangzhen107 @inter515 zh-cn/application-dev/reference/apis/js-apis-bundleMonitor.md @shuaytao @RayShih @wangzhen107 @inter515
zh-cn/application-dev/reference/apis/js-apis-colorSpaceManager.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee zh-cn/application-dev/reference/apis/js-apis-colorSpaceManager.md @zhangqiang183 @ge-yafang @wind_zj @zxg-gitee
zh-cn/application-dev/reference/apis/js-apis-commonEventManager.md @jayleehw @RayShih @li-weifeng2 @currydavids zh-cn/application-dev/reference/apis/js-apis-commonEventManager.md @jayleehw @RayShih @li-weifeng2 @currydavids
zh-cn/application-dev/reference/apis/js-apis-configPolicy.md @Buda-Liu @ningningW @budda-wang @yangqing3 zh-cn/application-dev/reference/apis/js-apis-configPolicy.md @liuzuming @ningningW @yangqing3
zh-cn/application-dev/reference/apis/js-apis-cooperate.md @yuanxinying @ningningW @cococoler @alien0208 zh-cn/application-dev/reference/apis/js-apis-cooperate.md @yuanxinying @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-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-cert.md @gaoyong @zengyawen @niejiteng @jumozhanjiang
...@@ -528,8 +529,14 @@ zh-cn/application-dev/reference/apis/js-apis-curve.md @huaweimaxuchu @HelloCreas ...@@ -528,8 +529,14 @@ zh-cn/application-dev/reference/apis/js-apis-curve.md @huaweimaxuchu @HelloCreas
zh-cn/application-dev/reference/apis/js-apis-defaultAppManager.md @shuaytao @RayShih @wangzhen107 @inter515 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 zh-cn/application-dev/reference/apis/js-apis-distributedBundle.md @shuaytao @RayShih @wangzhen107 @inter515
zh-cn/application-dev/reference/apis/js-apis-distributedKVStore.md @feng-aiwen @ge-yafang @gong-a-shi @logic42 zh-cn/application-dev/reference/apis/js-apis-distributedKVStore.md @feng-aiwen @ge-yafang @gong-a-shi @logic42
zh-cn/application-dev/reference/apis/js-apis-enterprise-adminManager.md @Buda-Liu @ningningW @budda-wang @yangqing3 zh-cn/application-dev/reference/apis/js-apis-enterprise-accountManager.md @liuzuming @ningningW @yangqing3
zh-cn/application-dev/reference/apis/js-apis-enterprise-dateTimeManager.md @Buda-Liu @ningningW @budda-wang @yangqing3 zh-cn/application-dev/reference/apis/js-apis-enterprise-adminManager.md @liuzuming @ningningW @yangqing3
zh-cn/application-dev/reference/apis/js-apis-enterprise-bundleManager.md @liuzuming @ningningW @yangqing3
zh-cn/application-dev/reference/apis/js-apis-enterprise-dateTimeManager.md @liuzuming @ningningW @yangqing3
zh-cn/application-dev/reference/apis/js-apis-enterprise-deviceControl.md @liuzuming @ningningW @yangqing3
zh-cn/application-dev/reference/apis/js-apis-enterprise-deviceInfo.md @liuzuming @ningningW @yangqing3
zh-cn/application-dev/reference/apis/js-apis-enterprise-networkManager.md @liuzuming @ningningW @yangqing3
zh-cn/application-dev/reference/apis/js-apis-enterprise-wifiManager.md @liuzuming @ningningW @yangqing3
zh-cn/application-dev/reference/apis/js-apis-fileAccess.md @panqinxu @zengyawen @bubble_mao @jinhaihw zh-cn/application-dev/reference/apis/js-apis-fileAccess.md @panqinxu @zengyawen @bubble_mao @jinhaihw
zh-cn/application-dev/reference/apis/js-apis-fileExtensionInfo.md @panqinxu @zengyawen @bubble_mao @jinhaihw zh-cn/application-dev/reference/apis/js-apis-fileExtensionInfo.md @panqinxu @zengyawen @bubble_mao @jinhaihw
zh-cn/application-dev/reference/apis/js-apis-freeInstall.md @shuaytao @RayShih @wangzhen107 @inter515 zh-cn/application-dev/reference/apis/js-apis-freeInstall.md @shuaytao @RayShih @wangzhen107 @inter515
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
- master:最新开发版本。 - master:最新开发版本。
- OpenHarmony 3.2 Beta5版本:点击[此处](zh-cn/release-notes/OpenHarmony-v3.2-beta5.md)了解版本详情。 - OpenHarmony 3.2 Release版本:点击[此处](zh-cn/release-notes/OpenHarmony-v3.2-release.md)了解版本详情。
- OpenHarmony 3.1 Release版本:点击[此处](zh-cn/release-notes/OpenHarmony-v3.1-release.md)了解版本详情。 - OpenHarmony 3.1 Release版本:点击[此处](zh-cn/release-notes/OpenHarmony-v3.1-release.md)了解版本详情。
......
...@@ -127,7 +127,7 @@ The following table describes the subsystems of OpenHarmony. For details about t ...@@ -127,7 +127,7 @@ The following table describes the subsystems of OpenHarmony. For details about t
| Build | Provides a compilation and building framework based on Generate Ninja (GN) and Ninja. | All systems | | Build | Provides a compilation and building framework based on Generate Ninja (GN) and Ninja. | All systems |
| Test | The test-driven development mode is used during the development process. You can develop new cases or modify existing cases to test new or enhanced system features. The test helps you develop high-quality code in the development phase.| All systems | | Test | The test-driven development mode is used during the development process. You can develop new cases or modify existing cases to test new or enhanced system features. The test helps you develop high-quality code in the development phase.| All systems |
| Data Management | Provides local data management and distributed data management:<br>- Local application data management for lightweight preference databases and relational databases<br>- Distributed data service to provide applications with the capability to store data in the databases of different devices| Standard system | | Data Management | Provides local data management and distributed data management:<br>- Local application data management for lightweight preference databases and relational databases<br>- Distributed data service to provide applications with the capability to store data in the databases of different devices| Standard system |
| Programming Language Runtime| Provides the compilation and execution environment for programs developed with JavaScript or C/C++, basic libraries that support the runtime, and the runtime-associated APIs, compilers, and auxiliary tools.| All systems | | Compiler and Runtime | Provides the compilation and execution environment for programs developed with JavaScript or C/C++, basic libraries that support the runtime, and the runtime-associated APIs, compilers, and auxiliary tools.| All systems |
| Distributed Scheduler| Starts, registers, queries, and manages system services. | All systems | | Distributed Scheduler| Starts, registers, queries, and manages system services. | All systems |
| JS UI Framework | OpenHarmony JS UI framework supports web-development-like paradigm. | All systems | | JS UI Framework | OpenHarmony JS UI framework supports web-development-like paradigm. | All systems |
| Multimedia | Provides easy-to-use APIs for developing multimedia components such as audio, video, and camera, and enables applications to use multimedia resources of the system.| All systems | | Multimedia | Provides easy-to-use APIs for developing multimedia components such as audio, video, and camera, and enables applications to use multimedia resources of the system.| All systems |
...@@ -189,7 +189,7 @@ For details about how to obtain the source code of OpenHarmony, see [Source Code ...@@ -189,7 +189,7 @@ For details about how to obtain the source code of OpenHarmony, see [Source Code
## How to Participate ## How to Participate
For details about how to join in the OpenHarmony community, see [OpenHarmony Community](https://gitee.com/openharmony/community/blob/master/README-EN.md) For details about how to join in the OpenHarmony community, see [OpenHarmony Community](https://gitee.com/openharmony/community/blob/master/README_EN.md)
For details about how to contribute, see [How to contribute](contribute/how-to-contribute.md). For details about how to contribute, see [How to contribute](contribute/how-to-contribute.md).
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
## IDL Overview ## IDL Overview
To ensure successful communications between the client and server, interfaces recognized by both parties must be defined. The OpenHarmony Interface Definition Language (IDL) is a tool for defining such interfaces. OpenHarmony IDL decomposes objects to be transferred into primitives that can be understood by the operating system and encapsulates cross-boundary objects based on developers' requirements. To ensure successful communications between the client and server, interfaces recognized by both parties must be defined. The OpenHarmony Interface Definition Language (IDL) is a tool for defining such interfaces. OpenHarmony IDL decomposes objects to be transferred into primitives that can be understood by the operating system and encapsulates cross-boundary objects based on developers' requirements.
**Figure 1** IDL interface description **Figure 1** IDL interface description
![IDL-interface-description](./figures/IDL-interface-description.png) ![IDL-interface-description](./figures/IDL-interface-description.png)
...@@ -156,11 +156,13 @@ On DevEco Studio, choose **Tools > SDK Manager** to view the local installation ...@@ -156,11 +156,13 @@ On DevEco Studio, choose **Tools > SDK Manager** to view the local installation
Go to the local installation path, choose **toolchains > 3.x.x.x** (the folder named after the version number), and check whether the executable file of IDL exists. Go to the local installation path, choose **toolchains > 3.x.x.x** (the folder named after the version number), and check whether the executable file of IDL exists.
> **NOTE**: Use the SDK of the latest version. The use of an earlier version may cause errors in some statements. > **NOTE**
>
> Use the SDK of the latest version. The use of an earlier version may cause errors in some statements.
If the executable file does not exist, download the SDK package from the mirror as instructed in the [Release Notes](../../release-notes). The following uses the [3.2 Beta3](../../release-notes/OpenHarmony-v3.2-beta3.md#acquiring-source-code-from-mirrors) as an example. If the executable file does not exist, download the SDK package from the mirror as instructed in the [Release Notes](../../release-notes). The following uses [3.2 Beta3](../../release-notes/OpenHarmony-v3.2-beta3.md) as an example.
For details about how to replace the SDK package, see [Guide to Switching to Full SDK](../quick-start/full-sdk-switch-guide.md). For details about how to replace the SDK package, see [Full SDK Compilation Guide](../quick-start/full-sdk-compile-guide.md).
After obtaining the executable file, perform subsequent development steps based on your scenario. After obtaining the executable file, perform subsequent development steps based on your scenario.
...@@ -176,6 +178,8 @@ You can use TS to create IDL files. ...@@ -176,6 +178,8 @@ You can use TS to create IDL files.
interface OHOS.IIdlTestService { interface OHOS.IIdlTestService {
int TestIntTransaction([in] int data); int TestIntTransaction([in] int data);
void TestStringTransaction([in] String data); void TestStringTransaction([in] String data);
void TestMapTransaction([in] Map<int, int> data);
int TestArrayTransaction([in] String[] data);
} }
``` ```
...@@ -183,7 +187,9 @@ Run the **idl -gen-ts -d *dir* -c dir/IIdlTestService.idl** command in the folde ...@@ -183,7 +187,9 @@ Run the **idl -gen-ts -d *dir* -c dir/IIdlTestService.idl** command in the folde
-*dir* next to **d** is the target output folder. For example, if the target output folder is **IIdlTestServiceTs**, run the **idl -gen-ts -d IIdlTestServiceTs -c IIdlTestServiceTs/IIdlTestService.idl** command in the folder where the executable file is located. The interface file, stub file, and proxy file are generated in the *dir* directory (**IIdlTestServiceTs** directory in this example) in the execution environment. -*dir* next to **d** is the target output folder. For example, if the target output folder is **IIdlTestServiceTs**, run the **idl -gen-ts -d IIdlTestServiceTs -c IIdlTestServiceTs/IIdlTestService.idl** command in the folder where the executable file is located. The interface file, stub file, and proxy file are generated in the *dir* directory (**IIdlTestServiceTs** directory in this example) in the execution environment.
> **NOTE**: The generated interface class file name must be the same as that of the .idl file. Otherwise, an error occurs during code generation. > **NOTE**
>
> The generated interface class file name must be the same as that of the .idl file. Otherwise, an error occurs during code generation.
For example, for an .idl file named **IIdlTestService.idl** and target output directory named **IIdlTestServiceTs**, the directory structure is similar to the following: For example, for an .idl file named **IIdlTestService.idl** and target output directory named **IIdlTestServiceTs**, the directory structure is similar to the following:
...@@ -203,6 +209,8 @@ The stub class generated by IDL is an abstract implementation of the interface c ...@@ -203,6 +209,8 @@ The stub class generated by IDL is an abstract implementation of the interface c
```ts ```ts
import {testIntTransactionCallback} from "./i_idl_test_service"; import {testIntTransactionCallback} from "./i_idl_test_service";
import {testStringTransactionCallback} from "./i_idl_test_service"; import {testStringTransactionCallback} from "./i_idl_test_service";
import {testMapTransactionCallback} from "./i_idl_test_service";
import {testArrayTransactionCallback} from "./i_idl_test_service";
import IIdlTestService from "./i_idl_test_service"; import IIdlTestService from "./i_idl_test_service";
import rpc from "@ohos.rpc"; import rpc from "@ohos.rpc";
...@@ -211,8 +219,8 @@ export default class IdlTestServiceStub extends rpc.RemoteObject implements IIdl ...@@ -211,8 +219,8 @@ export default class IdlTestServiceStub extends rpc.RemoteObject implements IIdl
super(des); super(des);
} }
async onRemoteRequestEx(code: number, data, reply, option): Promise<boolean> { async onRemoteMessageRequest(code: number, data, reply, option): Promise<boolean> {
console.log("onRemoteRequestEx called, code = " + code); console.log("onRemoteMessageRequest called, code = " + code);
switch(code) { switch(code) {
case IdlTestServiceStub.COMMAND_TEST_INT_TRANSACTION: { case IdlTestServiceStub.COMMAND_TEST_INT_TRANSACTION: {
let _data = data.readInt(); let _data = data.readInt();
...@@ -231,6 +239,29 @@ export default class IdlTestServiceStub extends rpc.RemoteObject implements IIdl ...@@ -231,6 +239,29 @@ export default class IdlTestServiceStub extends rpc.RemoteObject implements IIdl
}); });
return true; return true;
} }
case IdlTestServiceStub.COMMAND_TEST_MAP_TRANSACTION: {
let _data = new Map();
let _dataSize = data.readInt();
for (let i = 0; i < _dataSize; ++i) {
let key = data.readInt();
let value = data.readInt();
_data.set(key, value);
}
this.testMapTransaction(_data, (errCode) => {
reply.writeInt(errCode);
});
return true;
}
case IdlTestServiceStub.COMMAND_TEST_ARRAY_TRANSACTION: {
let _data = data.readStringArray();
this.testArrayTransaction(_data, (errCode, returnValue) => {
reply.writeInt(errCode);
if (errCode == 0) {
reply.writeInt(returnValue);
}
});
return true;
}
default: { default: {
console.log("invalid request code" + code); console.log("invalid request code" + code);
break; break;
...@@ -241,17 +272,23 @@ export default class IdlTestServiceStub extends rpc.RemoteObject implements IIdl ...@@ -241,17 +272,23 @@ export default class IdlTestServiceStub extends rpc.RemoteObject implements IIdl
testIntTransaction(data: number, callback: testIntTransactionCallback): void{} testIntTransaction(data: number, callback: testIntTransactionCallback): void{}
testStringTransaction(data: string, callback: testStringTransactionCallback): void{} testStringTransaction(data: string, callback: testStringTransactionCallback): void{}
testMapTransaction(data: Map<number, number>, callback: testMapTransactionCallback): void{}
testArrayTransaction(data: string[], callback: testArrayTransactionCallback): void{}
static readonly COMMAND_TEST_INT_TRANSACTION = 1; static readonly COMMAND_TEST_INT_TRANSACTION = 1;
static readonly COMMAND_TEST_STRING_TRANSACTION = 2; static readonly COMMAND_TEST_STRING_TRANSACTION = 2;
static readonly COMMAND_TEST_MAP_TRANSACTION = 3;
static readonly COMMAND_TEST_ARRAY_TRANSACTION = 4;
} }
``` ```
You need to inherit the interface class defined in the IDL file and implement the methods in the class. The following code snippet shows how to inherit the **IdlTestServiceStub** interface class and implement the **testIntTransaction** and **testStringTransaction** methods. You need to inherit the interface class defined in the IDL file and implement the methods in the class. The following code snippet shows how to inherit the **IdlTestServiceStub** interface class and implement the **testIntTransaction**, **testStringTransaction**, **testMapTransaction**, and **testArrayTransaction** methods.
```ts ```ts
import {testIntTransactionCallback} from "./i_idl_test_service" import {testIntTransactionCallback} from "./i_idl_test_service"
import {testStringTransactionCallback} from "./i_idl_test_service" import {testStringTransactionCallback} from "./i_idl_test_service"
import {testMapTransactionCallback} from "./i_idl_test_service";
import {testArrayTransactionCallback} from "./i_idl_test_service";
import IdlTestServiceStub from "./idl_test_service_stub" import IdlTestServiceStub from "./idl_test_service_stub"
...@@ -265,6 +302,14 @@ class IdlTestImp extends IdlTestServiceStub { ...@@ -265,6 +302,14 @@ class IdlTestImp extends IdlTestServiceStub {
{ {
callback(0); callback(0);
} }
testMapTransaction(data: Map<number, number>, callback: testMapTransactionCallback): void
{
callback(0);
}
testArrayTransaction(data: string[], callback: testArrayTransactionCallback): void
{
callback(0, 1);
}
} }
``` ```
...@@ -320,11 +365,28 @@ function callbackTestStringTransaction(result: number): void { ...@@ -320,11 +365,28 @@ function callbackTestStringTransaction(result: number): void {
} }
} }
function callbackTestMapTransaction(result: number): void {
if (result == 0) {
console.log('case 3 success');
}
}
function callbackTestArrayTransaction(result: number, ret: number): void {
if (result == 0 && ret == 124) {
console.log('case 4 success');
}
}
var onAbilityConnectDone = { var onAbilityConnectDone = {
onConnect:function (elementName, proxy) { onConnect:function (elementName, proxy) {
let testProxy = new IdlTestServiceProxy(proxy); let testProxy = new IdlTestServiceProxy(proxy);
let testMap = new Map();
testMap.set(1, 1);
testMap.set(1, 2);
testProxy.testIntTransaction(123, callbackTestIntTransaction); testProxy.testIntTransaction(123, callbackTestIntTransaction);
testProxy.testStringTransaction('hello', callbackTestStringTransaction); testProxy.testStringTransaction('hello', callbackTestStringTransaction);
testProxy.testMapTransaction(testMap, callbackTestMapTransaction);
testProxy.testArrayTransaction(['1','2'], callbackTestMapTransaction);
}, },
onDisconnect:function (elementName) { onDisconnect:function (elementName) {
console.log('onDisconnectService onDisconnect'); console.log('onDisconnectService onDisconnect');
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
- Application Package Structure - Application Package Structure
- [Application Package Structure in Stage Model)](quick-start/application-package-structure-stage.md) - [Application Package Structure in Stage Model)](quick-start/application-package-structure-stage.md)
- [Application Package Structure in FA Model](quick-start/application-package-structure-fa.md) - [Application Package Structure in FA Model](quick-start/application-package-structure-fa.md)
- [HAR File Structure](quick-start/har-structure.md)
- Multi-HAP Mechanism - Multi-HAP Mechanism
- [Multi-HAP Design Objectives](quick-start/multi-hap-objective.md) - [Multi-HAP Design Objectives](quick-start/multi-hap-objective.md)
- [Multi-HAP Build View](quick-start/multi-hap-build-view.md) - [Multi-HAP Build View](quick-start/multi-hap-build-view.md)
...@@ -49,7 +48,7 @@ ...@@ -49,7 +48,7 @@
- Development - Development
- [Application Models](application-models/Readme-EN.md) - [Application Models](application-models/Readme-EN.md)
- [UI Development](ui/Readme-EN.md) - [UI Development](ui/Readme-EN.md)
- [Common Event and Notification](notification/Readme-EN.md) - [Notification](notification/Readme-EN.md)
- [Window Manager](windowmanager/Readme-EN.md) - [Window Manager](windowmanager/Readme-EN.md)
- [WebGL](webgl/Readme-EN.md) - [WebGL](webgl/Readme-EN.md)
- [Media](media/Readme-EN.md) - [Media](media/Readme-EN.md)
...@@ -57,7 +56,7 @@ ...@@ -57,7 +56,7 @@
- [Connectivity](connectivity/Readme-EN.md) - [Connectivity](connectivity/Readme-EN.md)
- [Data Management](database/Readme-EN.md) - [Data Management](database/Readme-EN.md)
- [File Management](file-management/Readme-EN.md) - [File Management](file-management/Readme-EN.md)
- [Telephony](telephony/Readme-EN.md) - [Telephony Service](telephony/Readme-EN.md)
- [Task Management](task-management/Readme-EN.md) - [Task Management](task-management/Readme-EN.md)
- [Device Management](device/Readme-EN.md) - [Device Management](device/Readme-EN.md)
- [Device Usage Statistics](device-usage-statistics/Readme-EN.md) - [Device Usage Statistics](device-usage-statistics/Readme-EN.md)
......
...@@ -63,7 +63,7 @@ For details about how to use DevEco Studio to start the test framework, see [Ope ...@@ -63,7 +63,7 @@ For details about how to use DevEco Studio to start the test framework, see [Ope
**Example** **Example**
```javascript ```javascript
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'
function onAbilityCreateCallback(data) { function onAbilityCreateCallback(data) {
console.info("onAbilityCreateCallback"); console.info("onAbilityCreateCallback");
...@@ -87,11 +87,11 @@ abilityDelegator.addAbilityMonitor(monitor).then(() => { ...@@ -87,11 +87,11 @@ abilityDelegator.addAbilityMonitor(monitor).then(() => {
**Modules to Import** **Modules to Import**
```javascript ```javascript
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'
``` ```
```javascript ```javascript
var abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator(); var abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
``` ```
### Starting an Ability and Listening for the Ability State ### Starting an Ability and Listening for the Ability State
......
...@@ -250,9 +250,9 @@ In the stage model, in the onWindowStageCreate lifecycle of an ability, you can ...@@ -250,9 +250,9 @@ In the stage model, in the onWindowStageCreate lifecycle of an ability, you can
Use the API described in the table below to obtain the context associated with an ArkTS page. Use the API described in the table below to obtain the context associated with an ArkTS page.
| API | Description | | API | Description |
| :------------------------------------ | :--------------------------- | | :------------------------------------ | :----------------------------------------------------------- |
| getContext(component: Object): Object | Obtains the **Context** object associated with a component on the page.| | getContext(component: Object): Object | Obtains the **Context** object associated with a component on the page.<br>Since API version 9, this API is supported in ArkTS widgets.|
**Example** **Example**
......
...@@ -154,7 +154,7 @@ The basic dependency packages include: ...@@ -154,7 +154,7 @@ The basic dependency packages include:
import featureAbility from '@ohos.ability.featureAbility' import featureAbility from '@ohos.ability.featureAbility'
import ohos_data_ability from '@ohos.data.dataAbility' import ohos_data_ability from '@ohos.data.dataAbility'
import ohos_data_rdb from '@ohos.data.rdb' import ohos_data_rdb from '@ohos.data.rdb'
var urivar = "dataability:///com.ix.DataAbility" var urivar = "dataability:///com.ix.DataAbility"
var DAHelper = featureAbility.acquireDataAbilityHelper( var DAHelper = featureAbility.acquireDataAbilityHelper(
urivar urivar
......
...@@ -25,7 +25,7 @@ Carry out the following operations to develop the widget provider based on the [ ...@@ -25,7 +25,7 @@ Carry out the following operations to develop the widget provider based on the [
1. Implement lifecycle callbacks by using the **LifecycleForm** APIs. 1. Implement lifecycle callbacks by using the **LifecycleForm** APIs.
2. Create a **FormBindingData** instance. 2. Create a **FormBindingData** instance.
3. Update a widget by using the **FormProvider** APIs. 3. Update a widget by using the **FormProvider** APIs.
4. Develop the widget UI pages. 4. Develop the widget UI page.
## Available APIs ## Available APIs
...@@ -231,7 +231,7 @@ You should override **onDestroy** to implement widget data deletion. ...@@ -231,7 +231,7 @@ You should override **onDestroy** to implement widget data deletion.
} }
``` ```
For details about how to implement persistent data storage, see [Lightweight Data Store Development](../database/database-preference-guidelines.md). For details about how to implement persistent data storage, see [Data Persistence by User Preferences](../database/data-persistence-by-preferences.md).
The **Want** object passed in by the widget host to the widget provider contains a flag that specifies whether the requested widget is normal or temporary. The **Want** object passed in by the widget host to the widget provider contains a flag that specifies whether the requested widget is normal or temporary.
...@@ -402,3 +402,5 @@ The code snippet is as follows: ...@@ -402,3 +402,5 @@ The code snippet is as follows:
} }
} }
``` ```
<!--no_check-->
\ No newline at end of file
...@@ -47,7 +47,7 @@ You can specify the launch type by setting **launchType** in the **config.json** ...@@ -47,7 +47,7 @@ You can specify the launch type by setting **launchType** in the **config.json**
| Launch Type | Description |Description | | Launch Type | Description |Description |
| ----------- | ------- |---------------- | | ----------- | ------- |---------------- |
| standard | Multi-instance | A new instance is started each time an ability starts.| | standard | Multi-instance | A new instance is started each time an ability starts.|
| singleton | Singleton | The ability has only one instance in the system. If an instance already exists when an ability is started, that instance is reused.| | singleton | Singleton | The ability has only one instance in the system. If an instance already exists when an ability is started, that instance is reused.|
By default, **singleton** is used. By default, **singleton** is used.
......
...@@ -6,7 +6,7 @@ Ability continuation is to continue the current mission of an application, inclu ...@@ -6,7 +6,7 @@ Ability continuation is to continue the current mission of an application, inclu
## Available APIs ## Available APIs
The following table lists the APIs used for ability continuation. For details about the APIs, see [Ability](../reference/apis/js-apis-application-ability.md). The following table lists the APIs used for ability continuation. For details about the APIs, see [UIAbility](../reference/apis/js-apis-app-ability-uiAbility.md).
**Table 1** Ability continuation APIs **Table 1** Ability continuation APIs
...@@ -48,96 +48,88 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar ...@@ -48,96 +48,88 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar
} }
``` ```
- Configure the application startup type. - Configure the application startup type.
If **launchType** is set to **standard** in the **module.json5** file, the application is of the multi-instance launch type. During ability continuation, regardless of whether the application is already open, the target starts the application and restores the UI page. If **launchType** is set to **singleton**, the application is of the singleton launch type. If the application is already open, the target clears the existing page stack and restores the UI page. For more information, see "Launch Type" in [Ability Development](./stage-ability.md). If **launchType** is set to **multiton** in the **module.json5** file, the application is of the multi-instance launch type. During ability continuation, regardless of whether the application is already open, the target starts the application and restores the UI page. If **launchType** is set to **singleton**, the application is of the singleton launch type. If the application is already open, the target clears the existing page stack and restores the UI page. For more information, see "Launch Type" in [Ability Development](./stage-ability.md).
Configure a multi-instance application as follows:
```javascript
{
"module": {
"abilities": [
{
"launchType": "multiton"
}
]
}
}
```
Configure a singleton application as follows or retain the default settings of **launchType**:
```javascript
{
"module": {
"abilities": [
{
"launchType": "singleton"
}
]
}
}
```
- Apply for the distributed permissions.
Configure a multi-instance application as follows: Declare the **DISTRIBUTED_DATASYNC** permission in the **module.json5** file for the application.
```javascript ```javascript
{ "requestPermissions": [
"module": { {
"abilities": [ "name": "ohos.permission.DISTRIBUTED_DATASYNC"
{ },
"launchType": "standard" ```
}
]
}
}
```
Configure a singleton application as follows or retain the default settings of **launchType**: This permission must be granted by the user in a dialog box when the application is started for the first time. To enable the application to display a dialog box to ask for the permission, add the following code to **onWindowStageCreate** of the **Ability** class:
```javascript ```javascript
{ requestPermissions = async () => {
"module": { let permissions: Array<string> = [
"abilities": [ "ohos.permission.DISTRIBUTED_DATASYNC"
{ ];
"launchType": "singleton" let needGrantPermission = false
let accessManger = accessControl.createAtManager()
Logger.info("app permission get bundle info")
let bundleInfo = await bundle.getApplicationInfo(BUNDLE_NAME, 0, 100)
Logger.info(`app permission query permission ${bundleInfo.accessTokenId.toString()}`)
for (const permission of permissions) {
Logger.info(`app permission query grant status ${permission}`)
try {
let grantStatus = await accessManger.verifyAccessToken(bundleInfo.accessTokenId, permission)
if (grantStatus === PERMISSION_REJECT) {
needGrantPermission = true
break;
}
} catch (err) {
Logger.error(`app permission query grant status error ${permission} ${JSON.stringify(err)}`)
needGrantPermission = true
break;
}
}
if (needGrantPermission) {
Logger.info("app permission needGrantPermission")
try {
await accessManger.requestPermissionsFromUser(this.context, permissions)
} catch (err) {
Logger.error(`app permission ${JSON.stringify(err)}`)
}
} else {
Logger.info("app permission already granted")
}
} }
] ```
}
}
```
- Apply for the distributed permissions.
Declare the **DISTRIBUTED_DATASYNC** permission in the **module.json5** file for the application.
```javascript
"requestPermissions": [
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC"
},
```
This permission must be granted by the user in a dialog box when the application is started for the first time. To enable the application to display a dialog box to ask for the permission, add the following code to **onWindowStageCreate** of the **Ability** class:
```javascript
requestPermissions = async () => {
let permissions: Array<string> = [
"ohos.permission.DISTRIBUTED_DATASYNC"
];
let needGrantPermission = false
let accessManger = accessControl.createAtManager()
Logger.info("app permission get bundle info")
let bundleInfo = await bundle.getApplicationInfo(BUNDLE_NAME, 0, 100)
Logger.info(`app permission query permission ${bundleInfo.accessTokenId.toString()}`)
for (const permission of permissions) {
Logger.info(`app permission query grant status ${permission}`)
try {
let grantStatus = await accessManger.verifyAccessToken(bundleInfo.accessTokenId, permission)
if (grantStatus === PERMISSION_REJECT) {
needGrantPermission = true
break;
}
} catch (err) {
Logger.error(`app permission query grant status error ${permission} ${JSON.stringify(err)}`)
needGrantPermission = true
break;
}
}
if (needGrantPermission) {
Logger.info("app permission needGrantPermission")
try {
await accessManger.requestPermissionsFromUser(this.context, permissions)
} catch (err) {
Logger.error(`app permission ${JSON.stringify(err)}`)
}
} else {
Logger.info("app permission already granted")
}
}
```
2. Implement the **onContinue()** API. 2. Implement the **onContinue()** API.
...@@ -155,7 +147,7 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar ...@@ -155,7 +147,7 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar
You can obtain the target device ID (identified by the key **targetDevice**) and the version number (identified by the key **version**) of the application installed on the target device from the **wantParam** parameter of this API. The version number can be used for compatibility check. If the current application version is incompatible with that on the target device, **OnContinueResult.MISMATCH** can be returned to reject the continuation request. You can obtain the target device ID (identified by the key **targetDevice**) and the version number (identified by the key **version**) of the application installed on the target device from the **wantParam** parameter of this API. The version number can be used for compatibility check. If the current application version is incompatible with that on the target device, **OnContinueResult.MISMATCH** can be returned to reject the continuation request.
Example Example:
```javascript ```javascript
onContinue(wantParam : {[key: string]: any}) { onContinue(wantParam : {[key: string]: any}) {
...@@ -168,8 +160,6 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar ...@@ -168,8 +160,6 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar
} }
``` ```
3. Implement the continuation logic in the **onCreate()** or **onNewWant()** API. 3. Implement the continuation logic in the **onCreate()** or **onNewWant()** API.
The **onCreate()** API is called by the target. When the ability is started on the target device, this API is called to instruct the application to synchronize the memory data and UI component state, and triggers page restoration after the synchronization is complete. If the continuation logic is not implemented, the ability will be started in common startup mode and the page cannot be restored. The **onCreate()** API is called by the target. When the ability is started on the target device, this API is called to instruct the application to synchronize the memory data and UI component state, and triggers page restoration after the synchronization is complete. If the continuation logic is not implemented, the ability will be started in common startup mode and the page cannot be restored.
...@@ -178,11 +168,9 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar ...@@ -178,11 +168,9 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar
After data restore is complete, call **restoreWindowStage** to trigger page restoration. After data restore is complete, call **restoreWindowStage** to trigger page restoration.
You can also use **want.parameters.version** in the **want** parameter to obtain the application version number of the initiator. You can also use **want.parameters.version** in the **want** parameter to obtain the application version number of the initiator.
Example Example:
```javascript ```javascript
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
...@@ -190,7 +178,7 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar ...@@ -190,7 +178,7 @@ The code snippets provided below are all from [Sample](https://gitee.com/openhar
export default class EntryAbility extends UIAbility { export default class EntryAbility extends UIAbility {
storage : LocalStorag; storage : LocalStorag;
onCreate(want, launchParam) { onCreate(want, launchParam) {
Logger.info(`EntryAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`) Logger.info(`EntryAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`)
if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) { if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) {
...@@ -211,7 +199,7 @@ For a singleton ability, use **onNewWant()** to achieve the same implementation. ...@@ -211,7 +199,7 @@ For a singleton ability, use **onNewWant()** to achieve the same implementation.
Use distributed objects. Use distributed objects.
Distributed objects allow cross-device data synchronization like local variables. For two devices that form a Super Device, when data in the distributed data object of an application is added, deleted, or modified on a device, the data for the same application is also updated on the other device. Both devices can listen for the data changes and online and offline states of the other. For details, see [Distributed Data Object Development](../database/database-distributedobject-guidelines.md). Distributed objects allow cross-device data synchronization like local variables. For two devices that form a Super Device, when data in the distributed data object of an application is added, deleted, or modified on a device, the data for the same application is also updated on the other device. Both devices can listen for the data changes and online and offline states of the other. For details, see [Sharing Distributed Data Objects](../database/data-sync-of-distributed-data-object.md).
In the ability continuation scenario, the distributed data object is used to synchronize the memory data from the local device to the target device. In the ability continuation scenario, the distributed data object is used to synchronize the memory data from the local device to the target device.
...@@ -249,8 +237,6 @@ In the ability continuation scenario, the distributed data object is used to syn ...@@ -249,8 +237,6 @@ In the ability continuation scenario, the distributed data object is used to syn
}); });
``` ```
- The target device obtains the session ID from **onCreate()**, creates a distributed object, and associates the distributed object with the session ID. In this way, the distributed object can be synchronized. Before calling **restoreWindowStage**, ensure that all distributed objects required for continuation have been associated. - The target device obtains the session ID from **onCreate()**, creates a distributed object, and associates the distributed object with the session ID. In this way, the distributed object can be synchronized. Before calling **restoreWindowStage**, ensure that all distributed objects required for continuation have been associated.
```javascript ```javascript
...@@ -283,8 +269,6 @@ In the ability continuation scenario, the distributed data object is used to syn ...@@ -283,8 +269,6 @@ In the ability continuation scenario, the distributed data object is used to syn
} }
``` ```
### More Information ### More Information
1. Timeout 1. Timeout
...@@ -294,15 +278,13 @@ In the ability continuation scenario, the distributed data object is used to syn ...@@ -294,15 +278,13 @@ In the ability continuation scenario, the distributed data object is used to syn
2. By default, the system supports page stack information migration, which means that the page stack of the initiator will be automatically migrated to the target device. No adaptation is required. 2. By default, the system supports page stack information migration, which means that the page stack of the initiator will be automatically migrated to the target device. No adaptation is required.
### Restrictions ### Restrictions
1. The continuation must be performed between the same ability, which means the same bundle name, module name, and ability name. For details, see [Application Package Structure Configuration File](../quick-start/module-configuration-file.md). 1. The continuation must be performed between the same ability, which means the same bundle name, module name, and ability name. For details, see [Application Package Structure Configuration File](../quick-start/module-configuration-file.md).
2. Currently, the application can only implement the continuation capability. The continuation action must be initiated by the system. 2. Currently, the application can only implement the continuation capability. The continuation action must be initiated by the system.
### Best Practice ### Best Practice
For better user experience, you are advised to use the **wantParam** parameter to transmit data smaller than 100 KB and use distributed objects to transmit data larger than 100 KB. For better user experience, you are advised to use the **wantParam** parameter to transmit data smaller than 100 KB and use distributed objects to transmit data larger than 100 KB.
<!--no_check-->
\ No newline at end of file
...@@ -12,8 +12,8 @@ An ability can be launched in the **standard**, **singleton**, or **specified** ...@@ -12,8 +12,8 @@ An ability can be launched in the **standard**, **singleton**, or **specified**
| Launch Type | Description |Action | | Launch Type | Description |Action |
| ----------- | ------- |---------------- | | ----------- | ------- |---------------- |
| standard | Standard mode | A new instance is started each time an ability starts.| | multiton | Multi-instance mode| A new instance is started each time an ability starts.|
| singleton | Singleton mode | The ability has only one instance in the system. If an instance already exists when an ability is started, that instance is reused.| | singleton | Singleton mode | Default type. The ability has only one instance in the system. If an instance already exists when an ability is started, that instance is reused.|
| specified | Instance-specific| The internal service of an ability determines whether to create multiple instances during running.| | specified | Instance-specific| The internal service of an ability determines whether to create multiple instances during running.|
By default, the singleton mode is used. The following is an example of the **module.json5** file: By default, the singleton mode is used. The following is an example of the **module.json5** file:
...@@ -39,7 +39,7 @@ The table below describes the APIs provided by the **AbilityStage** class, which ...@@ -39,7 +39,7 @@ The table below describes the APIs provided by the **AbilityStage** class, which
|onAcceptWant(want: Want): string|Called when a specified ability is started.| |onAcceptWant(want: Want): string|Called when a specified ability is started.|
|onConfigurationUpdated(config: Configuration): void|Called when the global configuration is updated.| |onConfigurationUpdated(config: Configuration): void|Called when the global configuration is updated.|
The table below describes the APIs provided by the **Ability** class. For details about the APIs, see [Ability](../reference/apis/js-apis-application-ability.md). The table below describes the APIs provided by the **Ability** class. For details about the APIs, see [UIAbility](../reference/apis/js-apis-app-ability-uiAbility.md).
**Table 2** Ability APIs **Table 2** Ability APIs
...@@ -190,7 +190,7 @@ export default class EntryAbility extends UIAbility { ...@@ -190,7 +190,7 @@ export default class EntryAbility extends UIAbility {
``` ```
## Starting an Ability ## Starting an Ability
### Available APIs ### Available APIs
The **Ability** class has the **context** attribute, which belongs to the **AbilityContext** class. The **AbilityContext** class has the **abilityInfo**, **currentHapModuleInfo**, and other attributes as well as the APIs used for starting abilities. For details, see [AbilityContext](../reference/apis/js-apis-ability-context.md). The **Ability** class has the **context** attribute, which belongs to the **AbilityContext** class. The **AbilityContext** class has the **abilityInfo**, **currentHapModuleInfo**, and other attributes as well as the APIs used for starting abilities. For details, see [AbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md).
**Table 3** AbilityContext APIs **Table 3** AbilityContext APIs
|API|Description| |API|Description|
...@@ -207,7 +207,7 @@ The **Ability** class has the **context** attribute, which belongs to the **Abil ...@@ -207,7 +207,7 @@ The **Ability** class has the **context** attribute, which belongs to the **Abil
An application can obtain the context of an **Ability** instance through **this.context** and then use the **startAbility** API in the **AbilityContext** class to start the ability. The ability can be started by specifying **Want**, **StartOptions**, and **accountId**, and the operation result can be returned using a callback or **Promise** instance. The sample code is as follows: An application can obtain the context of an **Ability** instance through **this.context** and then use the **startAbility** API in the **AbilityContext** class to start the ability. The ability can be started by specifying **Want**, **StartOptions**, and **accountId**, and the operation result can be returned using a callback or **Promise** instance. The sample code is as follows:
```ts ```ts
let context = this.context let context = this.context
var want = { let want = {
"deviceId": "", "deviceId": "",
"bundleName": "com.example.MyApplication", "bundleName": "com.example.MyApplication",
"abilityName": "EntryAbility" "abilityName": "EntryAbility"
...@@ -224,7 +224,7 @@ context.startAbility(want).then(() => { ...@@ -224,7 +224,7 @@ context.startAbility(want).then(() => {
In the cross-device scenario, you must specify the ID of the remote device. The sample code is as follows: In the cross-device scenario, you must specify the ID of the remote device. The sample code is as follows:
```ts ```ts
let context = this.context let context = this.context
var want = { let want = {
"deviceId": getRemoteDeviceId(), "deviceId": getRemoteDeviceId(),
"bundleName": "com.example.MyApplication", "bundleName": "com.example.MyApplication",
"abilityName": "EntryAbility" "abilityName": "EntryAbility"
...@@ -239,9 +239,9 @@ Obtain the ID of a specified device from **DeviceManager**. The sample code is a ...@@ -239,9 +239,9 @@ Obtain the ID of a specified device from **DeviceManager**. The sample code is a
```ts ```ts
import deviceManager from '@ohos.distributedHardware.deviceManager'; import deviceManager from '@ohos.distributedHardware.deviceManager';
function getRemoteDeviceId() { function getRemoteDeviceId() {
if (typeof dmClass === 'object' && dmClass != null) { if (typeof dmClass === 'object' && dmClass !== null) {
var list = dmClass.getTrustedDeviceListSync(); let list = dmClass.getTrustedDeviceListSync();
if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') { if (typeof (list) === 'undefined' || typeof (list.length) === 'undefined') {
console.log("EntryAbility onButtonClick getRemoteDeviceId err: list is null"); console.log("EntryAbility onButtonClick getRemoteDeviceId err: list is null");
return; return;
} }
......
...@@ -135,7 +135,7 @@ To create a widget in the stage model, you need to implement lifecycle callbacks ...@@ -135,7 +135,7 @@ To create a widget in the stage model, you need to implement lifecycle callbacks
| Name | Description | Data Type | Default Value Allowed | | Name | Description | Data Type | Default Value Allowed |
| ----------- | ------------------------------------------------------------ | ---------- | -------------------- | | ----------- | ------------------------------------------------------------ | ---------- | -------------------- |
| name | Name of the Extension ability. This field must be specified. | String | No | | name | Name of the Extension ability. This field must be specified. | String | No |
| srcEntrance | Path of the Extension ability lifecycle code. This field must be specified.| String | No | | srcEntry | Path of the Extension ability lifecycle code. This field must be specified.| String | No |
| description | Description of the Extension ability. The value can be a string or a resource index to descriptions in multiple languages.| String | Yes (initial value: left empty)| | description | Description of the Extension ability. The value can be a string or a resource index to descriptions in multiple languages.| String | Yes (initial value: left empty)|
| icon | Index of the Extension ability icon file. | String | Yes (initial value: left empty)| | icon | Index of the Extension ability icon file. | String | Yes (initial value: left empty)|
| label | Descriptive information about the Extension ability presented externally. The value can be a string or a resource index to the description.| String | Yes (initial value: left empty)| | label | Descriptive information about the Extension ability presented externally. The value can be a string or a resource index to the description.| String | Yes (initial value: left empty)|
...@@ -150,7 +150,7 @@ To create a widget in the stage model, you need to implement lifecycle callbacks ...@@ -150,7 +150,7 @@ To create a widget in the stage model, you need to implement lifecycle callbacks
```json ```json
"extensionAbilities": [{ "extensionAbilities": [{
"name": "FormAbility", "name": "FormAbility",
"srcEntrance": "./ets/FormAbility/FormAbility.ts", "srcEntry": "./ets/FormAbility/FormAbility.ts",
"label": "$string:form_FormAbility_label", "label": "$string:form_FormAbility_label",
"description": "$string:form_FormAbility_desc", "description": "$string:form_FormAbility_desc",
"type": "form", "type": "form",
...@@ -242,7 +242,7 @@ You should override **onDestroy** to implement widget data deletion. ...@@ -242,7 +242,7 @@ You should override **onDestroy** to implement widget data deletion.
} }
``` ```
For details about how to implement persistent data storage, see [Lightweight Data Store Development](../database/database-preference-guidelines.md). For details about how to implement persistent data storage, see [Application Data Persistence Overview](../database/app-data-persistence-overview.md).
The **Want** object passed in by the widget host to the widget provider contains a flag that specifies whether the requested widget is normal or temporary. The **Want** object passed in by the widget host to the widget provider contains a flag that specifies whether the requested widget is normal or temporary.
...@@ -366,7 +366,7 @@ You can set router and message events for components on a widget. The router eve ...@@ -366,7 +366,7 @@ You can set router and message events for components on a widget. The router eve
1. Set the **onclick** field in the HML file to **routerEvent** or **messageEvent**, depending on the **actions** settings in the JSON file. 1. Set the **onclick** field in the HML file to **routerEvent** or **messageEvent**, depending on the **actions** settings in the JSON file.
2. Set the router event. 2. Set the router event.
- **action**: **"router"**, which indicates a router event. - **action**: **"router"**, which indicates a router event.
- **abilityName**: target ability name, for example, **EntryAbility**, which is the default UIAbility name in DevEco Studio for the stage model. - **abilityName**: target ability name, for example, **EntryAbility**, which is the default main ability name in DevEco Studio for the stage model.
- **params**: custom parameters of the target ability. Set them as required. The value can be obtained from **parameters** in **want** used for starting the target ability. For example, in the lifecycle function **onCreate** of the EntryAbility in the stage model, you can obtain **want** and its **parameters** field. - **params**: custom parameters of the target ability. Set them as required. The value can be obtained from **parameters** in **want** used for starting the target ability. For example, in the lifecycle function **onCreate** of the EntryAbility in the stage model, you can obtain **want** and its **parameters** field.
3. Set the message event. 3. Set the message event.
- **action**: **"message"**, which indicates a message event. - **action**: **"message"**, which indicates a message event.
...@@ -413,3 +413,5 @@ The code snippet is as follows: ...@@ -413,3 +413,5 @@ The code snippet is as follows:
} }
} }
``` ```
<!--no_check-->
\ No newline at end of file
...@@ -33,8 +33,8 @@ OpenHarmony does not support creation of a Service Extension ability for third-p ...@@ -33,8 +33,8 @@ OpenHarmony does not support creation of a Service Extension ability for third-p
"icon": "$media:icon", "icon": "$media:icon",
"description": "service", "description": "service",
"type": "service", "type": "service",
"visible": true, "exported": true,
"srcEntrance": "./ets/ServiceExtAbility/ServiceExtAbility.ts" "srcEntry": "./ets/ServiceExtAbility/ServiceExtAbility.ts"
}] }]
``` ```
......
...@@ -24,14 +24,17 @@ First thing first, familiarize yourself with the two cornerstone frameworks in O ...@@ -24,14 +24,17 @@ First thing first, familiarize yourself with the two cornerstone frameworks in O
All applications should be developed on top of these frameworks. All applications should be developed on top of these frameworks.
Then, equip yourself for developing the key features, with the following guidelines: Then, equip yourself for developing the key features, with the following guidelines:
- [Common Event and Notification](notification/Readme-EN.md)
- [Web](web/web-component-overview.md)
- [Notification](notification/Readme-EN.md)
- [Window Manager](windowmanager/Readme-EN.md) - [Window Manager](windowmanager/Readme-EN.md)
- [WebGL](webgl/Readme-EN.md) - [WebGL](webgl/Readme-EN.md)
- [Media](media/Readme-EN.md) - [Media](media/Readme-EN.md)
- [Security](security/Readme-EN.md) - [Security](security/Readme-EN.md)
- [Connectivity](connectivity/Readme-EN.md) - [Connectivity](connectivity/Readme-EN.md)
- [Telephony](telephony/Readme-EN.md) - [Telephony Service](telephony/Readme-EN.md)
- [Data Management](database/Readme-EN.md) - [Data Management](database/Readme-EN.md)
- [File Management](file-management/Readme-EN.md)
- [Task Management](task-management/Readme-EN.md) - [Task Management](task-management/Readme-EN.md)
- [Device Management](device/Readme-EN.md) - [Device Management](device/Readme-EN.md)
- [Device Usage Statistics](device-usage-statistics/Readme-EN.md) - [Device Usage Statistics](device-usage-statistics/Readme-EN.md)
...@@ -69,3 +72,5 @@ They are organized as follows: ...@@ -69,3 +72,5 @@ They are organized as follows:
### Readme ### Readme
For details about the principles and basic information of each subsystem, see the README file in [docs/en/readme](../readme). For details about the principles and basic information of each subsystem, see the README file in [docs/en/readme](../readme).
<!--no_check-->
\ No newline at end of file
...@@ -4,7 +4,7 @@ The application development documents provide reference for you to develop appli ...@@ -4,7 +4,7 @@ The application development documents provide reference for you to develop appli
The documents are carefully organized as follows: The documents are carefully organized as follows:
### Getting Started ## Getting Started
[Here](quick-start/start-overview.md) you'll learn how to quickly get started with OpenHarmony application development. [Here](quick-start/start-overview.md) you'll learn how to quickly get started with OpenHarmony application development.
...@@ -12,7 +12,7 @@ Browse the documents on the instructions for quickly building your first applica ...@@ -12,7 +12,7 @@ Browse the documents on the instructions for quickly building your first applica
Check out the development fundamentals, which comprise descriptions of the package structure configuration file for OpenHarmony applications and the instructions for use of resource files. Check out the development fundamentals, which comprise descriptions of the package structure configuration file for OpenHarmony applications and the instructions for use of resource files.
### Development ## Development
To facilitate your application development, we provide development guidelines for key features. To facilitate your application development, we provide development guidelines for key features.
...@@ -24,14 +24,17 @@ First thing first, familiarize yourself with the two cornerstone frameworks in O ...@@ -24,14 +24,17 @@ First thing first, familiarize yourself with the two cornerstone frameworks in O
All applications should be developed on top of these frameworks. All applications should be developed on top of these frameworks.
Then, equip yourself for developing the key features, with the following guidelines: Then, equip yourself for developing the key features, with the following guidelines:
- [Common Event and Notification](notification/notification-overview.md)
- [Web](web/web-component-overview.md)
- [Notification](notification/notification-overview.md)
- [Window Manager](windowmanager/window-overview.md) - [Window Manager](windowmanager/window-overview.md)
- [WebGL](webgl/webgl-overview.md) - [WebGL](webgl/webgl-overview.md)
- [Media](media/audio-overview.md) - [Media](media/media-application-overview.md)
- [Security](security/userauth-overview.md) - [Security](security/userauth-overview.md)
- [Connectivity](connectivity/ipc-rpc-overview.md) - [Connectivity](connectivity/ipc-rpc-overview.md)
- [Telephony](telephony/telephony-overview.md) - [Telephony Service](telephony/telephony-overview.md)
- [Data Management](database/database-mdds-overview.md) - [Data Management](database/data-mgmt-overview.md)
- [File Management](file-management/file-management-overview.md)
- [Task Management](task-management/background-task-overview.md) - [Task Management](task-management/background-task-overview.md)
- [Device](device/usb-overview.md) - [Device](device/usb-overview.md)
- [Device Usage Statistics](device-usage-statistics/device-usage-statistics-overview.md) - [Device Usage Statistics](device-usage-statistics/device-usage-statistics-overview.md)
...@@ -41,30 +44,28 @@ Then, equip yourself for developing the key features, with the following guideli ...@@ -41,30 +44,28 @@ Then, equip yourself for developing the key features, with the following guideli
- [OpenHarmony IDL Specifications and User Guide](IDL/idl-guidelines.md) - [OpenHarmony IDL Specifications and User Guide](IDL/idl-guidelines.md)
- [Using Native APIs in Application Projects](napi/napi-guidelines.md) - [Using Native APIs in Application Projects](napi/napi-guidelines.md)
### Tools ## Tools
DevEco Studio is a high-performance integrated development environment (IDE) recommended for developing OpenHarmony applications. DevEco Studio is a high-performance integrated development environment (IDE) recommended for developing OpenHarmony applications.
[Here](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-deveco-studio-overview-0000001263280421) you can learn everything about DevEco Studio, including how to use this tool to create a project and sign, debug, and run an application. [Here](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-deveco-studio-overview-0000001263280421) you can learn everything about DevEco Studio, including how to use this tool to create a project and sign, debug, and run an application.
### Hands-On Tutorials ## Hands-On Tutorials
To make you better understand how functions work together and jumpstart your application development projects, we provide stripped-down, real-world [samples](https://gitee.com/openharmony/applications_app_samples/blob/master/README.md) and [codelabs](https://gitee.com/openharmony/codelabs). To make you better understand how functions work together and jumpstart your application development projects, we provide stripped-down, real-world [samples](https://gitee.com/openharmony/applications_app_samples/blob/master/README.md) and [codelabs](https://gitee.com/openharmony/codelabs).
### API References ## API References
API references encompass all components and APIs available in OpenHarmony, helping you use and integrate APIs more effectively. API references encompass all components and APIs available in OpenHarmony, helping you use and integrate APIs more effectively.
They are organized as follows: They are organized as follows:
- [Component Reference (TypeScript-based Declarative Development Paradigm)](reference/arkui-ts/Readme-EN.md) - [Component Reference (TypeScript-based Declarative Development Paradigm)](reference/arkui-ts/ts-components-summary.md)
- [Component Reference (JavaScript-compatible Web-like Development Paradigm-ArkUI.Full)](reference/arkui-js/js-components-common-attributes.md)
- [Component Reference (JavaScript-based Web-like Development Paradigm)](reference/arkui-js/Readme-EN.md) - [Component Reference (JavaScript-compatible Web-like Development Paradigm-ArkUI.Lite)](reference/arkui-js-lite/js-framework-file.md)
- [JS Service Widget UI Components](reference/js-service-widget-ui/js-service-widget-file.md)
- [JS Service Widget UI Components](reference/js-service-widget-ui/Readme-EN.md) - [JS and TS APIs](reference/apis/development-intro.md)
- [JS and TS APIs](reference/apis/js-apis-ability-dataUriUtils.md)
- Native APIs - Native APIs
- [Standard Library](reference/native-lib/third_party_libc/musl.md) - [Standard Library](reference/native-lib/third_party_libc/musl.md)
- [Node_API](reference/native-lib/third_party_napi/napi.md) - [Node_API](reference/native-lib/third_party_napi/napi.md)
<!--no_check-->
\ No newline at end of file
...@@ -17,9 +17,11 @@ ...@@ -17,9 +17,11 @@
- ExtensionAbility Component - ExtensionAbility Component
- [ExtensionAbility Component Overview](extensionability-overview.md) - [ExtensionAbility Component Overview](extensionability-overview.md)
- [ServiceExtensionAbility](serviceextensionability.md) - [ServiceExtensionAbility](serviceextensionability.md)
- [DataShareExtensionAbility](datashareextensionability.md)
- [FormExtensionAbility (Widget)](widget-development-stage.md) - [FormExtensionAbility (Widget)](widget-development-stage.md)
- [StaticSubscriberExtensionAbility](static-subscriber-extension-ability.md) - [AccessibilityExtensionAbility](accessibilityextensionability.md)
- [EnterpriseAdminExtensionAbility](enterprise-extensionAbility.md)
- [InputMethodExtensionAbility](inputmethodextentionability.md)
- [WindowExtensionAbility](windowextensionability.md)
- [AbilityStage Component Container](abilitystage.md) - [AbilityStage Component Container](abilitystage.md)
- [Context](application-context-stage.md) - [Context](application-context-stage.md)
- Want - Want
...@@ -32,15 +34,19 @@ ...@@ -32,15 +34,19 @@
- [Component Startup Rules](component-startup-rules.md) - [Component Startup Rules](component-startup-rules.md)
- Inter-Device Application Component Interaction (Continuation) - Inter-Device Application Component Interaction (Continuation)
- [Continuation Overview](inter-device-interaction-hop-overview.md) - [Continuation Overview](inter-device-interaction-hop-overview.md)
- [Cross-Device Migration](hop-cross-device-migration.md) - [Cross-Device Migration (for System Applications Only)](hop-cross-device-migration.md)
- [Multi-device Collaboration](hop-multi-device-collaboration.md) - [Multi-device Collaboration (for System Applications Only)](hop-multi-device-collaboration.md)
- [Subscribing to System Environment Variable Changes](subscribe-system-environment-variable-changes.md)
- IPC - IPC
- [Process Model](process-model-stage.md) - [Process Model](process-model-stage.md)
- Common Events - Common Events
- [Introduction to Common Events](common-event-overview.md) - [Introduction to Common Events](common-event-overview.md)
- [Subscribing to Common Events](common-event-subscription.md) - Common Event Subscription
- [Common Event Subscription Overview](common-event-subscription-overview.md)
- [Subscribing to Common Events in Dynamic Mode](common-event-subscription.md)
- [Subscribing to Common Events in Static Mode (for System Applications Only)](common-event-static-subscription.md)
- [Unsubscribing from Common Events](common-event-unsubscription.md)
- [Publishing Common Events](common-event-publish.md) - [Publishing Common Events](common-event-publish.md)
- [Unsubscribing from Common Events](common-event-unsubscription.md)
- [Background Services](background-services.md) - [Background Services](background-services.md)
- Inter-Thread Communication - Inter-Thread Communication
- [Thread Model](thread-model-stage.md) - [Thread Model](thread-model-stage.md)
...@@ -50,6 +56,7 @@ ...@@ -50,6 +56,7 @@
- [Mission Management Scenarios](mission-management-overview.md) - [Mission Management Scenarios](mission-management-overview.md)
- [Mission Management and Launch Type](mission-management-launch-type.md) - [Mission Management and Launch Type](mission-management-launch-type.md)
- [Page Stack and MissionList](page-mission-stack.md) - [Page Stack and MissionList](page-mission-stack.md)
- [Setting the Icon and Name of a Mission Snapshot](mission-set-icon-name-for-task-snapshot.md)
- [Application Configuration File](config-file-stage.md) - [Application Configuration File](config-file-stage.md)
- FA Model Development - FA Model Development
- [FA Model Development Overview](fa-model-development-overview.md) - [FA Model Development Overview](fa-model-development-overview.md)
...@@ -63,7 +70,7 @@ ...@@ -63,7 +70,7 @@
- [Creating a PageAbility](create-pageability.md) - [Creating a PageAbility](create-pageability.md)
- [Starting a Local PageAbility](start-local-pageability.md) - [Starting a Local PageAbility](start-local-pageability.md)
- [Stopping a PageAbility](stop-pageability.md) - [Stopping a PageAbility](stop-pageability.md)
- [Starting a Remote PageAbility](start-remote-pageability.md) - [Starting a Remote PageAbility (for System Applications Only)](start-remote-pageability.md)
- [Starting a Specified Page](start-page.md) - [Starting a Specified Page](start-page.md)
- [Window Properties](window-properties.md) - [Window Properties](window-properties.md)
- [Requesting Permissions](request-permissions.md) - [Requesting Permissions](request-permissions.md)
......
# Using Explicit Want to Start an Ability # Using Explicit Want to Start an Ability
When a user touches a button in an application, the application often needs to start a UIAbility component to complete a specific task. If the **abilityName** and **bundleName** parameters are specified when starting a UIAbility, then the explicit Want is used.
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). ## Using Explicit Want
The user touches a button in the application to start the UIAbility component to complete a specific task. To start the UIAbility component in explicit Want mode, the **abilityName** and **bundleName** parameters must be specified. For details, see [Starting UIAbility in the Same Application](uiability-intra-device-interaction.md#starting-uiability-in-the-same-application).
# Using Implicit Want to Open a Website # Using Implicit Want to Open a Website
This section uses the operation of using a browser to open a website as an example. It is assumed that one or more browser applications are installed on the device. To ensure that the browser application can work properly, configure the [module.json5 file](../quick-start/module-configuration-file.md) as follows:
## Prerequisites
One or more browsers are installed on your device.
The **module.json5** of a browser application is as follows:
```json ```json
"skills": [ {
{ "module": {
"entities": [ // ...
"entity.system.browsable" "abilities": [
// ...
],
"actions": [
"ohos.want.action.viewData"
// ...
],
"uris": [
{
"scheme": "https",
"host": "www.test.com",
"port": "8080",
// Prefix matching is used.
"pathStartWith": "query",
"type": "text/*"
},
{ {
"scheme": "http",
// ... // ...
"skills": [
{
"entities": [
"entity.system.home",
"entity.system.browsable"
// ...
],
"actions": [
"action.system.home",
"ohos.want.action.viewData"
// ...
],
"uris": [
{
"scheme": "https",
"host": "www.test.com",
"port": "8080",
// Prefix matching is used.
"pathStartWith": "query"
},
{
"scheme": "http",
// ...
}
// ...
]
}
]
} }
// ...
] ]
}, }
] }
``` ```
In the initiator UIAbility, use implicit Want to start the browser application.
## How to Develop ```ts
import common from '@ohos.app.ability.common';
1. Use the custom function **implicitStartAbility** to start an ability. function implicitStartAbility() {
let context = getContext(this) as common.UIAbilityContext;
```ts let wantInfo = {
async implicitStartAbility() { // Uncomment the line below if you want to implicitly query data only in the specific bundle.
try { // bundleName: 'com.example.myapplication',
let want = { 'action': 'ohos.want.action.viewData',
// Uncomment the line below if you want to implicitly query data only in the specific bundle. // entities can be omitted.
// bundleName: "com.example.myapplication", 'entities': ['entity.system.browsable'],
"action": "ohos.want.action.viewData", 'uri': 'https://www.test.com:8080/query/student'
// entities can be omitted. }
"entities": [ "entity.system.browsable" ], context.startAbility(wantInfo).then(() => {
"uri": "https://www.test.com:8080/query/student", // ...
"type": "text/plain" }).catch((err) => {
} // ...
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. The matching process is as follows:
4. If **type** in the passed **want** parameter is specified and is included in **type** under **skills**, the matching is successful. 1. If **action** in the passed **want** parameter is specified and is included in **actions** under **skills** of the ability to match, the matching is successful.
2. If **entities** in the passed **want** parameter is specified and is included in **entities** under **skills** of the ability to match, the matching is successful.
3. If **uri** in the passed **want** parameter is included in **uris** under **skills** of the ability to match, which is concatenated into https://www.test.com:8080/query* (where * is a wildcard), the matching is successful.
4. If **type** in the passed **want** parameter is specified and is included in **type** under **skills** of the ability to match, the matching is successful.
2. When there are multiple matching applications, a dialog box is displayed for you to select one of them. If there are multiple matching applications, the system displays a dialog box for you to select one of them. The following figure shows an example.
![stage-want1](figures/stage-want1.png) ![](figures/ability-startup-with-implicit-want1.png)
\ No newline at end of file
...@@ -29,6 +29,18 @@ AbilityStage is not automatically generated in the default project of DevEco Stu ...@@ -29,6 +29,18 @@ AbilityStage is not automatically generated in the default project of DevEco Stu
} }
} }
``` ```
4. Set **srcEntry** in the [module.json5 file](../quick-start/module-configuration-file.md) to the code path of the module.
```json
{
"module": {
"name": "entry",
"type": "entry",
"srcEntry": "./ets/myabilitystage/MyAbilityStage.ts",
// ...
}
}
```
[AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md) has the lifecycle callback [onCreate()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageoncreate) and the event callbacks [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant), [onConfigurationUpdated()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonconfigurationupdate), and [onMemoryLevel()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonmemorylevel). [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).
...@@ -41,6 +53,7 @@ AbilityStage is not automatically generated in the default project of DevEco Stu ...@@ -41,6 +53,7 @@ AbilityStage is not automatically generated in the default project of DevEco Stu
- **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. - **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. - **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. 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.
...@@ -54,4 +67,3 @@ When an application is switched to the background, it is cached in the backgroun ...@@ -54,4 +67,3 @@ When an application is switched to the background, it is cached in the backgroun
} }
} }
``` ```
...@@ -15,14 +15,15 @@ Common events are classified into system common events and custom common events. ...@@ -15,14 +15,15 @@ Common events are classified into system common events and custom common events.
Common events are also classified into unordered, ordered, and sticky common events. 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. - Unordered common events: common events that CES forwards regardless of whether subscribers receive the events and when they subscribe to the events.
- Ordered common event: CES forwards common events to the next subscriber only after receiving a reply from the previous subscriber. - Ordered common events: common events that CES forwards based on the subscriber priority. CES forwards common events to the subscriber with lower priority only after receiving a reply from the previous subscriber with higher priority. Subscribers with the same priority receive common events in a random order.
- Sticky common 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). - Sticky common events: common events that can be sent to a subscriber before or after they initiate a subscription. Only system applications and system services can send sticky common events, which remain in the system after being sent. The sends must first request the **ohos.permission.COMMONEVENT_STICKY** permission. For details about the configuration, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
Each application can subscribe to common events as required. After your application subscribes to a common event, the system sends it to your application every time the event is published. Such an event may be published by the system, other applications, or your own application. 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 **Figure 1** Common events
![common-event](figures/common-event.png) ![common-event](figures/common-event.png)
\ No newline at end of file
# Subscribing to Common Events in Static Mode (for System Applications Only)
## When to Use
A static subscriber is started once it receives a target event published by the system or application. At the same time, the **onReceiveEvent** callback is triggered, in which you can implement the service logic. For example, if an application needs to execute some initialization tasks during device power-on, the application can subscribe to the power-on event in static mode. After receiving the power-on event, the application is started to execute the initialization tasks. Subscribing to a common event in static mode is achieved by configuring a declaration file and implementing a class that inherits from **StaticSubscriberExtensionAbility**. Note that this subscribing mode has negative impact on system power consumption. Therefore, exercise caution when using this mode.
## How to Develop
1. Declaring a Static Subscriber
To declare a static subscriber, create an ExtensionAbility, which is derived from the **StaticSubscriberExtensionAbility** class, in the project. The sample code is as follows:
```ts
import StaticSubscriberExtensionAbility from '@ohos.application.StaticSubscriberExtensionAbility'
export default class StaticSubscriber extends StaticSubscriberExtensionAbility {
onReceiveEvent(event) {
console.log('onReceiveEvent, event:' + event.event);
}
}
```
You can implement service logic in the **onReceiveEvent** callback.
2. Project Configuration for a Static Subscriber
After writing the static subscriber code, configure the subscriber in the **module.json5** file. The configuration format is as follows:
```ts
{
"module": {
......
"extensionAbilities": [
{
"name": "StaticSubscriber",
"srcEntrance": "./ets/StaticSubscriber/StaticSubscriber.ts",
"description": "$string:StaticSubscriber_desc",
"icon": "$media:icon",
"label": "$string:StaticSubscriber_label",
"type": "staticSubscriber",
"visible": true,
"metadata": [
{
"name": "ohos.extension.staticSubscriber",
"resource": "$profile:subscribe"
}
]
}
]
......
}
}
```
Pay attention to the following fields in the JSON file:
- **srcEntrance**: entry file path of the ExtensionAbility, that is, the file path of the static subscriber declared in Step 2.
- **type**: ExtensionAbility type. For a static subscriber, set this field to **staticSubscriber**.
- **metadata**: level-2 configuration file information of the ExtensionAbility. The configuration information varies according to the ExtensionAbility type. Therefore, you must use different config files to indicate the specific configuration.
- **name**: name of the ExtensionAbility. For a static subscriber, declare the name as **ohos.extension.staticSubscriber** for successful identification.
- **resource**: path that stores the ExtensionAbility configuration, which is customizable. In this example, the path is **resources/base/profile/subscribe.json**.
A level-2 configuration file pointed to by **metadata** must be in the following format:
```ts
{
"commonEvents": [
{
"name": "xxx",
"permission": "xxx",
"events":[
"xxx"
]
}
]
}
```
If the level-2 configuration file is not declared in this format, the file cannot be identified. The fields are described as follows:
- **name**: name of the ExtensionAbility, which must be the same as the name of **extensionAbility** declared in **module.json5**.
- **permission**: permission required for the publisher. If a publisher without the required permission attempts to publish an event, the event is regarded as invalid and will not be published.
- **events**: list of target events to subscribe to.
3. Device System Configuration
In the device system configuration file **/system/etc/app/install_list_capability.json**, add the bundle name of the static subscriber.
```json
{
"install_list": [
{
"bundleName": "ohos.extension.staticSubscriber",
"allowCommonEvent": ["usual.event.A", "usual.event.B"],
}
]
}
```
# Common Event Subscription Overview
​The common event service provides two subscription modes: dynamic and static. The biggest difference between these two modes is that dynamic subscription requires the application to be running, while static subscription does not.
- In dynamic subscription mode, a subscriber subscribes to common events by calling an API during the running period. For details, see [Subscribing to Common Events in Dynamic Mode](common-event-subscription.md).
- In static subscription mode, a subscriber subscribes to common events by configuring a declaration file and implementing a class that inherits from StaticSubscriberExtensionAbility. For details, see [Subscribing to Common Events in Static Mode](common-event-static-subscription.md).
# Subscribing to Common Events # Subscribing to Common Events in Dynamic Mode
## When to Use ## 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). In dynamic subscription mode, an application subscribes to a common event when it is running. If the subscribed event is published during the running period, the subscriber application will receive the event, together with the parameters passed in the event. For example, if an application expects to be notified of low battery so that it can reduce power consumption accordingly when running, then the application can subscribe to the low-battery event. Upon receiving the event, the application can close some unnecessary tasks to reduce power consumption. Certain system common events [require specific permissions](../security/accesstoken-guidelines.md) to subscribe to. For details, see [Required Permissions](../reference/apis/js-apis-commonEventManager.md#support).
## Available APIs ## Available APIs
......
# Unsubscribing from Common Events # Unsubscribing from Common Events in Dynamic Mode
## When to Use ## 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. You can call [unsubscribe()](../reference/apis/js-apis-commonEventManager.md#commoneventmanagerunsubscribe) to unsubscribe from a common event that is no longer required in dynamic mode.
## Available APIs ## Available APIs
...@@ -21,12 +21,12 @@ You can call [unsubscribe()](../reference/apis/js-apis-commonEventManager.md#com ...@@ -21,12 +21,12 @@ You can call [unsubscribe()](../reference/apis/js-apis-commonEventManager.md#com
import commonEventManager from '@ohos.commonEventManager'; import commonEventManager from '@ohos.commonEventManager';
``` ```
2. Subscribe to an event by following the procedure described in [Subscribing to Common Events](common-event-subscription.md). 2. Subscribe to an event by following the procedure described in [Subscribing to Common Events in Dynamic Mode](common-event-subscription.md).
3. Call **unsubscribe** in **CommonEvent** to unsubscribe from the common event. 3. Call **unsubscribe** in **CommonEvent** to unsubscribe from the common event.
```ts ```ts
// The subscriber object iscreated during event subscription. // The subscriber object is created during event subscription.
if (subscriber !== null) { if (subscriber !== null) {
commonEventManager.unsubscribe(subscriber, (err) => { commonEventManager.unsubscribe(subscriber, (err) => {
if (err) { if (err) {
......
...@@ -30,7 +30,7 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol ...@@ -30,7 +30,7 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol
- An application is considered as a foreground application only when the application process gains focus or its UIAbility component is running in the foreground. - An application is considered as a foreground application only when the application process gains focus or its UIAbility component is running in the foreground.
- Verify the **ohos.permission.START_ABILITIES_FROM_BACKGROUND** permission. - Verify the **ohos.permission.START_ABILITIES_FROM_BACKGROUND** permission.
- **When the startAbilityByCall() method is used, verify the call permission.** For details, see [Using Ability Call to Implement UIAbility Interaction](uiability-intra-device-interaction.md#using-ability-call-to-implement-uiability-interaction) and [Using Cross-Device Ability Call](hop-multi-device-collaboration.md#using-cross-device-ability-call). - **When the startAbilityByCall() method is used, verify the call permission.** For details, see [Using Call to Implement UIAbility Interaction](uiability-intra-device-interaction.md#using-call-to-implement-uiability-interaction) and [Using Cross-Device Call](hop-multi-device-collaboration.md#using-cross-device-call).
- Verify the **ohos.permission.ABILITY_BACKGROUND_COMMUNICATION** permission. - Verify the **ohos.permission.ABILITY_BACKGROUND_COMMUNICATION** permission.
......
...@@ -76,22 +76,22 @@ In the FA model, you can call **getContext** of **featureAbility** to obtain the ...@@ -76,22 +76,22 @@ In the FA model, you can call **getContext** of **featureAbility** to obtain the
The following code snippet shows how to use **getContext()** to obtain the application context and distributed directory: The following code snippet shows how to use **getContext()** to obtain the application context and distributed directory:
```ts ```ts
import featureAbility from '@ohos.ability.featureAbility' import featureAbility from '@ohos.ability.featureAbility';
import fileIo from '@ohos.fileio' import fs from '@ohos.file.fs';
(async () => { (async () => {
let dir: string let dir: string;
try { try {
console.info('Begin to getOrCreateDistributedDir') console.info('Begin to getOrCreateDistributedDir');
dir = await featureAbility.getContext().getOrCreateDistributedDir() dir = await featureAbility.getContext().getOrCreateDistributedDir();
console.info('distribute dir is ' + dir) console.info('distribute dir is ' + dir)
} catch (error) { } catch (error) {
console.error('getOrCreateDistributedDir failed with ' + error) console.error('getOrCreateDistributedDir failed with ' + error);
} }
let fd: number; let fd: number;
let path = dir + "/a.txt"; let path = dir + "/a.txt";
fd = fileIo.openSync(path, 0o2 | 0o100, 0o666); fd = fs.openSync(path, fs.OpenMode.READ_WRITE).fd;
fileIo.close(fd); fs.close(fd);
})() })()
``` ```
# Using Want to Share Data Between Applications # 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. Users often need to share data (such as a text or an image) from one application to another. The following uses PDF file sharing as an example to describe how to use Want to share data between applications.
Data sharing requires two UIAbility components (one for the sharing party and the other for the shared party) and one system component (used as the application sharing box). When the sharing party initiates data sharing by calling **startAbility()**, the system implicitly matches and displays all applications that support the type of data to share. After the user selects an application, the system starts the application to complete data sharing.
## Prerequisites In this section, data sharing is triggered by touching a button. You can use other ways to trigger data sharing during application development. This section focuses on how to configure Want to implement data sharing.
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. The following actions are involved for 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. - **ohos.want.action.select**: action of starting the application sharing box.
- **ohos.want.action.sendData**: action of sending a single data record, that is, transferring data to the shared party.
3. The following actions are involved in this section:
- **ACTION_SELECT (ohos.want.action.select)**: action of displaying the application selector. ## Sharing Party
- **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.
The sharing party starts an application sharing box and transfers the data to the shared party. Therefore, Want of the sharing party must be nested at two layers. In the first layer, implicit Want is used together with the **ohos.want.action.select** action to display the application sharing box. In the second layer, the data to share is declared
## How to Develop in the custom field **parameters**, and then the Want that includes the **ohos.want.action.sendData** action and the **parameters** field is transferred to the application sharing box. The shared party obtains the shared data from **parameters**.
- Sharing party ```ts
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. import common from '@ohos.app.ability.common';
```ts let fileType = 'application/pdf';
import fileIO from '@ohos.fileio'; let fileName = 'TestFile.pdf';
let fileFd = -1; // Obtain the file descriptor (FD) of the file to share.
// let path = ... let fileSize; // Obtain the size of the file to share.
// Open the file whose path is a variable.
let fileFd = fileIO.openSync(path, 0o102, 0o666); function implicitStartAbility() {
``` let context = getContext(this) as common.UIAbilityContext;
let wantInfo = {
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. / This action is used to implicitly match the application sharing box.
action: 'ohos.want.action.select',
```ts // This is the custom parameter in the first layer of Want,
import wantConstant from '@ohos.app.ability.wantConstant'; / which is intended to add information to the application sharing box.
parameters: {
// let path = ... // MIME type of PDF.
// let fileFd = ... 'ability.picker.type': fileType,
// let fileSize = ... 'ability.picker.fileNames': [fileName],
let want = { 'ability.picker.fileSizes': [fileSize],
/ This action is used to implicitly match the application selector. // This is nested Want ,which will be directly sent to the selected application.
action: wantConstant.Action.ACTION_SELECT, 'ability.want.params.INTENT': {
// This is the custom parameter in the first layer of Want, 'action': 'ohos.want.action.sendData',
/ which is intended to add information to the application selector. 'type': 'application/pdf',
parameters: { 'parameters': {
// MIME type of PDF. 'keyFd': { 'type': 'FD', 'value': fileFd }
"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: context.startAbility(wantInfo).then(() => {
// ...
- **"ability.picker.type"**: The application selector renders the file type icon based on this field. }).catch((err) => {
- **"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:
> **NOTE**
![stage-want2](figures/stage-want2.png) >
> Data sharing can be implemented only in FD format. For details about how to obtain the FD and file name, see [File Management](../reference/apis/js-apis-file-fs.md).
In the preceding code, 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 [Matching Rules of Implicit Want](explicit-implicit-want-mappings.md#matching-rules-of-implicit-want). After the user selects an application, the nested Want of the **ability.want.params.INTENT** field is passed to that application.
In the preceding code, under the custom field **parameters**, the following **ability.picker.*** fields are used to pass the information to be displayed on the application sharing box:
- 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: - **ability.picker.type**: file type icon.
- **ability.picker.fileNames**: file name.
```ts - **ability.picker.fileSizes**: file size, in bytes.
"skills": [ - **ability.picker.fileNames** and **ability.picker.fileSizes** are arrays and have a one-to-one mapping.
{
"entities": [ The following figure shows an example.
![](figures/ability-startup-with-implicit-want2.png)
## Shared Party
To enable the shared party to identify the shared content, configure **skills** in the [module.json5 file](../quick-start/module-configuration-file.md) of the UIAbility of the shared party. The **actions** and **type** fields in **uris** match the **action** and **type** fields in **ability.want.params.INTENT** of the sharing party, respectively.
```json
{
"module": {
// ...
"abilities": [
{
// ...
"skills": [
{
// ... // ...
], "actions": [
"actions": [ "action.system.home",
"ohos.want.action.sendData" "ohos.want.action.sendData"
// ... // ...
], ],
"uris": [ "uris": [
{ {
"type": "application/pdf" "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;
// ...
}
} }
``` ]
}
}
```
After the user selects an application, the Want nested in the **ability.want.params.INTENT** field is passed to that application. The UIAbility of the shared party, after being started, can call [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) or [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonnewwant) to obtain the passed Want.
The following is an example of the Want obtained. You can use the FD of the shared file to perform required operations.
```json
{
"deviceId": "",
"bundleName": "com.example.myapplication",
"abilityName": "EntryAbility",
"moduleName": "entry",
"uri": "",
"type": "application/pdf",
"flags": 0,
"action": "ohos.want.action.sendData",
"parameters": {
"component.startup.newRules": true,
"keyFd": {
"type": "FD",
"value": 36
},
"mime-type": "application/pdf",
"moduleName": "entry",
"ohos.aafwk.param.callerPid": 3488,
"ohos.aafwk.param.callerToken": 537379209,
"ohos.aafwk.param.callerUid": 20010014
},
"entities": []
}
```
# DataShareExtensionAbility # DataShareExtensionAbility (for System Applications Only)
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). DataShareExtensionAbility provides the data sharing capability. System applications can implement a DataShareExtensionAbility or access an existing DataShareExtensionAbility in the system. Third-party applications can only access an existing DataShareExtensionAbility. For details, see [DataShare Development](../database/database-datashare-guidelines.md).
# EnterpriseAdminExtensionAbility Development # EnterpriseAdminExtensionAbility Development
## Introduction ## Introduction to EnterpriseAdminExtensionAbility
**EnterpriseAdminExtensionAbility** is essential to a mobile device management (MDM) application. When developing an MDM application for an enterprise, you must inherit the **EnterpriseAdminExtensionAbility** class and have the MDM service logic implemented in an **EnterpriseAdminExtensionAbility** instance. The **EnterpriseAdminExtensionAbility** class provides callbacks for the enable, disable, install, and uninstall events of a device administrator application, implementing notification of system administrator status changes. EnterpriseAdminExtensionAbility is a mandatory component for Mobile Device Management (MDM) applications. When developing MDM applications for enterprises, you need to inherit EnterpriseAdminExtensionAbility and implement MDM service logic in the EnterpriseAdminExtensionAbility instance. EnterpriseAdminExtensionAbility implements notifications of system management status changes and defines the callbacks for when a device administrator application is enabled or disabled or an application is installed or uninstalled.
## Constraints ## Constraints
- ***Function constraints*** EnterpriseAdminExtensionAbility is applicable only to enterprise administrator applications.
The APIs provided can be used only by device administrator applications. ## Observing Activation/Deactivation of a Device Administrator Application and Installation/Removal of an Application
## Scenarios: Listening for the Enable, Disable, Install, and Uninstall Events of a Device Administrator Application
### Overview ### Overview
**onAdminEnabled**: called when the enterprise administrator or employee deploys an MDM application and enables the DeviceAdmin permission for the application. The MDM application can set the initialization policy in the **onAdminEnabled** callback. **onAdminEnabled**: When an enterprise administrator or employee deploys an MDM application and activates the device administrator application, this callback is invoked to notify the MDM application that the DeviceAdmin permission is activated. The initialization policy of the MDM application can set in **onAdminEnabled**.
**onAdminDisabled**: called when the system or employee disables the DeviceAdmin permission to notify the enterprise administrator that the device is no longer managed. **onAdminDisabled**: When the device administrator application is deactivated, the callback is invoked to notify the MDM application that the DeviceAdmin permission is deactivated.
**onBundleAdded**: called to notify the enterprise administrator that the specified MDM application is installed on the device. In enterprise application administration settings, after the enterprise administrator subscribes to application installation and uninstallation events, the MDM application reports the events through the callbacks. **onBundleAdded**: The enterprise administrator can subscribe to application installation and uninstallation events. When an application is installed on an enterprise device, the MDM application reports the event in this callback to notify the enterprise administrator.
**onBundleRemoved**: called to notify the enterprise administrator that the specified MDM application is uninstalled on the device. **onBundleRemoved**: When an application is removed from an enterprise device, the MDM application reports the event in this callback to notify the enterprise administrator.
### Available APIs ### Available APIs
| Class | API | Description | | Class | API | Description |
| :------------------------------ | ----------------------------------------- | ---------------------------- | | ------------------------------ | ----------------------------------------- | ---------------------------- |
| EnterpriseAdminExtensionAbility | onAdminDisabled(): void | Called when the device administrator application is enabled.| | EnterpriseAdminExtensionAbility | onAdminEnabled(): void | Called when a device administrator application is activated. |
| EnterpriseAdminExtensionAbility | onBundleAdded(bundleName: string): void | Called when the MDM application is installed. | | EnterpriseAdminExtensionAbility | onAdminDisabled(): void | Called when a device administrator application is deactivated.|
| EnterpriseAdminExtensionAbility | onAdminEnabled(): void | Called when the device administrator application is disabled. | | EnterpriseAdminExtensionAbility | onBundleAdded(bundleName: string): void | Called when an application is installed on a device. |
| EnterpriseAdminExtensionAbility | onBundleRemoved(bundleName: string): void | Called when the MDM application is uninstalled. | | EnterpriseAdminExtensionAbility | onBundleRemoved(bundleName: string): void | Called when an application is removed from a device. |
### How to Develop ### How to Develop
To implement **EnterpriseAdminExtensionAbility**, enable the device administrator application and create an **ExtensionAbility** instance from the code directory of the device administrator application. The procedure is as follows: To implement EnterpriseAdminExtensionAbility, you need to activate the device administrator application and create **ExtensionAbility** in the code directory of the device administrator application. The procedure is as follows:
1. In the **ets** directory of the target module, right-click and choose **New > Directory** to create a directory named **EnterpriseExtAbility**. 1. In the **ets** directory of the target module, right-click and choose **New > Directory** to create a directory named **EnterpriseExtAbility**.
2. Right-click the **EnterpriseExtAbility** directory and choose **New > TypeScript File** to create a file named **EnterpriseExtAbility.ts**. 2. Right-click the **EnterpriseExtAbility** directory, and choose **New > TypeScript File** to create a file named **EnterpriseExtAbility.ts**.
3. Open the **EnterpriseExtAbility.ts** file and import the **EnterpriseAdminExtensionAbility** module. Customize a class that inherits from **EnterpriseAdminExtensionAbility** and add the required callbacks, such as **onAdminEnabled()** and **onAdminDisabled()**, through which the enterprise administrator can receive notification when the device administrator application is enabled or disabled. 3. Open the **EnterpriseExtAbility.ts** file and import the **EnterpriseAdminExtensionAbility** module. Inherit the **EnterpriseAdminExtensionAbility** module to the custom class and add application notification callbacks, such as **onAdminEnabled()** and **onAdminDisabled()**. When the device administrator application is activated or deactivated, the device administrator can receive notifications.
```ts ```ts
import EnterpriseAdminExtensionAbility from '@ohos.enterprise.EnterpriseAdminExtensionAbility'; import EnterpriseAdminExtensionAbility from '@ohos.enterprise.EnterpriseAdminExtensionAbility';
export default class EnterpriseAdminAbility extends EnterpriseAdminExtensionAbility { export default class EnterpriseAdminAbility extends EnterpriseAdminExtensionAbility {
onAdminEnabled() { onAdminEnabled() {
console.info("onAdminEnabled"); console.info("onAdminEnabled");
} }
onAdminDisabled() { onAdminDisabled() {
console.info("onAdminDisabled"); console.info("onAdminDisabled");
} }
...@@ -56,14 +53,14 @@ To implement **EnterpriseAdminExtensionAbility**, enable the device administrato ...@@ -56,14 +53,14 @@ To implement **EnterpriseAdminExtensionAbility**, enable the device administrato
onBundleAdded(bundleName: string) { onBundleAdded(bundleName: string) {
console.info("EnterpriseAdminAbility onBundleAdded bundleName:" + bundleName) console.info("EnterpriseAdminAbility onBundleAdded bundleName:" + bundleName)
} }
onBundleRemoved(bundleName: string) { onBundleRemoved(bundleName: string) {
console.info("EnterpriseAdminAbility onBundleRemoved bundleName" + bundleName) console.info("EnterpriseAdminAbility onBundleRemoved bundleName" + bundleName)
} }
}; };
``` ```
4. Register **ServiceExtensionAbility** in the [module.json5](../quick-start/module-configuration-file.md) file of the target module. Among the parameters, set **type** to **enterpriseAdmin** and **srcEntrance** to the code path of the current ExtensionAbility. 4. Register **ServiceExtensionAbility** in the [**module.json5**](../quick-start/module-configuration-file.md) file corresponding to the project module. Set **type** to **enterpriseAdmin** and **srcEntrance** to the path of the ExtensionAbility code.
```ts ```ts
"extensionAbilities": [ "extensionAbilities": [
...@@ -78,10 +75,9 @@ To implement **EnterpriseAdminExtensionAbility**, enable the device administrato ...@@ -78,10 +75,9 @@ To implement **EnterpriseAdminExtensionAbility**, enable the device administrato
## Example ## Example
Use the **subscribeManagedEvent** and **unsubscribeManagedEvent** APIs in the **@ohos.enterprise.adminManager** module to subscribe to and unsubscribe from the application installation and uninstallation event, respectively. After the subscription is successful, the MDM application notifies the enterprise administrator when it is installed or uninstalled on the device. Use **subscribeManagedEvent** in the **@ohos.enterprise.adminManager** module to subscribe to application installation and removal events. When an application is installed or removed, the MDM application is notified of the event. Then, the MDM application reports the event in the callback to notify the enterprise administrator. To unsubscribe from events, use **unsubscribeManagedEvent**.
```ts ```ts
@State managedEvents: Array<adminManager.ManagedEvent> = [0,1]
@State subscribeManagedEventMsg: string = "" @State subscribeManagedEventMsg: string = ""
@State unsubscribeManagedEventMsg: string = "" @State unsubscribeManagedEventMsg: string = ""
...@@ -108,4 +104,3 @@ Use the **subscribeManagedEvent** and **unsubscribeManagedEvent** APIs in the ** ...@@ -108,4 +104,3 @@ Use the **subscribeManagedEvent** and **unsubscribeManagedEvent** APIs in the **
} }
``` ```
...@@ -62,7 +62,7 @@ The system matches the **action** attribute in the **want** parameter passed by ...@@ -62,7 +62,7 @@ The system matches the **action** attribute in the **want** parameter passed by
**Figure 1** Matching rules of action in the want parameter **Figure 1** Matching rules of action in the want parameter
![want-action](figures/want-action.png) ![want-action](figures/want-action.png)
### Matching Rules of entities in the want Parameter ### Matching Rules of entities in the want Parameter
...@@ -79,19 +79,15 @@ The system matches the **entities** attribute in the **want** parameter passed b ...@@ -79,19 +79,15 @@ The system matches the **entities** attribute in the **want** parameter passed b
- If **entities** in the passed **want** parameter is specified, and **entities** under **skills** of an ability is specified but does not contain **entities** in the passed **want** parameter, the matching fails. - If **entities** in the passed **want** parameter is specified, and **entities** under **skills** of an ability is specified but does not contain **entities** in the passed **want** parameter, the matching fails.
Figure 2 Matching rule of entities in the want parameter **Figure 2** Matching rule of entities in the want parameter
![want-entities](figures/want-entities.png) ![want-entities](figures/want-entities.png)
### Matching Rules of uri and type in the want Parameter ### Matching Rules of uri and type in the want Parameter
When the **uri** and **type** parameters are specified in the **want** parameter to initiate a component startup request, the system traverses the list of installed components and matches the **uris** array under **skills** of the abilities one by one. If one of the **uris** arrays under **skills** matches the **uri** and **type** in the passed **want**, the matching is successful. When the **uri** and **type** parameters are specified in the **want** parameter to initiate a component startup request, the system traverses the list of installed components and matches the **uris** array under **skills** of the abilities one by one. If one of the **uris** arrays under **skills** matches the **uri** and **type** in the passed **want**, the matching is successful.
Figure 3 Matching rules when uri and type are specified in the want parameter
![want-uri-type1](figures/want-uri-type1.png)
There are four combinations of **uri** and **type** settings. The matching rules are as follows: There are four combinations of **uri** and **type** settings. The matching rules are as follows:
- Neither **uri** or **type** is specified in the **want** parameter. - Neither **uri** or **type** is specified in the **want** parameter.
...@@ -111,11 +107,17 @@ There are four combinations of **uri** and **type** settings. The matching rules ...@@ -111,11 +107,17 @@ There are four combinations of **uri** and **type** settings. The matching rules
- If the **uris** array under **skills** of an ability is unspecified, the matching fails. - If the **uris** array under **skills** of an ability is unspecified, the matching fails.
- If the **uris** array under **skills** of an ability contains an element whose [uri is matched](#matching-rules-of-uri) and [type is matched](#matching-rules-of-type), the matching is successful. Otherwise, the matching fails. - If the **uris** array under **skills** of an ability contains an element whose [uri is matched](#matching-rules-of-uri) and [type is matched](#matching-rules-of-type), the matching is successful. Otherwise, the matching fails.
Leftmost URI matching: When only **scheme**, a combination of **scheme** and **host**, or a combination of **scheme**, **host**, and **port** is configured in the **uris** array under **skills** of the ability,
the matching is successful only if the leftmost URI in the passed **want** parameter matches **scheme**, the combination of **scheme** and **host**, or the combination of **scheme**, **host**, and **port**.
To simplify the description, **uri** and **type** passed in the **want** parameter are called **w_uri** and **w_type**, respectively; the **uris** array under **skills** of an ability to match is called **s_uris**; each element in the array is called **s_uri**. Matching is performed from top to bottom. **Figure 3** Matching rules when uri and type are specified in the want parameter
![want-uri-type1](figures/want-uri-type1.png)
To simplify the description, **uri** and **type** passed in the **want** parameter are called **w_uri** and **w_type**, respectively; the **uris** array under **skills** of an ability to match is called **s_uris**; each element in the array is called **s_uri**. Matching is performed from top to bottom.
Figure 4 Matching rules of uri and type in the want parameter **Figure 4** Matching rules of uri and type in the want parameter
![want-uri-type2](figures/want-uri-type2.png) ![want-uri-type2](figures/want-uri-type2.png)
...@@ -128,7 +130,9 @@ To simplify the description, **uri** in the passed **want** parameter is called ...@@ -128,7 +130,9 @@ To simplify the description, **uri** in the passed **want** parameter is called
- If **host** of **s_uri** is unspecified and **scheme** of **w_uri** and **scheme** of **s_uri** are the same, the matching is successful. Otherwise, the matching fails. - If **host** of **s_uri** is unspecified and **scheme** of **w_uri** and **scheme** of **s_uri** are the same, the matching is successful. Otherwise, the matching fails.
- If **path**, **pathStartWith**, and **pathRegex** of **s_uri** are unspecified and **w_uri** and **s_uri** are the same, the matching is successful. Otherwise, the matching fails. - If **port** of **s_uri** is unspecified and the combination of **scheme** and **host** of **w_uri** is the same as the combination of **scheme** and **host** of **s_uri**, the matching is successful. Otherwise, the matching fails.
- If **path**, **pathStartWith**, and **pathRegex** of **s_uri** are unspecified and the combination of **scheme**, **host**, and **port** of **w_uri** is the same as the combination of **scheme**, **host**, and **port** of **s_uri**, the matching is successful. Otherwise, the matching fails.
- If **path** of **s_uri** is specified and the **full path expressions** of **w_uri** and **s_uri** are the same, the matching is successful. Otherwise, the matching of **pathStartWith** continues. - If **path** of **s_uri** is specified and the **full path expressions** of **w_uri** and **s_uri** are the same, the matching is successful. Otherwise, the matching of **pathStartWith** continues.
...@@ -139,12 +143,17 @@ To simplify the description, **uri** in the passed **want** parameter is called ...@@ -139,12 +143,17 @@ To simplify the description, **uri** in the passed **want** parameter is called
> **NOTE** > **NOTE**
> >
> The **scheme**, **host**, **port**, **path**, **pathStartWith**, and **pathRegex** attributes of **uris** under **skills** of an ability are concatenated. If **path**, **pathStartWith**, and **pathRegex** are declared in sequence, **uris** can be concatenated into the following expressions: > The **scheme**, **host**, **port**, **path**, **pathStartWith**, and **pathRegex** attributes of **uris** under **skills** of an ability are concatenated. If **path**, **pathStartWith**, and **pathRegex** are declared in sequence, **uris** can be concatenated into the following expressions:
> >
> - **Full path expression**: `scheme://host:port/path` > - **Full path expression**: `scheme://host:port/path`
> >
> - **Prefix expression**: `scheme://host:port/pathStartWith` > - **Prefix expression**: `scheme://host:port/pathStartWith`
> >
> - **Regular expression**: `scheme://host:port/pathRegex` > - **Regular expression**: `scheme://host:port/pathRegex`
>
> - **Prefix URI expression**: When only **scheme**, a combination of **scheme** and **host**, or a combination of **scheme**, **host**, and **port** is configured in the configuration file, the matching is successful if a URI prefixed with the configuration file is passed in.
> * `scheme://`
> * `scheme://host`
> * `scheme://host:port`
### Matching Rules of type ### Matching Rules of type
......
...@@ -9,7 +9,7 @@ An [ExtensionAbilityType](../reference/apis/js-apis-bundleManager.md#extensionab ...@@ -9,7 +9,7 @@ An [ExtensionAbilityType](../reference/apis/js-apis-bundleManager.md#extensionab
- [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md): ExtensionAbility component of the form type, which provides APIs related to widgets. - [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 callbacks for Work Scheduler tasks. - [WorkSchedulerExtensionAbility](../reference/apis/js-apis-WorkSchedulerExtensionAbility.md): ExtensionAbility component of the work_scheduler type, which provides callbacks for Work Scheduler tasks.
- [InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod.md): ExtensionAbility component of the input_method type, which provides an input method framework that can be used to hide the keyboard, obtain the list of installed input methods, display the dialog box for input method selection, and more. - [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.
...@@ -21,10 +21,16 @@ An [ExtensionAbilityType](../reference/apis/js-apis-bundleManager.md#extensionab ...@@ -21,10 +21,16 @@ An [ExtensionAbilityType](../reference/apis/js-apis-bundleManager.md#extensionab
- [StaticSubscriberExtensionAbility](../reference/apis/js-apis-application-staticSubscriberExtensionAbility.md): ExtensionAbility component of the static_subscriber type, which provides APIs for static broadcast. - [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. - [WindowExtensionAbility](../reference/apis/js-apis-application-windowExtensionAbility.md): ExtensionAbility component of the window type, which allows a system application to be embedded in and displayed over another application.
- [EnterpriseAdminExtensionAbility](../reference/apis/js-apis-EnterpriseAdminExtensionAbility.md): ExtensionAbility component of the enterprise_admin type, which provides APIs for processing enterprise management events, such as application installation events on devices and events indicating too many incorrect screen-lock password attempts. - [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.
> **NOTE**<br>
> 1. Third-party applications cannot implement ServiceExtensionAbility, DataShareExtensionAbility, StaticSubscriberExtensionAbility, or WindowExtensionAbility.
>
> 2. To implement transaction processing in the background for a third-party application, use background tasks rather than ServiceExtensionAbility. For details, see [Background Task](../task-management/background-task-overview.md).
>
> 3. Third-party applications can use other types of ExtensionAbility components that have been defined.
## Using ExtensionAbility of the Specified Type ## Using ExtensionAbility of the Specified Type
......
# Cross-Device Migration # Cross-Device Migration (for System Applications Only)
## When to Use ## 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: The main task of cross-device migration 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 custom data
...@@ -47,25 +47,16 @@ The table below describes the main APIs used for cross-device migration. For det ...@@ -47,25 +47,16 @@ The table below describes the main APIs used for cross-device migration. For det
## How to Develop ## How to Develop
1. Configure the data synchronization permission in the **module.json5** file. The sample code is as follows: 1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
```json
{
"module": {
"requestPermissions":[
{
"name" : "ohos.permission.DISTRIBUTED_DATASYNC",
}
]
}
}
```
2. Configure the fields related to cross-device migration in the configuration file. 2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
- Configure the application to support migration.
Set the **continuable** field in the **module.json5** file to **true**. The default value is **false**. If this parameter is set to **false**, the application cannot be continued on the target device. 3. Configure the fields related to cross-device migration in the configuration file.
Configure the application to support migration.
Set the **continuable** field in the **module.json5** file to **true**. The default value is **false**. If this parameter is set to **false**, the application cannot be continued on the target device.
```json ```json
{ {
"module": { "module": {
...@@ -80,47 +71,31 @@ The table below describes the main APIs used for cross-device migration. For det ...@@ -80,47 +71,31 @@ The table below describes the main APIs used for cross-device migration. For det
} }
``` ```
- Configure the application launch type. For details, see [UIAbility Component Launch Type](uiability-launch-type.md). Configure the application launch type. For details, see [UIAbility Component Launch Type](uiability-launch-type.md).
3. Request the data synchronization permission. The sample code for displaying a dialog box to request the permission is as follows:
```ts
requestPermission() {
let context = this.context
let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC']
context.requestPermissionsFromUser(permissions).then((data) => {
console.info("Succeed to request permission from user with data: "+ JSON.stringify(data))
}).catch((error) => {
console.info("Failed to request permission from user with error: "+ JSON.stringify(error))
})
}
```
4. Implement [onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) in the UIAbility of the initiator. 4. Implement [onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) in the UIAbility of the initiator.
[onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) is called on the initiator. You can save the data in this method to implement application compatibility check and migration decision. [onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) is called on the initiator. You can save the data in this method to implement application compatibility check and migration decision.
- Saving migrated data: You can save the data to be migrated in key-value pairs in **wantParam**. - Saving migrated data: You can save the data to be migrated in key-value pairs in **wantParam**.
- Checking application compatibility: You can obtain the version number of the target application from **wantParam** and check the compatibility between the target application and the current application. - Checking application compatibility: You can obtain the version number of the target application from **wantParam** and check the compatibility between the target application and the current application.
- Making a migration decision: You can determine whether to support the migration based on the return value of **onContinue()**. For details about the return value, see [Available APIs](#available-apis). - Making a migration decision: You can determine whether to support the migration based on the return value of **onContinue()**. For details about the return value, see [Available APIs](#available-apis).
The sample code is as follows: The sample code is as follows:
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
import AbilityConstant from '@ohos.app.ability.AbilityConstant'; import AbilityConstant from '@ohos.app.ability.AbilityConstant';
onContinue(wantParam : {[key: string]: any}) { onContinue(wantParam : {[key: string]: any}) {
console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`) console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`)
let workInput = AppStorage.Get<string>('ContinueWork'); let workInput = AppStorage.Get<string>('ContinueWork');
// Set the user input data into wantParam. // Set the user input data into wantParam.
wantParam["work"] = workInput // set user input data into want params wantParam["work"] = workInput // set user input data into want params
console.info(`onContinue input = ${wantParam["input"]}`); console.info(`onContinue input = ${wantParam["input"]}`);
return AbilityConstant.OnContinueResult.AGREE return AbilityConstant.OnContinueResult.AGREE
} }
``` ```
5. Implement **onCreate()** and **onNewWant()** in the UIAbility of the target application to implement data restoration. 5. Implement **onCreate()** and **onNewWant()** in the UIAbility of the target application to implement data restoration.
- Implementation example of **onCreate** in the multi-instance scenario - Implementation example of **onCreate** in the multi-instance scenario
......
# InputMethodExtensionAbility Development
[InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod-extension-ability.md) is an ExtensionAbility component of the inputMethod type that provides extension capabilities for the input method framework.
InputMethodExtensionAbility can be started or connected by other application components to process transactions in the background based on the request of the caller.
InputMethodExtensionAbility provides related capabilities through the [InputMethodExtensionContext](../reference/apis/js-apis-inputmethod-extension-context.md).
## Implementing an Input Method Application
InputMethodExtensionAbility provides the **onCreate()** and **onDestory()** callbacks, as described below. Override them as required.
- **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.
- **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 an input method application, manually create an InputMethodExtensionAbility component in DevEco Studio. The procedure is as follows:
In the **ets** directory of the target module, right-click and choose **New** > **Extention Ability** > **InputMethod** to a minimum template of InputMethodExtensionAbility.
> **NOTE**
>
> When compiling the input method application, use the signature at the system_basic level. Otherwise, the application will not be able to start the keyboard.
The minimum template implements an input method application with the most basic features, such as starting the keyboard, entering text, and deleting input. You can diversify the feature set of the application by, for example, adding the feature to hide the keyboard.
The minimum template contains four files: **KeyboardController.ts**, **InputMethodService.ts**, **Index.ets**, and **KeyboardKeyData.ts**. The file directory is as follows:
```
/src/main/
├── ets/inputmethodextability
│ └──model/KeyboardController.ts # Shows the keyboard.
│ └──InputMethodService.ts # Customizes a class that inherits from InputMethodExtensionAbility and add the required lifecycle callbacks.
│ └──pages
│ └── Index.ets # Draws the keyboard and adds the input and deletion features.
│ └── KeyboardKeyData.ts # Defines keyboard attributes.
├── resources/base/profile/main_pages.json
```
## File Introduction
1. **InputMethodService.ts** file:
In this file, add the dependency package for importing InputMethodExtensionAbility. Customize a class that inherits from InputMethodExtensionAbility and add the required lifecycle callbacks.
```ts
import InputMethodExtensionAbility from '@ohos.InputMethodExtensionAbility';
import { KeyboardController } from './model/KeyboardController'
export default class InputDemoService extends InputMethodExtensionAbility {
private keyboardController: KeyboardController;
onCreate(want) {
this.keyboardController = new KeyboardController(this.context);
this.keyboardController.onCreate(); // Initialize the window and register an event listener for the input method framework.
}
onDestroy() {
console.log("onDestroy.");
this.context.destroy();
}
}
```
2. **KeyboardController.ts** file:
```ts
import inputMethodEngine from '@ohos.inputMethodEngine';
import display from '@ohos.display';
import windowManager from '@ohos.window';
// Call the getInputMethodAbility API to obtain an instance, and then call the other APIs of the input method framework based on the instance.
globalThis.inputAbility = inputMethodEngine.getInputMethodAbility();
export class KeyboardController {
mContext; // Save the context attribute in InputMethodExtensionAbility.
WINDOW_TYPE_INPUT_METHOD_FLOAT = 2105; // Define the window type. The value 2105 indicates the input method window type, which is used to create an input method application window.
windowName = 'inputApp';
private windowHeight: number = 0;
private windowWidth: number = 0;
private nonBarPosition: number = 0;
private isWindowShowing: boolean = false;
constructor(context) {
this.mContext = context;
}
public onCreate(): void
{
this.initWindow(); // Initialize the window.
this.registerListener(); // Register an event listener for the input method framework.
}
public onDestroy(): void // Destroy the instance.
{
this.unRegisterListener(); // Deregister the event listener.
let win = windowManager.findWindow(this.windowName);
win.destroyWindow(); // Destroy the window.
this.mContext.terminateSelf(); // Terminate the InputMethodExtensionAbility service.
}
private initWindow(): void // Initialize the window.
{
let dis = display.getDefaultDisplaySync();
let dWidth = dis.width;
let dHeight = dis.height;
let keyHeightRate = 0.47;
let keyHeight = dHeight * keyHeightRate;
this.windowWidth = dWidth;
this.windowHeight = keyHeight;
this.nonBarPosition = dHeight - keyHeight;
let config = {
name: this.windowName,
windowType: this.WINDOW_TYPE_INPUT_METHOD_FLOAT,
ctx: this.mContext
}
windowManager.createWindow(config).then((win) => { // Create a window of the specified type.
win.resize(dWidth, keyHeight).then(() => {
win.moveWindowTo(0, this.nonBarPosition).then(() => {
win.setUIContent('pages/InputMethodExtAbility/Index').then(() => {
});
});
});
});
}
private registerListener(): void
{
this.registerInputListener(); // Register an event listener for the input method framework service.
globalThis.inputAbility.on('keyboardShow', () => {// Register an event listener for the keyboard .
if (this.isWindowShowing) {
return;
}
this.isWindowShowing = true;
this.showHighWindow(); // Show the window.
});
...
// Register a listener for keyboard hiding.
}
private registerInputListener() { // Register a listener for the enabling and disabling events of the input method framework service.
globalThis.inputAbility.on('inputStart', (kbController, textInputClient) => {
globalThis.textInputClient = textInputClient; // This is an input method client instance, based on which you can call the functional APIs that the input method framework provides for the input method application.
globalThis.keyboardController = kbController;
})
globalThis.inputAbility.on('inputStop', (imeId) => {
if (imeId == "Bundle name/Ability name") {
this.onDestroy();
}
});
}
private unRegisterListener(): void
{
globalThis.inputAbility.off('inputStart');
globalThis.inputAbility.off('inputStop', () => {});
globalThis.inputAbility.off('keyboardShow');
}
private showHighWindow() {
let win = windowManager.findWindow(this.windowName)
win.resize(this.windowWidth, this.windowHeight).then(() => {
win.moveWindowTo(0, this.nonBarPosition).then(() => {
win.showWindow().then(() => {
this.isWindowShowing = false;
})
})
})
}
}
```
3. **KeyboardKeyData.ts** file:
In this file you can define the content displayed on the soft keyboard.
```ts
export interface sourceListType {
content: string,
}
export let numberSourceListData: sourceListType[] = [
{
content: '1'
},
{
content: '2'
},
{
content: '3'
},
{
content: '4'
},
{
content: '5'
},
{
content: '6'
},
{
content: '7'
},
{
content: '8'
},
{
content: '9'
},
{
content: '0'
}
]
```
4. **Index.ets** file:
This file describes the functions of keys. For example, the number keys print numbers in the text box, and the delete key deletes what's entered.
Add the path to this file to the **src** field in the **resources/base/profile/main_pages.json** file.
```ets
import { numberSourceListData, sourceListType } from './keyboardKeyData'
@Component
struct keyItem {
private keyValue: sourceListType
@State keyBgc: string = "#fff"
@State keyFontColor: string = "#000"
build() {
Column() {
Flex({ direction: FlexDirection.Column,
alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text(this.keyValue.content).fontSize(20).fontColor(this.keyFontColor)
}
}
.backgroundColor(this.keyBgc)
.borderRadius(6)
.width("8%")
.height("65%")
.onTouch((event: TouchEvent) => {
if (event.type === TouchType.Down) {
globalThis.textInputClient.insertText(this.keyValue.content);
}
})
}
}
// Component used for deletion.
@Component
export struct deleteItem {
@State keyBgc: string = "#fff"
@State keyFontColor: string = "#000"
build() {
Column() {
Flex({ direction: FlexDirection.Column,
alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Text("Delete").fontSize(20).fontColor(this.keyFontColor)
}
}
.backgroundColor(this.keyBgc)
.width("13%")
.borderRadius(6)
.onTouch((event: TouchEvent) => {
if (event.type === TouchType.Down) {
globalThis.textInputClient.deleteForward(1);
}
})
}
}
// Numeric keyboard
@Component
struct numberMenu {
private numberList: sourceListType[]
build() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceEvenly }) {
Flex({ justifyContent: FlexAlign.SpaceBetween }) {
ForEach(this.numberList, (item: sourceListType) => { // First row on the numeric keyboard
keyItem({ keyValue: item })
}, (item: sourceListType) => item.content);
}
.padding({ top: "2%" })
.width("96%")
.height("25%")
Flex({ justifyContent: FlexAlign.SpaceBetween }) {
deleteItem()
}
.width("96%")
.height("25%")
}
}
}
@Entry
@Component
struct Index {
private numberList: sourceListType[] = numberSourceListData
build() {
Stack() {
Flex({
direction: FlexDirection.Column,
alignItems: ItemAlign.Center,
justifyContent: FlexAlign.End
}) {
Flex({
direction: FlexDirection.Column,
alignItems: ItemAlign.Center,
justifyContent: FlexAlign.SpaceBetween
}) {
numberMenu({
numberList: this.numberList
})
}
.align(Alignment.End)
.width("100%")
.height("75%")
}
.height("100%").align(Alignment.End).backgroundColor("#cdd0d7")
}
.position({ x: 0, y: 0 }).zIndex(99999)
}
}
```
Register the InputMethodExtensionAbility in the [module.json5 file](../quick-start/module-configuration-file.md) corresponding to the target module. Set **type** to **"inputMethod"** and **srcEntrance** to the code path of the InputMethodExtensionAbility component.
```ts
{
"module": {
// ...
"extensionAbilities": [
{
"description": "inputMethod",
"icon": "$media:icon",
"name": "InputMethodExtAbility",
"srcEntrance": "./ets/inputmethodextability/InputMethodService.ts",
"type": "inputMethod",
"visible": true,
}
]
}
}
```
...@@ -18,7 +18,7 @@ To develop the Worker mode, perform the following steps: ...@@ -18,7 +18,7 @@ To develop the Worker mode, perform the following steps:
} }
``` ```
2. Create the **worker.js** file based on the configuration in **build-profile.json5**. 2. Create the **worker.ts** file based on the configuration in **build-profile.json5**.
```ts ```ts
import worker from '@ohos.worker'; import worker from '@ohos.worker';
...@@ -58,7 +58,7 @@ To develop the Worker mode, perform the following steps: ...@@ -58,7 +58,7 @@ To develop the Worker mode, perform the following steps:
```ts ```ts
import worker from '@ohos.worker'; import worker from '@ohos.worker';
let wk = new worker.ThreadWorker("../workers/worker.js"); let wk = new worker.ThreadWorker("../workers/worker.ts");
// Send a message to the worker thread. // Send a message to the worker thread.
wk.postMessage("message from main thread.") wk.postMessage("message from main thread.")
...@@ -74,6 +74,6 @@ To develop the Worker mode, perform the following steps: ...@@ -74,6 +74,6 @@ To develop the Worker mode, perform the following steps:
> **NOTE** > **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. > - 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.ts** 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). > - 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).
...@@ -30,102 +30,100 @@ Missions are managed by system applications (such as home screen), rather than t ...@@ -30,102 +30,100 @@ Missions are managed by system applications (such as home screen), rather than t
A UIAbility instance corresponds to an independent mission. Therefore, when an application calls [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to start a UIAbility, a mission is created. A UIAbility instance corresponds to an independent mission. Therefore, when an application calls [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to start a UIAbility, a mission is created.
To call [missionManager](../reference/apis/js-apis-application-missionManager.md) to manage missions, the home screen application must request the **ohos.permission.MANAGE_MISSIONS** permission. For details about the configuration, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
To call [missionManager](../reference/apis/js-apis-application-missionManager.md) to manage missions, the home screen application must request the **ohos.permission.MANAGE_MISSIONS** permission. For details about the configuration, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
You can use **missionManager** to manage missions, for example, listening for mission changes, obtaining mission information or snapshots, and clearing, locking, or unlocking missions.
You can use **missionManager** to manage missions, for example, listening for mission changes, obtaining mission information or snapshots, and clearing, locking, or unlocking missions. The sample code is as follows: ```ts
import missionManager from '@ohos.app.ability.missionManager'
let listener = {
```ts // Listen for mission creation.
import missionManager from '@ohos.app.ability.missionManager' onMissionCreated: function (mission) {
console.info("--------onMissionCreated-------")
let listener = { },
// Listen for mission creation. // Listen for mission destruction.
onMissionCreated: function (mission) { onMissionDestroyed: function (mission) {
console.info("--------onMissionCreated-------") console.info("--------onMissionDestroyed-------")
}, },
// Listen for mission destruction. // Listen for mission snapshot changes.
onMissionDestroyed: function (mission) { onMissionSnapshotChanged: function (mission) {
console.info("--------onMissionDestroyed-------") console.info("--------onMissionSnapshotChanged-------")
}, },
// Listen for mission snapshot changes. // Listen for switching the mission to the foreground.
onMissionSnapshotChanged: function (mission) { onMissionMovedToFront: function (mission) {
console.info("--------onMissionSnapshotChanged-------") console.info("--------onMissionMovedToFront-------")
}, },
// Listen for switching the mission to the foreground. // Listen for mission icon changes.
onMissionMovedToFront: function (mission) { onMissionIconUpdated: function (mission, icon) {
console.info("--------onMissionMovedToFront-------") console.info("--------onMissionIconUpdated-------")
}, },
// Listen for mission icon changes. // Listen for mission name changes.
onMissionIconUpdated: function (mission, icon) { onMissionLabelUpdated: function (mission) {
console.info("--------onMissionIconUpdated-------") console.info("--------onMissionLabelUpdated-------")
}, },
// Listen for mission name changes. // Listen for mission closure events.
onMissionLabelUpdated: function (mission) { onMissionClosed: function (mission) {
console.info("--------onMissionLabelUpdated-------") console.info("--------onMissionClosed-------")
}, }
// Listen for mission closure events. };
onMissionClosed: function (mission) {
console.info("--------onMissionClosed-------") // 1. Register a mission change listener.
} let listenerId = missionManager.on('mission', listener);
};
// 2. Obtain the latest 20 missions in the system.
// 1. Register a mission change listener. missionManager.getMissionInfos("", 20, (error, missions) => {
let listenerId = missionManager.on('mission', listener); console.info("getMissionInfos is called, error.code = " + error.code);
console.info("size = " + missions.length);
// 2. Obtain the latest 20 missions in the system. console.info("missions = " + JSON.stringify(missions));
missionManager.getMissionInfos("", 20, (error, missions) => { });
console.info("getMissionInfos is called, error.code = " + error.code);
console.info("size = " + missions.length); // 3. Obtain the detailed information about a mission.
console.info("missions = " + JSON.stringify(missions)); let missionId = 11; // The mission ID 11 is only an example.
}); let mission = missionManager.getMissionInfo("", missionId).catch(function (err) {
console.info(err);
// 3. Obtain the detailed information about a mission. });
let missionId = 11; // The mission ID 11 is only an example.
let mission = missionManager.getMissionInfo("", missionId).catch(function (err) { // 4. Obtain the mission snapshot.
console.info(err); missionManager.getMissionSnapShot("", missionId, (error, snapshot) => {
}); console.info("getMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
// 4. Obtain the mission snapshot. })
missionManager.getMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getMissionSnapShot is called, error.code = " + error.code); // 5. Obtain the low-resolution mission snapshot.
console.info("bundleName = " + snapshot.ability.bundleName); missionManager.getLowResolutionMissionSnapShot("", missionId, (error, snapshot) => {
}) console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
// 5. Obtain the low-resolution mission snapshot. })
missionManager.getLowResolutionMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code); // 6. Lock or unlock the mission.
console.info("bundleName = " + snapshot.ability.bundleName); missionManager.lockMission(missionId).then(() => {
}) console.info("lockMission is called ");
});
// 6. Lock or unlock the mission.
missionManager.lockMission(missionId).then(() => { missionManager.unlockMission(missionId).then(() => {
console.info("lockMission is called "); console.info("unlockMission is called ");
}); });
missionManager.unlockMission(missionId).then(() => { // 7. Switch the mission to the foreground.
console.info("unlockMission is called "); missionManager.moveMissionToFront(missionId).then(() => {
}); console.info("moveMissionToFront is called ");
});
// 7. Switch the mission to the foreground.
missionManager.moveMissionToFront(missionId).then(() => { // 8. Clear a single mission.
console.info("moveMissionToFront is called "); missionManager.clearMission(missionId).then(() => {
}); console.info("clearMission is called ");
});
// 8. Clear a single mission.
missionManager.clearMission(missionId).then(() => { // 9. Clear all missions.
console.info("clearMission is called "); missionManager.clearAllMissions().catch(function (err) {
}); console.info(err);
});
// 9. Clear all missions.
missionManager.clearAllMissions().catch(function (err) { // 10. Deregister the mission change listener.
console.info(err); missionManager.off('mission', listenerId, (error) => {
}); console.info("unregisterMissionListener");
})
// 10. Deregister the mission change listener. ```
missionManager.off('mission', listenerId, (error) => {
console.info("unregisterMissionListener");
})
```
# Setting the Icon and Name of a Mission Snapshot
Setting a unique icon and name for each mission snapshot of an application helps you better manage the missions and functions of the application.
By default, the **icon** and **label** fields in the [abilities tag](../quick-start/module-configuration-file.md#abilities) of the [module.json5 file](../quick-start/module-configuration-file.md) are used to set the icon and label.
Figure 1 Mission snapshot of a UIAbility
![](figures/mission-list-recent.png)
You can also use [UIAbilityContext.setMissionIcon()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionicon) and [UIAbilityContext.setMissionLabel()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionlabel) to customize the icon and name for a mission snapshot. For example, for a UIAbility instance with the launch type set to **standard**, you can configure the icon and name for each mission snapshot based on different functions.
This document describes the following operations:
- [Setting a Mission Snapshot Icon (for System Applications Only)](#setting-a-mission-snapshot-icon-for-system-applications-only)
- [Setting a Mission Snapshot Name](#setting-a-mission-snapshot-name)
## Setting a Mission Snapshot Icon (for System Applications Only)
Call [UIAbilityContext.setMissionIcon()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionicon) to set the icon of a mission snapshot. The icon is an object of the [PixelMap](../reference/apis/js-apis-image.md#pixelmap7) type. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability).
```ts
let imagePixelMap: PixelMap = undefined; // Obtain the PixelMap information.
this.context.setMissionIcon(imagePixelMap, (err) => {
console.error(`setMissionLabel failed, code is ${err.code}, message is ${err.message}`);
})
```
The display effect is shown below.
Figure 2 Mission snapshot icon
![](figures/mission-set-task-snapshot-icon.png)
## Setting a Mission Snapshot Name
Call [UIAbilityContext.setMissionLabel()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionlabel) to set the name of a mission snapshot.
```ts
this.context.setMissionLabel('test').then(() => {
console.info('setMissionLabel succeeded.');
}).catch((err) => {
console.error(`setMissionLabel failed, code is ${err.code}, message is ${err.message}`);
});
```
The display effect is shown below.
Figure 3 Mission snapshot name
![](figures/mission-set-task-snapshot-label.png)
\ No newline at end of file
...@@ -9,37 +9,7 @@ During application development, you must declare the required permission in the ...@@ -9,37 +9,7 @@ During application development, you must declare the required permission in the
To declare a permission in **config.json**, add **reqPermissions** under **module** and list the permission. To declare a permission in **config.json**, add **reqPermissions** under **module** and list the permission.
For example, to request the permission to access the calendar, perform the following steps:
For example, to declare the permission to access the calendar, request the **ohos.permission.READ_CALENDAR** permission. For details, see [Permission Application Guide](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). 1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
The sample code in the **config.json** file is as follows:
```json
{
"module": {
// ...
"reqPermissions": [
{
"name": "ohos.permission.READ_CALENDAR"
// ...
}
]
}
}
```
Request the permission from uses in the form of a dialog box:
```ts
import featureAbility from '@ohos.ability.featureAbility';
let context = featureAbility.getContext();
let permissions: Array<string> = ['ohos.permission.READ_CALENDAR']
context.requestPermissionsFromUser(permissions, 1).then((data) => {
console.info("Succeed to request permission from user with data: " + JSON.stringify(data))
}).catch((error) => {
console.info("Failed to request permission from user with error: " + JSON.stringify(error))
})
```
...@@ -18,9 +18,9 @@ Each type of ExtensionAbility has its own context. ServiceExtensionAbility has [ ...@@ -18,9 +18,9 @@ Each type of ExtensionAbility has its own context. ServiceExtensionAbility has [
This topic describes how to use ServiceExtensionAbility in the following scenarios: This topic describes how to use ServiceExtensionAbility in the following scenarios:
- [Implementing a Background Service](#implementing-a-background-service) - [Implementing a Background Service (for System Applications Only)](#implementing-a-background-service-for-system-applications-only)
- [Starting a Background Service](#starting-a-background-service) - [Starting a Background Service (for System Applications Only)](#starting-a-background-service-for-system-applications-only)
- [Connecting to a Background Service](#connecting-to-a-background-service) - [Connecting to a Background Service](#connecting-to-a-background-service)
...@@ -33,9 +33,9 @@ This topic describes how to use ServiceExtensionAbility in the following scenari ...@@ -33,9 +33,9 @@ This topic describes how to use ServiceExtensionAbility in the following scenari
> - Third-party applications can connect to ServiceExtensionAbility provided by the system only when they gain focus in the foreground. > - Third-party applications can connect to ServiceExtensionAbility provided by the system only when they gain focus in the foreground.
## Implementing a Background Service ## Implementing a Background Service (for System Applications Only)
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. [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 **Figure 1** ServiceExtensionAbility lifecycle
![ServiceExtensionAbility-lifecycle](figures/ServiceExtensionAbility-lifecycle.png) ![ServiceExtensionAbility-lifecycle](figures/ServiceExtensionAbility-lifecycle.png)
...@@ -164,9 +164,9 @@ To implement a background service, manually create a ServiceExtensionAbility com ...@@ -164,9 +164,9 @@ To implement a background service, manually create a ServiceExtensionAbility com
``` ```
## Starting a Background Service ## Starting a Background Service (for System Applications Only)
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. 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** > **NOTE**
> >
......
...@@ -10,7 +10,7 @@ The following figure shows the basic concepts used in the stage model. ...@@ -10,7 +10,7 @@ The following figure shows the basic concepts used in the stage model.
- [UIAbility component](uiability-overview.md) and [ExtensionAbility component](extensionability-overview.md) - [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. The stage model provides two types of application components: UIAbility and ExtensionAbility. Both have specific classes and support object-oriented development.
- 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. - 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.
...@@ -22,6 +22,7 @@ The following figure shows the basic concepts used in the stage model. ...@@ -22,6 +22,7 @@ The following figure shows the basic concepts used in the stage model.
- [Context](application-context-stage.md) - [Context](application-context-stage.md)
In the stage model, Context and its derived classes provide a variety of resources and 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. In the stage model, Context and its derived classes provide a variety of resources and 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) - [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. 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.
......
# Starting a Remote PageAbility # Starting a Remote PageAbility (for System Applications Only)
This feature applies only to system applications. The **startAbility()** method in the **featureAbility** class is used to start a remote PageAbility. 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. 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.
......
# StaticSubscriberExtensionAbility Development
## Scenario Description
​The common event service provides two subscription modes: dynamic and static. In dynamic subscription mode, a subscriber calls an API during the running period to subscribe to common events. For details, see [Subscribing to Common Events](common-event-subscription.md). In static subscription mode, no common event subscription API is called. A common event is subscribed by configuring a declaration file and implementing a class that inherits from **StaticSubscriberExtensionAbility**. A static subscriber is started once it receives a target event (for example, a power-on event) published by the system or application. At the same time, the **onReceiveEvent** callback is triggered, in which you can implement the service logic. **The static subscriber APIs are system APIs and can be used only by system applications that have passed the system-level power consumption review.**
## How to Develop
1. Prerequisites
The application must meet the following requirements:
The application is a system application.
The application is developed using the full SDK.
The application's power consumption has passed the system-level power consumption review. If you want to use static subscription in the debugging phase, add the bundle name of your application to the system configuration file **/etc/static_subscriber_config.json**.
2. Declaring a Static Subscriber
To declare a static subscriber, create an ExtensionAbility, which is derived from the **StaticSubscriberExtensionAbility** class, in the project. The sample code is as follows:
```ts
import StaticSubscriberExtensionAbility from '@ohos.application.StaticSubscriberExtensionAbility'
export default class StaticSubscriber extends StaticSubscriberExtensionAbility {
onReceiveEvent(event) {
console.log('onReceiveEvent, event:' + event.event);
}
}
```
You can implement service logic in the **onReceiveEvent** callback.
3. Project Configuration for a Static Subscriber
After writing the static subscriber code, configure the subscriber in the **module.json5** file. The configuration format is as follows:
```ts
{
"module": {
......
"extensionAbilities": [
{
"name": "StaticSubscriber",
"srcEntrance": "./ets/StaticSubscriber/StaticSubscriber.ts",
"description": "$string:StaticSubscriber_desc",
"icon": "$media:icon",
"label": "$string:StaticSubscriber_label",
"type": "staticSubscriber",
"visible": true,
"metadata": [
{
"name": "ohos.extension.staticSubscriber",
"resource": "$profile:subscribe"
}
]
}
]
......
}
}
```
Pay attention to the following fields in the JSON file:
**srcEntrance**: entry file path of the ExtensionAbility, that is, the file path of the static subscriber declared in Step 2.
**type**: ExtensionAbility type. For a static subscriber, set this field to **staticSubscriber**.
**metadata**: level-2 configuration file information of the ExtensionAbility. The configuration information varies according to the ExtensionAbility type. Therefore, you must use different config files to indicate the specific configuration. The **metadata** field contains two keywords: **name** and **resource**. The **name** field indicates the ExtensionAbility type name. For a static subscriber, declare the name as **ohos.extension.staticSubscriber** for successful identification. The **resource** field indicates the path that stores the ExtensionAbility configuration, which is customizable. In this example, the path is **resources/base/profile/subscribe.json**.
A level-2 configuration file pointed to by **metadata** must be in the following format:
```ts
{
"commonEvents": [
{
"name": "xxx",
"permission": "xxx",
"events":[
"xxx"
]
}
]
}
```
If the level-2 configuration file is not declared in this format, the file cannot be identified. The fields are described as follows:
**name**: name of the ExtensionAbility, which must be the same as the name of **extensionAbility** declared in **module.json5**.
**permission**: permission required by the publisher. If a publisher without the required permission attempts to publish an event, the event is regarded as invalid and will not be published.
**events**: list of subscribed target events
## Samples
For details about how to develop StaticSubscriberExtensionAbility, see [StaticSubscriber (ArkTS, API version 9, Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/ability/StaticSubscriber).
# Subscribing to System Environment Variable Changes
System environment variables are system settings (for example, the system language or screen direction) of a device that may change during the running of an application.
By subscribing to the changes of system environment variables, the application can detect the changes in a timely manner and process the changes accordingly, providing better user experience. For example, when the system language changes, the application can display the UI in the new language; when the user rotates the device to landscape or portrait mode, the application can re-arrange the UI to adapt to the new screen orientation and size.
The system environment variable changes are usually triggered by options in **Settings** or icons in **Control Panel**. For details about the system environment variables that support subscription, see [Configuration](../reference/apis/js-apis-app-ability-configuration.md).
In OpenHarmony, you can subscribe to system environment variable changes in the following ways:
- [Using ApplicationContext for Subscription](#using-applicationcontext-for-subscription)
- [Using AbilityStage for Subscription](#using-abilitystage-for-subscription)
- [Using UIAbility for Subscription](#using-uiability-for-subscription)
- [Using ExtensionAbility for Subscription](#using-extensionability-for-subscription)
## Using ApplicationContext for Subscription
[ApplicationContext](../reference/apis/js-apis-inner-application-applicationContext.md) provides an API for registering a callback function to subscribe to the system environment variable changes. It also provides an API for deregistration so you can release related resources when they are no longer needed.
1. Call **ApplicationContext.on(type: 'environment', callback: EnvironmentCallback)** to subscribe to changes in system environment variables. The code snippet below is used to subscribe to system language changes on a page.
```ts
import common from '@ohos.app.ability.common';
@Entry
@Component
struct Index {
private context = getContext(this) as common.UIAbilityContext;
private callbackId: number; // ID of the subscription for system environment variable changes.
subscribeConfigurationUpdate() {
let systemLanguage: string = this.context.config.language; // Obtain the system language in use.
// 1. Obtain an ApplicationContext object.
let applicationContext = this.context.getApplicationContext();
// 2. Subscribe to system environment variable changes through ApplicationContext.
let environmentCallback = {
onConfigurationUpdated(newConfig) {
console.info(`onConfigurationUpdated systemLanguage is ${systemLanguage}, newConfig: ${JSON.stringify(newConfig)}`);
if (this.systemLanguage !== newConfig.language) {
console.info(`systemLanguage from ${systemLanguage} changed to ${newConfig.language}`);
systemLanguage = newConfig.language; // Save the new system language as the system language in use, which will be used for comparison.
}
},
onMemoryLevel(level) {
console.info(`onMemoryLevel level: ${level}`);
}
}
this.callbackId = applicationContext.on('environment', environmentCallback);
}
// Page display.
build() {
// ...
}
}
```
2. Call **ApplicationContext.off(type: 'environment', callbackId: number)** to release the resources.
```ts
import common from '@ohos.app.ability.common';
@Entry
@Component
struct Index {
private context = getContext(this) as common.UIAbilityContext;
private callbackId: number; // ID of the subscription for system environment variable changes.
unsubscribeConfigurationUpdate() {
let applicationContext = this.context.getApplicationContext();
applicationContext.off('environment', this.callbackId);
}
// Page display.
build() {
// ...
}
}
```
## Using AbilityStage for Subscription
The AbilityStage component provides the [AbilityStage.onConfigurationUpdate()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonconfigurationupdate) callback for subscribing to system environment variable changes. This callback is invoked when a system environment variable changes. In this callback, the latest system environment configuration is obtained through the [Configuration](../reference/apis/js-apis-app-ability-configuration.md) object.
> **NOTE**
>
> - 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).
> - The callback used to subscribe to system environment variable changes has the same lifecycle as the [AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md) instance and will be destroyed when the instance is destroyed.
The code snippet below uses the [AbilityStage.onConfigurationUpdate()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonconfigurationupdate) callback to subscribe to the system language changes.
```ts
import AbilityStage from '@ohos.app.ability.AbilityStage';
let systemLanguage: string; // System language in use.
export default class MyAbilityStage extends AbilityStage {
onCreate() {
systemLanguage = this.context.config.language; // Obtain the system language in use when the AbilityStage instance is loaded for the first time.
console.info(`systemLanguage is ${systemLanguage} `);
}
onConfigurationUpdate(newConfig) {
console.info(`onConfigurationUpdated systemLanguage is ${systemLanguage}, newConfig: ${JSON.stringify(newConfig)}`);
if (systemLanguage !== newConfig.language) {
console.info(`systemLanguage from ${systemLanguage} changed to ${newConfig.language}`);
systemLanguage = newConfig.language; // Save the new system language as the system language in use, which will be used for comparison.
}
}
}
```
## Using UIAbility for Subscription
The UIAbility component provides the **UIAbility.onConfigurationUpdate()** callback for subscribing to system environment variable changes. This callback is invoked when a system environment variable changes. In this callback, the latest system environment configuration is obtained through the [Configuration](../reference/apis/js-apis-app-ability-configuration.md) object, without restarting the UIAbility.
> **NOTE**
>
> The callback used to subscribe to system environment variable changes has the same lifecycle as the UIAbility instance and will be destroyed when the instance is destroyed.
The code snippet below uses the **onConfigurationUpdate()** callback to subscribe to the system language changes.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
let systemLanguage: string; // System language in use.
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
systemLanguage = this.context.config.language; // Obtain the system language in use when the UIAbility instance is loaded for the first time.
console.info(`systemLanguage is ${systemLanguage} `);
}
onConfigurationUpdate(newConfig) {
console.info(`onConfigurationUpdated systemLanguage is ${systemLanguage}, newConfig: ${JSON.stringify(newConfig)}`);
if (systemLanguage !== newConfig.language) {
console.info(`systemLanguage from ${systemLanguage} changed to ${newConfig.language}`);
systemLanguage = newConfig.language; // Save the new system language as the system language in use, which will be used for comparison.
}
}
// ...
}
```
## Using ExtensionAbility for Subscription
The ExtensionAbility component provides the **onConfigurationUpdate()** callback for subscribing system environment variable changes. This callback is invoked when a system environment variable changes. In this callback, the latest system environment configuration is obtained through the [Configuration](../reference/apis/js-apis-app-ability-configuration.md) object.
> **NOTE**
>
> The callback used to subscribe to system environment variable changes has the same lifecycle as the ExtensionAbility instance and will be destroyed when the instance is destroyed.
The code snippet below uses FormExtensionAbility as an example to describe how to use the **onConfigurationUpdate()** callback to subscribe to system environment variable changes.
```ts
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
export default class EntryFormAbility extends FormExtensionAbility {
onConfigurationUpdate(newConfig) {
console.info(`newConfig is ${JSON.stringify(newConfig)}`);
}
// ...
}
```
...@@ -80,7 +80,7 @@ Before using the APIs provided by **EventHub**, you must obtain an **EventHub** ...@@ -80,7 +80,7 @@ Before using the APIs provided by **EventHub**, you must obtain an **EventHub**
4. After **event1** is used, you can call [eventHub.off()](../reference/apis/js-apis-inner-application-eventHub.md#eventhuboff) to unsubscribe from the event. 4. After **event1** is used, you can call [eventHub.off()](../reference/apis/js-apis-inner-application-eventHub.md#eventhuboff) to unsubscribe from the event.
```ts ```ts
// context is the ability-level context of the UIAbility instance. // context is the AbilityContext of the UIAbility instance.
this.context.eventHub.off('event1'); this.context.eventHub.off('event1');
``` ```
...@@ -240,10 +240,6 @@ The following provides an example to describe the object overwritten problem in ...@@ -240,10 +240,6 @@ The following provides an example to describe the object overwritten problem in
struct Index { struct Index {
onPageShow() { onPageShow() {
let ctx = globalThis.context; // Obtain the context from globalThis and use it. let ctx = globalThis.context; // Obtain the context from globalThis and use it.
let permissions = ['com.example.permission']
ctx.requestPermissionsFromUser(permissions,(result) => {
// ...
});
} }
// Page display. // Page display.
build() { build() {
...@@ -251,7 +247,7 @@ The following provides an example to describe the object overwritten problem in ...@@ -251,7 +247,7 @@ The following provides an example to describe the object overwritten problem in
} }
} }
``` ```
3. In the UIAbilityB file, [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) is stored in **globalThis** and has the same name as that in the UIAbilityA file. 3. In the UIAbilityB file, [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) is stored in **globalThis** and has the same name as that in the UIAbilityA file.
```ts ```ts
...@@ -274,10 +270,6 @@ The following provides an example to describe the object overwritten problem in ...@@ -274,10 +270,6 @@ The following provides an example to describe the object overwritten problem in
struct Index { struct Index {
onPageShow() { onPageShow() {
let ctx = globalThis.context; // Obtain the context from globalThis and use it. let ctx = globalThis.context; // Obtain the context from globalThis and use it.
let permissions = ['com.example.permission']
ctx.requestPermissionsFromUser(permissions,(result) => {
console.info('requestPermissionsFromUser result:' + JSON.stringify(result));
});
} }
// Page display. // Page display.
build() { build() {
...@@ -285,7 +277,7 @@ The following provides an example to describe the object overwritten problem in ...@@ -285,7 +277,7 @@ The following provides an example to describe the object overwritten problem in
} }
} }
``` ```
5. Switch the UIAbilityB instance to the background and switch the UIAbilityA instance to the foreground. In this case, UIAbilityA will not enter the **onCreate()** lifecycle again. 5. Switch the UIAbilityB instance to the background and switch the UIAbilityA instance to the foreground. In this case, UIAbilityA will not enter the **onCreate()** lifecycle again.
```ts ```ts
...@@ -307,10 +299,6 @@ The following provides an example to describe the object overwritten problem in ...@@ -307,10 +299,6 @@ The following provides an example to describe the object overwritten problem in
struct Index { struct Index {
onPageShow() { onPageShow() {
let ctx = globalThis.context; // The context in globalThis is the context of UIAbilityB. let ctx = globalThis.context; // The context in globalThis is the context of UIAbilityB.
let permissions=['com.example.permission'];
ctx.requestPermissionsFromUser(permissions,(result) => { // Using this object causes a process breakdown.
console.info('requestPermissionsFromUser result:' + JSON.stringify(result));
});
} }
// Page display. // Page display.
build() { build() {
......
...@@ -19,7 +19,7 @@ Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbility ...@@ -19,7 +19,7 @@ Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbility
**Figure 1** Demonstration effect in singleton mode **Figure 1** Demonstration effect in singleton mode
![uiability-launch-type1](figures/uiability-launch-type1.png) ![uiability-launch-type1](figures/uiability-launch-type1.png)
> **NOTE** > **NOTE**
> >
...@@ -47,9 +47,9 @@ To use the singleton mode, set **launchType** in the [module.json5 configuration ...@@ -47,9 +47,9 @@ To use the singleton mode, set **launchType** in the [module.json5 configuration
In standard mode, each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, a new UIAbility instance of this type is created in the application process. Multiple UIAbility instances of this type are displayed in **Recents**. In standard mode, each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, a new UIAbility instance of this type is created in the application process. Multiple UIAbility instances of this type are displayed in **Recents**.
**Figure 2** Demonstration effect in standard mode **Figure 2** Demonstration effect in standard mode
![standard-mode](figures/standard-mode.png) ![standard-mode](figures/standard-mode.png)
To use the standard mode, set **launchType** in the [module.json5 configuration file](../quick-start/module-configuration-file.md) to **standard**. To use the standard mode, set **launchType** in the [module.json5 configuration file](../quick-start/module-configuration-file.md) to **standard**.
...@@ -75,12 +75,12 @@ The **specified** mode is used in some special scenarios. For example, in a docu ...@@ -75,12 +75,12 @@ The **specified** mode is used in some special scenarios. For example, in a docu
**Figure 3** Demonstration effect in specified mode **Figure 3** Demonstration effect in specified mode
![uiability-launch-type2](figures/uiability-launch-type2.png) ![uiability-launch-type2](figures/uiability-launch-type2.png)
For example, there are EntryAbility and SpecifiedAbility, and the launch type of SpecifiedAbility is set to **specified**. You are required to start SpecifiedAbility from EntryAbility. For example, there are two UIAbility components: EntryAbility and SpecifiedAbility (with the launch type **specified**). You are required to start SpecifiedAbility from EntryAbility.
1. In SpecifiedAbility, set the **launchType** field in the [module.json5 file](../quick-start/module-configuration-file.md) to **specified**.
1. In SpecifiedAbility, set the **launchType** field in the [module.json5 configuration file](../quick-start/module-configuration-file.md) to **specified**.
```json ```json
{ {
"module": { "module": {
...@@ -95,9 +95,8 @@ For example, there are EntryAbility and SpecifiedAbility, and the launch type of ...@@ -95,9 +95,8 @@ For example, there are EntryAbility and SpecifiedAbility, and the launch type of
} }
``` ```
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. 2. Create a unique string key for the instance. Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, the application, based on the key, identifies the UIAbility instance used to respond to the 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 instance.
In EntryAbility, add a custom parameter, for example, **instanceKey**, to the [want](want-overview.md) parameter in [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to distinguish the UIAbility instances.
```ts ```ts
// Configure an independent key for each UIAbility instance. // Configure an independent key for each UIAbility instance.
// For example, in the document usage scenario, use the document path as the key. // For example, in the document usage scenario, use the document path as the key.
...@@ -114,17 +113,18 @@ For example, there are EntryAbility and SpecifiedAbility, and the launch type of ...@@ -114,17 +113,18 @@ For example, there are EntryAbility and SpecifiedAbility, and the launch type of
instanceKey: getInstance(), instanceKey: getInstance(),
}, },
} }
// context is the ability-level context of the initiator UIAbility. // context is the UIAbilityContext of the initiator UIAbility.
this.context.startAbility(want).then(() => { this.context.startAbility(want).then(() => {
// ... // ...
}).catch((err) => { }).catch((err) => {
// ... // ...
}) })
``` ```
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. 3. Before SpecifiedAbility is started, the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback of the corresponding AbilityStage instance is invoked to obtain the key of the UIAbility, because the launch type of SpecifiedAbility is set to **specified**. If a UIAbility instance matching the key exists, the system starts the UIAbility instance and invokes its [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback. Otherwise, the system creates a new UIAbility instance and invokes its [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks.
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.
In the sample code, the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback parses the **want** parameter to obtain the custom parameter **instanceKey**. The service logic returns a key string based on **instanceKey** parameter to identify the UIAbility instance. If the returned key maps to a started UIAbility instance, the system pulls the UIAbility instance back to the foreground and obtains the focus. If the returned key does not map to a started UIAbility instance, the system creates a new UIAbility instance and starts it.
```ts ```ts
import AbilityStage from '@ohos.app.ability.AbilityStage'; import AbilityStage from '@ohos.app.ability.AbilityStage';
...@@ -133,7 +133,7 @@ For example, there are EntryAbility and SpecifiedAbility, and the launch type of ...@@ -133,7 +133,7 @@ For example, there are EntryAbility and SpecifiedAbility, and the launch type of
// 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 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. // In this example, SpecifiedAbility of module1 is returned.
if (want.abilityName === 'SpecifiedAbility') { if (want.abilityName === 'SpecifiedAbility') {
// The returned string key is a custom string. // The returned key string is a custom string.
return `SpecifiedAbilityInstance_${want.parameters.instanceKey}`; return `SpecifiedAbilityInstance_${want.parameters.instanceKey}`;
} }
...@@ -141,22 +141,17 @@ For example, there are EntryAbility and SpecifiedAbility, and the launch type of ...@@ -141,22 +141,17 @@ For example, there are EntryAbility and SpecifiedAbility, and the launch type of
} }
} }
``` ```
> **NOTE** > **NOTE**
> >
> 1. Assume that the application already has a UIAbility instance created, and the launch type of the UIAbility instance is set to **specified**. If [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called again to start the UIAbility instance, and the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback of [AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md) matches a created UIAbility instance, the original UIAbility instance is started, and no new UIAbility instance is created. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback is invoked, but the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks are not. > 1. Assume that the application already has a UIAbility instance created, and the launch type of the UIAbility instance is set to **specified**. If [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called again to start the UIAbility instance, and the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback of [AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md) matches a created UIAbility instance, the original UIAbility instance is started, and no new UIAbility instance is created. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback is invoked, but the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks are not.
> 2. AbilityStage is not automatically generated in the default project of DevEco Studio. For details about how to create an AbilityStage file, see [AbilityStage Component Container](abilitystage.md). > 2. AbilityStage is not automatically generated in the default project of DevEco Studio. For details about how to create an AbilityStage file, see [AbilityStage Component Container](abilitystage.md).
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. For example, in the document application, different keys are bound to different document instances. Each time a document is created, a new key (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. 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. 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. 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. This is because the system automatically matches the key of the UIAbility instance and starts the UIAbility instance that has a matching key. In this example, UIAbility instance 2 has the same key as file A. Therefore, the system pulls back UIAbility instance 2 and focuses it without creating a new instance.
4. Return to the home screen and open file A again. UIAbility instance 2 is started.
<!--no_check-->
\ No newline at end of file
...@@ -3,10 +3,27 @@ ...@@ -3,10 +3,27 @@
## Overview ## Overview
UIAbility has the UI and is mainly used for user interaction. UIAbility is a type of application component that provides the UI 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**. The following design philosophy is behind UIAbility:
1. 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
2. Support for multiple device types and window forms
For details, see [Interpretation of the Application Model](application-model-description.md).
The UIAbility division principles and suggestions are as follows:
UIAbility is the basic unit scheduled by the system and provides a window for applications to draw UIs. An application can contain one or more UIAbility components. For example, for a payment application, you can use two UIAbility components to carry the entry and payment functionalities.
Each UIAbility component instance is displayed as a mission in Recents.
You can develop a single UIAbility or multiple UIAbilities for your application based on service requirements.
- If you want only one mission to be displayed in Recents, use one UIAbility and multiple pages.
- If you want multiple missions to be displayed in Recents or multiple windows to be opened simultaneously, use multiple UIAbilities.
## Privacy Statement Configuration ## Privacy Statement Configuration
...@@ -32,8 +49,3 @@ To enable an application to properly use a UIAbility component, declare the UIAb ...@@ -32,8 +49,3 @@ To enable an application to properly use a UIAbility component, declare the UIAb
} }
} }
``` ```
> **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).
# WindowExtensionAbility
[WindowExtensionAbility](../reference/apis/js-apis-application-windowExtensionAbility.md) is a type of ExtensionAbility component that allows a system application to be embedded in and displayed over another application.
The WindowExtensionAbility component must be used together with the [AbilityComponent](../reference/arkui-ts/ts-container-ability-component.md) to process services of the started application. WindowExtensionAbility is run in connection mode. A system application must use the AbilityComponent to start the WindowExtensionAbility component.
Each ExtensionAbility has its own context. For WindowExtensionAbility,
the context is [WindowExtensionContext](../reference/apis/js-apis-inner-application-windowExtensionContext.md).
> **NOTE**
>
> **WindowExtensionAbility** is a system API. To embed a third-party application in another application and display it over the application, switch to the full SDK by following the instructions provided in [Guide to Switching to Full SDK](../../application-dev/quick-start/full-sdk-switch-guide.md).
>
## Setting an Embedded Ability (for System Applications Only)
The **WindowExtensionAbility** class provides **onConnect()**, **onDisconnect()**, and **onWindowReady()** lifecycle callbacks, which can be overridden.
- The **onWindowReady()** callback is invoked when a window is created for the ability.
- The **onConnect()** callback is invoked when the AbilityComponent corresponding to the window connects to the ability.
- The **onDisconnect()** callback is invoked when the AbilityComponent disconnects from the ability.
**How to Develop**
To implement an embedded application, manually create a WindowExtensionAbility in DevEco Studio as follows:
1. In the **ets** directory of the **Module** project, right-click and choose **New > Directory** to create a directory named **WindowExtAbility**.
2. Right-click the **WindowExtAbility** directory, and choose **New > TypeScript File** to create a file named **WindowExtAbility.ts**.
3. Open the **WindowExtAbility.ts** file and import the dependency package of **WindowExtensionAbility**. Customize a class that inherits from **WindowExtensionAbility** and implement the **onWindowReady()**, **onConnect()**, and **onDisconnect()** lifecycle callbacks.
```ts
import Extension from '@ohos.application.WindowExtensionAbility'
export default class WindowExtAbility extends Extension {
onWindowReady(window) {
window.loadContent('WindowExtAbility/pages/index1').then(() => {
window.getProperties().then((pro) => {
console.log("WindowExtension " + JSON.stringify(pro));
})
window.show();
})
}
onConnect(want) {
console.info('JSWindowExtension onConnect ' + want.abilityName);
}
onDisconnect(want) {
console.info('JSWindowExtension onDisconnect ' + want.abilityName);
}
}
```
4. Register the WindowExtensionAbility in the [module.json5 file](../quick-start/module-configuration-file.md) corresponding to the **Module** project. Set **type** to **"window"** and **srcEntrance** to the code path of the ExtensionAbility component.
```json
{
"module": {
"extensionAbilities": [
{
"name": "WindowExtAbility",
"srcEntrance": "./ets/WindowExtAbility/WindowExtAbility.ts",
"icon": "$media:icon",
"description": "WindowExtension",
"type": "window",
"visible": true,
}
],
}
}
```
## Starting an Embedded Ability (for System Applications Only)
System applications can load the created WindowExtensionAbility through the AbilityComponent.
**How to Develop**
1. To connect to an embedded application, add the AbilityComponent to the corresponding pages in the DevEco Studio project.
2. Set **bundleName** and **abilityName** in the AbilityComponent.
3. Set the width and height. The sample code is as follows:
```ts
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
AbilityComponent({ abilityName: "WindowExtAbility", bundleName: "com.example.WindowExtAbility"})
.width(500)
.height(500)
}
.width('100%')
}
.height('100%')
.backgroundColor(0x64BB5c)
}
}
```
...@@ -108,7 +108,7 @@ You write a UI test script based on the unit test framework, adding the invoking ...@@ -108,7 +108,7 @@ You write a UI test script based on the unit test framework, adding the invoking
In this example, the UI test script is written based on the preceding unit test script. First, add the dependency package, as shown below: In this example, the UI test script is written based on the preceding unit test script. First, add the dependency package, as shown below:
```js ```js
import {UiDriver,BY,UiComponent,MatchPattern} from '@ohos.uitest' import {Driver,ON,Component,MatchPattern} from '@ohos.uitest'
``` ```
Then, write specific test code. Specifically, implement the click action on the started application page and add checkpoint check cases. Then, write specific test code. Specifically, implement the click action on the started application page and add checkpoint check cases.
...@@ -131,16 +131,16 @@ export default function abilityTest() { ...@@ -131,16 +131,16 @@ export default function abilityTest() {
expect(Ability.context.abilityInfo.name).assertEqual('EntryAbility'); expect(Ability.context.abilityInfo.name).assertEqual('EntryAbility');
}) })
//ui test code //ui test code
//init uidriver //init driver
var driver = await UiDriver.create(); var driver = await Driver.create();
await driver.delayMs(1000); await driver.delayMs(1000);
//find button by text 'Next' //find button on text 'Next'
var button = await driver.findComponent(BY.text('Next')); var button = await driver.findComponent(ON.text('Next'));
//click button //click button
await button.click(); await button.click();
await driver.delayMs(1000); await driver.delayMs(1000);
//check text //check text
await driver.assertComponentExist(BY.text('after click')); await driver.assertComponentExist(ON.text('after click'));
await driver.pressBack(); await driver.pressBack();
done(); done();
}) })
...@@ -195,14 +195,15 @@ The framework supports multiple test case execution modes, which are triggered b ...@@ -195,14 +195,15 @@ The framework supports multiple test case execution modes, which are triggered b
| itName | Test case to be executed. | {itName} | -s itName testAttributeIt | | itName | Test case to be executed. | {itName} | -s itName testAttributeIt |
| timeout | Timeout interval for executing a test case. | Positive integer (unit: ms). If no value is set, the default value 5000 is used. | -s timeout 15000 | | timeout | Timeout interval for executing a test case. | Positive integer (unit: ms). If no value is set, the default value 5000 is used. | -s timeout 15000 |
| breakOnError | Whether to enable break-on-error mode. When this mode is enabled, the test execution process exits if a test assertion error or any other error occurs.| **true**/**false** (default value) | -s breakOnError true | | breakOnError | Whether to enable break-on-error mode. When this mode is enabled, the test execution process exits if a test assertion error or any other error occurs.| **true**/**false** (default value) | -s breakOnError true |
| random | Whether to execute test cases in random sequence.| **true**/**false** (default value) | -s random true |
| testType | Type of the test case to be executed. | function, performance, power, reliability, security, global, compatibility, user, standard, safety, resilience| -s testType function | | testType | Type of the test case to be executed. | function, performance, power, reliability, security, global, compatibility, user, standard, safety, resilience| -s testType function |
| level | Level of the test case to be executed. | 0, 1, 2, 3, 4 | -s level 0 | | level | Level of the test case to be executed. | 0, 1, 2, 3, 4 | -s level 0 |
| size | Size of the test case to be executed. | small, medium, large | -s size small | | size | Size of the test case to be executed. | small, medium, large | -s size small |
| stress | Number of times that the test case is executed. | Positive integer | -s stress 1000 | | stress | Number of times that the test case is executed. | Positive integer | -s stress 1000 |
**Running Commands** **Running Commands**
> Configure hdc-related environment variables, and then perform the following: > Before running commands in the CLI, make sure hdc-related environment variables have been configured.
- Open the CLI. - Open the CLI.
- Run the **aa test** commands. - Run the **aa test** commands.
......
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
- [HTTP Data Request](http-request.md) - [HTTP Data Request](http-request.md)
- [WebSocket Connection](websocket-connection.md) - [WebSocket Connection](websocket-connection.md)
- [Socket Connection](socket-connection.md) - [Socket Connection](socket-connection.md)
- [Network Policy Management](net-policy-management.md)
- [Network Sharing](net-sharing.md)
- [Ethernet Connection](net-ethernet.md)
- [Network Connection Management](net-connection-manager.md)
- IPC & RPC - IPC & RPC
- [IPC & RPC Overview](ipc-rpc-overview.md) - [IPC & RPC Overview](ipc-rpc-overview.md)
- [IPC & RPC Development](ipc-rpc-development-guideline.md) - [IPC & RPC Development](ipc-rpc-development-guideline.md)
......
# HTTP Data Request # HTTP Data Request
## Use Cases ## When to Use
An application can initiate a data request over HTTP. Common HTTP methods include **GET**, **POST**, **OPTIONS**, **HEAD**, **PUT**, **DELETE**, **TRACE**, and **CONNECT**. An application can initiate a data request over HTTP. Common HTTP methods include **GET**, **POST**, **OPTIONS**, **HEAD**, **PUT**, **DELETE**, **TRACE**, and **CONNECT**.
...@@ -14,40 +14,49 @@ For details about how to apply for permissions, see [Access Control Development] ...@@ -14,40 +14,49 @@ For details about how to apply for permissions, see [Access Control Development]
The following table provides only a simple description of the related APIs. For details, see [API Reference](../reference/apis/js-apis-http.md). The following table provides only a simple description of the related APIs. For details, see [API Reference](../reference/apis/js-apis-http.md).
| API | Description | | API | Description |
| ----------------------------------------- | --------------------------------------------------------- | | ----------------------------------------- | ----------------------------------- |
| createHttp() | Creates an HTTP request. | | createHttp() | Creates an HTTP request. |
| request() | Initiates an HTTP request to a given URL. | | request() | Initiates an HTTP request to a given URL. |
| destroy() | Destroys an HTTP request. | | request2()<sup>10+</sup> | Initiates an HTTP network request based on the URL and returns a streaming response.|
| destroy() | Destroys an HTTP request. |
| on(type: 'headersReceive') | Registers an observer for HTTP Response Header events. | | on(type: 'headersReceive') | Registers an observer for HTTP Response Header events. |
| off(type: 'headersReceive') | Unregisters the observer for HTTP Response Header events. | | off(type: 'headersReceive') | Unregisters the observer for HTTP Response Header events.|
| once\('headersReceive'\)<sup>8+</sup> | Registers a one-time observer for HTTP Response Header events.|
| on\('dataReceive'\)<sup>10+</sup> | Registers an observer for events indicating receiving of HTTP streaming responses. |
| off\('dataReceive'\)<sup>10+</sup> | Unregisters the observer for events indicating receiving of HTTP streaming responses. |
| on\('dataEnd'\)<sup>10+</sup> | Registers an observer for events indicating completion of receiving HTTP streaming responses. |
| off\('dataEnd'\)<sup>10+</sup> | Unregisters the observer for events indicating completion of receiving HTTP streaming responses.|
| on\('dataProgress'\)<sup>10+</sup> | Registers an observer for events indicating progress of receiving HTTP streaming responses. |
| off\('dataProgress'\)<sup>10+</sup> | Unregisters the observer for events indicating progress of receiving HTTP streaming responses.|
## How to Develop ## How to Develop request APIs
1. Import the required HTTP module. 1. Import the **http** namespace from **@ohos.net.http.d.ts**.
2. Create an **HttpRequest** object. 2. Call **createHttp()** to create an **HttpRequest** object.
3. (Optional) Listen for HTTP Response Header events. 3. Call **httpRequest.on()** to subscribe to HTTP response header events. This API returns a response earlier than the request. You can subscribe to HTTP response header events based on service requirements.
4. Initiate an HTTP request to a given URL. 4. Call **httpRequest.request()** to initiate a network request. You need to pass in the URL and optional parameters of the HTTP request.
5. (Optional) Process the HTTP Response Header event and the return result of the HTTP request. 5. Parse the returned result based on service requirements.
6. Call **off()** to unsubscribe from HTTP response header events.
7. Call **httpRequest.destroy()** to release resources after the request is processed.
```js ```js
// Import the http namespace.
import http from '@ohos.net.http'; import http from '@ohos.net.http';
// Each HttpRequest corresponds to an HttpRequestTask object and cannot be reused. // Each httpRequest corresponds to an HTTP request task and cannot be reused.
let httpRequest = http.createHttp(); let httpRequest = http.createHttp();
// This API is used to listen for the HTTP Response Header event, which is returned earlier than the result of the HTTP request. It is up to you whether to listen for HTTP Response Header events.
// Subscribe to the HTTP response header, which is returned earlier than HttpRequest. You can subscribe to HTTP Response Header events based on service requirements. // on('headerReceive', AsyncCallback) is replaced by on('headersReceive', Callback) since API version 8.
// on('headerReceive', AsyncCallback) will be replaced by on('headersReceive', Callback) in API version 8. 8+
httpRequest.on('headersReceive', (header) => { httpRequest.on('headersReceive', (header) => {
console.info('header: ' + JSON.stringify(header)); console.info('header: ' + JSON.stringify(header));
}); });
httpRequest.request( httpRequest.request(
// Set the URL of the HTTP request. You need to define the URL. Set the parameters of the request in extraData. // Customize EXAMPLE_URL in extraData on your own. It is up to you whether to add parameters to the URL.
"EXAMPLE_URL", "EXAMPLE_URL",
{ {
method: http.RequestMethod.POST, // Optional. The default value is http.RequestMethod.GET. method: http.RequestMethod.POST, // Optional. The default value is http.RequestMethod.GET.
// You can add the header field based on service requirements. // You can add header fields based on service requirements.
header: { header: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
...@@ -55,21 +64,105 @@ httpRequest.request( ...@@ -55,21 +64,105 @@ httpRequest.request(
extraData: { extraData: {
"data": "data to send", "data": "data to send",
}, },
connectTimeout: 60000, // Optional. The default value is 60000, in ms. expectDataType: http.HttpDataType.STRING, // Optional. This field specifies the type of the return data.
usingCache: true, // Optional. The default value is true.
priority: 1, // Optional. The default value is 1.
connectTimeout: 60000 // Optional. The default value is 60000, in ms.
readTimeout: 60000, // Optional. The default value is 60000, in ms. readTimeout: 60000, // Optional. The default value is 60000, in ms.
usingProtocol: http.HttpProtocol.HTTP1_1, // Optional. The default protocol type is automatically specified by the system.
usingProxy: false, // Optional. By default, network proxy is not used. This field is supported since API 10.
}, (err, data) => { }, (err, data) => {
if (!err) { if (!err) {
// data.result contains the HTTP response. Parse the response based on service requirements. // data.result carries the HTTP response. Parse the response based on service requirements.
console.info('Result:' + data.result); console.info('Result:' + JSON.stringify(data.result));
console.info('code:' + data.responseCode); console.info('code:' + JSON.stringify(data.responseCode));
// data.header contains the HTTP response header. Parse the content based on service requirements. // data.header carries the HTTP response header. Parse the content based on service requirements.
console.info('header:' + JSON.stringify(data.header)); console.info('header:' + JSON.stringify(data.header));
console.info('cookies:' + data.cookies); // 8+ console.info('cookies:' + JSON.stringify(data.cookies)); // 8+
} else { } else {
console.info('error:' + JSON.stringify(err)); console.info('error:' + JSON.stringify(err));
// Call the destroy() method to destroy the request if it is no longer needed. // Unsubscribe from HTTP Response Header events.
httpRequest.off('headersReceive');
// Call the destroy() method to release resources after HttpRequest is complete.
httpRequest.destroy(); httpRequest.destroy();
} }
} }
); );
``` ```
## How to Develop request2 APIs
1. Import the **http** namespace from **@ohos.net.http.d.ts**.
2. Call **createHttp()** to create an **HttpRequest** object.
3. Depending on your need, call **on()** of the **HttpRequest** object to subscribe to HTTP response header events as well as events indicating receiving of HTTP streaming responses, progress of receiving HTTP streaming responses, and completion of receiving HTTP streaming responses.
4. Call **request2()** to initiate a network request. You need to pass in the URL and optional parameters of the HTTP request.
5. Parse the returned response code as needed.
6. Call **off()** of the **HttpRequest** object to unsubscribe from the related events.
7. Call **httpRequest.destroy()** to release resources after the request is processed.
```js
// Import the http namespace.
import http from '@ohos.net.http'
// Each httpRequest corresponds to an HTTP request task and cannot be reused.
let httpRequest = http.createHttp();
// Subscribe to HTTP response header events.
httpRequest.on('headersReceive', (header) => {
console.info('header: ' + JSON.stringify(header));
});
// Subscribe to events indicating receiving of HTTP streaming responses.
let res = '';
httpRequest.on('dataReceive', (data) => {
res += data;
console.info('res: ' + res);
});
// Subscribe to events indicating completion of receiving HTTP streaming responses.
httpRequest.on('dataEnd', () => {
console.info('No more data in response, data receive end');
});
// Subscribe to events indicating progress of receiving HTTP streaming responses.
httpRequest.on('dataProgress', (data) => {
console.log("dataProgress receiveSize:" + data.receiveSize+ ", totalSize:" + data.totalSize);
});
httpRequest.request2(
// Customize EXAMPLE_URL in extraData on your own. It is up to you whether to add parameters to the URL.
"EXAMPLE_URL",
{
method: http.RequestMethod.POST, // Optional. The default value is http.RequestMethod.GET.
// You can add header fields based on service requirements.
header: {
'Content-Type': 'application/json'
},
// This field is used to transfer data when the POST request is used.
extraData: {
"data": "data to send",
},
expectDataType: http.HttpDataType.STRING, // Optional. This field specifies the type of the return data.
usingCache: true, // Optional. The default value is true.
priority: 1, // Optional. The default value is 1.
connectTimeout: 60000 // Optional. The default value is 60000, in ms.
readTimeout: 60000, // Optional. The default value is 60000, in ms. If a large amount of data needs to be transmitted, you are advised to set this parameter to a larger value to ensure normal data transmission.
usingProtocol: http.HttpProtocol.HTTP1_1, // Optional. The default protocol type is automatically specified by the system.
}, (err, data) => {
console.info('error:' + JSON.stringify(err));
console.info('ResponseCode :' + JSON.stringify(data));
// Unsubscribe from HTTP Response Header events.
httpRequest.off('headersReceive');
// Unregister the observer for events indicating receiving of HTTP streaming responses.
httpRequest.off('dataReceive');
// Unregister the observer for events indicating progress of receiving HTTP streaming responses.
httpRequest.off('dataProgress');
// Unregister the observer for events indicating completion of receiving HTTP streaming responses.
httpRequest.off('dataEnd');
// Call the destroy() method to release resources after HttpRequest is complete.
httpRequest.destroy();
}
);
```
## Samples
The following sample is provided to help you better understand how to develop the HTTP data request feature:
- [HTTP Data Request (ArkTS) (API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/Http)
- [HTTP Communication (ArkTS) (API9)](https://gitee.com/openharmony/codelabs/tree/master/NetworkManagement/SmartChatEtsOH)
# IPC & RPC Development Guidelines # IPC & RPC Development
## When to Use ## When to Use
......
# Network Connection Management
## Introduction
The Network Connection Management module provides basic network management capabilities, including management of Wi-Fi/cellular/Ethernet connection priorities, network quality evaluation, subscription to network connection status changes, query of network connection information, and DNS resolution.
> **NOTE**
> To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [sms API Reference](../reference/apis/js-apis-net-connection.md).
## Basic Concepts
- Producer: a provider of data networks, such as Wi-Fi, cellular, and Ethernet.
- Consumer: a user of data networks, for example, an application or a system service.
- Network probe: a mechanism used to detect the network availability to prevent the switch from an available network to an unavailable network. The probe type can be binding network detection, DNS detection, HTTP detection, or HTTPS detection.
- Network selection: a mechanism used to select the optimal network when multiple networks coexist. It is triggered when the network status, network information, or network quality evaluation score changes.
## **Constraints**
- Programming language: C++ and JS
- System: Linux kernel
- The initial APIs of this module are supported since API version 8. Newly added APIs will be marked with a superscript to indicate their earliest API version.
## When to Use
Typical application scenarios of network connection management are as follows:
- Subscribing to status changes of the specified network
- Obtaining the list of all registered networks
- Querying network connection information based on the data network
- Resolving the domain name of a network to obtain all IP addresses
The following describes the development procedure specific to each application scenario.
## Available APIs
For the complete list of APIs and example code, see [Network Connection Management](../reference/apis/js-apis-net-connection.md).
| Type| API| Description|
| ---- | ---- | ---- |
| ohos.net.connection | function getDefaultNet(callback: AsyncCallback\<NetHandle>): void; |Creates a **NetHandle** object that contains the **netId** of the default network. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function getGlobalHttpProxy<sup>10+</sup>(callback: AsyncCallback\<HttpProxy>): void;| Obtains the global HTTP proxy for the network. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function setGlobalHttpProxy<sup>10+</sup>(httpProxy: HttpProxy, callback: AsyncCallback<void>): void;| Sets the global HTTP proxy for the network. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function getAppNet<sup>9+</sup>(callback: AsyncCallback\<NetHandle>): void;| Obtains a **NetHandle** object that contains the **netId** of the network bound to the application. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function setAppNet<sup>9+</sup>(netHandle: NetHandle, callback: AsyncCallback\<void>): void;| Binds an application to the specified network. The application can access the external network only through this network. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function getDefaultNetSync<sup>9+</sup>(): NetHandle; |Obtains the default active data network in synchronous mode. You can use **getNetCapabilities** to obtain information such as the network type and capabilities.|
| ohos.net.connection | function hasDefaultNet(callback: AsyncCallback\<boolean>): void; |Checks whether the default network is available. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function getAllNets(callback: AsyncCallback\<Array\<NetHandle>>): void;| Obtains the list of **NetHandle** objects of the connected network. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function getConnectionProperties(netHandle: NetHandle, callback: AsyncCallback\<ConnectionProperties>): void; |Obtains link information of the default network. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function getNetCapabilities(netHandle: NetHandle, callback: AsyncCallback\<NetCapabilities>): void; |Obtains the capability set of the default network. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function isDefaultNetMetered<sup>9+</sup>(callback: AsyncCallback<boolean>): void; |Checks whether the data traffic usage on the current network is metered. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function reportNetConnected(netHandle: NetHandle, callback: AsyncCallback\<void>): void;| Reports a **netAavailable** event to NetManager. If this API is called, the application considers that its network status (ohos.net.connection.NetCap.NET_CAPABILITY_VAILDATED) is inconsistent with that of NetManager. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function reportNetDisconnected(netHandle: NetHandle, callback: AsyncCallback\<void>): void;| Reports a **netAavailable** event to NetManager. If this API is called, the application considers that its network status (ohos.net.connection.NetCap.NET_CAPABILITY_VAILDATED) is inconsistent with that of NetManager. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function getAddressesByName(host: string, callback: AsyncCallback\<Array\<NetAddress>>): void; |Obtains all IP addresses of the specified network by resolving the domain name. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function enableAirplaneMode(callback: AsyncCallback\<void>): void; | Enables the airplane mode. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function disableAirplaneMode(callback: AsyncCallback\<void>): void;| Disables the airplane mode. This API uses an asynchronous callback to return the result.|
| ohos.net.connection | function createNetConnection(netSpecifier?: NetSpecifier, timeout?: number): NetConnection; | Creates a **NetConnection** object. **netSpecifier** specifies the network, and **timeout** specifies the timeout interval in ms. **timeout** is configurable only when **netSpecifier** is specified. If neither of them is present, the default network is used.|
| ohos.net.connection.NetHandle | bindSocket(socketParam: TCPSocket \| UDPSocket, callback: AsyncCallback\<void>): void; | Binds a **TCPSocket** or **UDPSocket** to the current network. This API uses an asynchronous callback to return the result.|
| ohos.net.connection.NetHandle | getAddressesByName(host: string, callback: AsyncCallback\<Array\<NetAddress>>): void; |Obtains all IP addresses of the default network by resolving the domain name. This API uses an asynchronous callback to return the result.|
| ohos.net.connection.NetHandle | getAddressByName(host: string, callback: AsyncCallback\<NetAddress>): void; |Obtains an IP address of the specified network by resolving the domain name. This API uses an asynchronous callback to return the result.|
| ohos.net.connection.NetConnection | on(type: 'netAvailable', callback: Callback\<NetHandle>): void; |Subscribes to **netAvailable** events.|
| ohos.net.connection.NetConnection | on(type: 'netCapabilitiesChange', callback: Callback\<{ netHandle: NetHandle, netCap: NetCapabilities }>): void; |Subscribes to **netCapabilitiesChange** events.|
| ohos.net.connection.NetConnection | on(type: 'netConnectionPropertiesChange', callback: Callback\<{ netHandle: NetHandle, connectionProperties: ConnectionProperties }>): void; |Subscribes to **netConnectionPropertiesChange** events.|
| ohos.net.connection.NetConnection | on(type: 'netBlockStatusChange', callback: Callback<{ netHandle: NetHandle, blocked: boolean }>): void; |Subscribes to **netBlockStatusChange** events.|
| ohos.net.connection.NetConnection | on(type: 'netLost', callback: Callback\<NetHandle>): void; |Subscribes to **netLost** events.|
| ohos.net.connection.NetConnection | on(type: 'netUnavailable', callback: Callback\<void>): void; |Subscribes to **netUnavailable** events.|
| ohos.net.connection.NetConnection | register(callback: AsyncCallback\<void>): void; |Registers an observer for the default network or the network specified in **createNetConnection**.|
| ohos.net.connection.NetConnection | unregister(callback: AsyncCallback\<void>): void; |Unregisters the observer for the default network or the network specified in **createNetConnection**.|
## Subscribing to Status Changes of the Specified Network
1. Import the connection namespace from **@ohos.net.connection.d.ts**.
2. Call **createNetConnection()** to create a **NetConnection** object. You can specify the network type, capability, and timeout interval. If you do not specify parameters, the default values will be used.
3. Call **conn.on()** to subscribe to the target event. You must pass in **type** and **callback**.
4. Call **conn.register()** to subscribe to network status changes of the specified network.
5. When the network is available, the callback will be invoked to return the **netAvailable** event. When the network is unavailable, the callback will be invoked to return the **netUnavailable** event.
6. Call **conn.unregister()** to unsubscribe from the network status changes if required.
```js
// Import the connection namespace.
import connection from '@ohos.net.connection'
let netCap = {
// Assume that the default network is Wi-Fi. If you need to create a cellular network connection, set the network type to CELLULAR.
bearerTypes: [connection.NetBearType.BEARER_CELLULAR],
// Set the network capability to INTERNET.
networkCap: [connection.NetCap.NET_CAPABILITY_INTERNET],
};
let netSpec = {
netCapabilities: netCap,
};
// Set the timeout value to 10s. The default value is 0.
let timeout = 10 * 1000;
// Create a NetConnection object.
let conn = connection.createNetConnection(netSpec, timeout);
// Listen to network status change events. If the network is available, an on_netAvailable event is returned.
conn.on('netAvailable', (data=> {
console.log("net is available, netId is " + data.netId);
}));
// Listen to network status change events. If the network is unavailable, an on_netUnavailable event is returned.
conn.on('netUnavailable', (data=> {
console.log("net is unavailable, netId is " + data.netId);
}));
// Register an observer for network status changes.
conn.register((err, data) => {});
// Unregister the observer for network status changes.
conn.unregister((err, data) => {});
```
## Obtaining the List of All Registered Networks
### How to Develop
1. Import the connection namespace from **@ohos.net.connection.d.ts**.
2. Call **getAllNets** to obtain the list of all connected networks.
```js
// Import the connection namespace.
import connection from '@ohos.net.connection'
// Obtain the list of all connected networks.
connection.getAllNets((err, data) => {
console.log(JSON.stringify(err));
console.log(JSON.stringify(data));
if (data) {
this.netList = data;
}
})
```
## Querying Network Capability Information and Connection Information of Specified Data Network
### How to Develop
1. Import the connection namespace from **@ohos.net.connection.d.ts**.
2. Call **getDefaultNet** to obtain the default data network via **NetHandle** or call **getAllNets** to obtain the list of all connected networks via **Array\<NetHandle>**.
3. Call **getNetCapabilities** to obtain the network capability information of the data network specified by **NetHandle**. The capability information includes information such as the network type (cellular, Wi-Fi, or Ethernet network) and the specific network capabilities.
4. Call **getConnectionProperties** to obtain the connection information of the data network specified by **NetHandle**.
```js
// Import the connection namespace.
import connection from '@ohos.net.connection'
// Call getDefaultNet to obtain the default data network specified by **NetHandle**.
connection.getDefaultNet((err, data) => {
console.log(JSON.stringify(err));
console.log(JSON.stringify(data));
if (data) {
this.netHandle = data;
}
})
// Obtain the network capability information of the data network specified by **NetHandle**. The capability information includes information such as the network type and specific network capabilities.
connection.getNetCapabilities(this.netHandle, (err, data) => {
console.log(JSON.stringify(err));
// Obtain the network type via bearerTypes.
for (let item of data.bearerTypes) {
if (item == 0) {
// Cellular network
console.log(JSON.stringify("BEARER_CELLULAR"));
} else if (item == 1) {
// Wi-Fi network
console.log(JSON.stringify("BEARER_WIFI"));
} else if (item == 3) {
// Ethernet network
console.log(JSON.stringify("BEARER_ETHERNET"));
}
}
// Obtain the specific network capabilities via networkCap.
for (let item of data.networkCap) {
if (item == 0) {
// The network can connect to the carrier's Multimedia Messaging Service Center (MMSC) to send and receive multimedia messages.
console.log(JSON.stringify("NET_CAPABILITY_MMS"));
} else if (item == 11) {
// The network traffic is not metered.
console.log(JSON.stringify("NET_CAPABILITY_NOT_METERED"));
} else if (item == 12) {
// The network has the Internet access capability, which is set by the network provider.
console.log(JSON.stringify("NET_CAPABILITY_INTERNET"));
} else if (item == 15) {
// The network does not use a Virtual Private Network (VPN).
console.log(JSON.stringify("NET_CAPABILITY_NOT_VPN"));
} else if (item == 16) {
// The Internet access capability of the network is successfully verified by the connection management module.
console.log(JSON.stringify("NET_CAPABILITY_VALIDATED"));
}
}
})
// Obtain the connection information of the data network specified by NetHandle. Connection information includes link and route information.
connection.getConnectionProperties(this.netHandle, (err, data) => {
console.log(JSON.stringify(err));
console.log(JSON.stringify(data));
})
// Call getAllNets to obtain the list of all connected networks via Array<NetHandle>.
connection.getAllNets((err, data) => {
console.log(JSON.stringify(err));
console.log(JSON.stringify(data));
if (data) {
this.netList = data;
}
})
for (let item of this.netList) {
// Obtain the network capability information of the network specified by each netHandle on the network list cyclically.
connection.getNetCapabilities(item, (err, data) => {
console.log(JSON.stringify(err));
console.log(JSON.stringify(data));
})
// Obtain the connection information of the network specified by each netHandle on the network list cyclically.
connection.getConnectionProperties(item, (err, data) => {
console.log(JSON.stringify(err));
console.log(JSON.stringify(data));
})
}
```
## Resolving the domain name of a network to obtain all IP addresses
### How to Develop
1. Import the connection namespace from **@ohos.net.connection.d.ts**.
2. Call **getAddressesByName** to use the default network to resolve the host name to obtain the list of all IP addresses.
```js
// Import the connection namespace.
import connection from '@ohos.net.connection'
// Use the default network to resolve the host name to obtain the list of all IP addresses.
connection.getAddressesByName(this.host, (err, data) => {
console.log(JSON.stringify(err));
console.log(JSON.stringify(data));
})
```
此差异已折叠。
...@@ -2,15 +2,19 @@ ...@@ -2,15 +2,19 @@
Network management functions include: Network management functions include:
- [HTTP Data Request](http-request.md): Initiates a data request through HTTP. - [HTTP data request](http-request.md): Initiates a data request through HTTP.
- [WebSocket Connection](websocket-connection.md): Establishes a bidirectional connection between the server and client through WebSocket. - [WebSocket connection](websocket-connection.md): Establishes a bidirectional connection between the server and client through WebSocket.
- [Socket Connection](socket-connection.md): Transmits data through Socket. - [Socket connection](socket-connection.md): Transmits data through Socket.
- [Network policy management](net-policy-management.md): Restricts network capabilities by setting network policies, including cellular network policy, sleep/power-saving mode policy, and background network policy, and resets network policies as needed.
- [Network sharing](net-sharing.md): Shares a device's Internet connection with other connected devices by means of Wi-Fi hotspot, Bluetooth, and USB sharing, and queries the network sharing state and shared mobile data volume.
- [Ethernet connection](net-ethernet.md): Provides wired network capabilities, which allow you to set the IP address, subnet mask, gateway, and Domain Name System (DNS) server of a wired network.
- [Network connection management](net-connection-manager.md): Provides basic network management capabilities, including management of Wi-Fi/cellular/Ethernet connection priorities, network quality evaluation, subscription to network connection status changes, query of network connection information, and DNS resolution.
## Constraints ## Constraints
To use the functions of the network management module, you must obtain the permissions listed in the following table. To use the functions of the network management module, you must obtain the permissions listed in the following table.
| Permission | Description | | Permission | Description |
| -------------------------------- | -------------------------------------- | | -------------------------------- | -------------------------------------- |
| ohos.permission.GET_NETWORK_INFO | Allows an application to obtain the network connection information. | | ohos.permission.GET_NETWORK_INFO | Allows an application to obtain the network connection information. |
| ohos.permission.SET_NETWORK_INFO | Allows an application to modify the network connection state. | | ohos.permission.SET_NETWORK_INFO | Allows an application to modify the network connection state. |
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册