提交 1dd0e0b3 编写于 作者: W Wangkai 提交者: Gitee

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

Signed-off-by: NWangkai <wangkai424@huawei.com>

要显示的变更太多。

To preserve performance only 1000 of 1000+ files are displayed.
...@@ -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
...@@ -531,6 +531,7 @@ zh-cn/application-dev/reference/apis/js-apis-distributedBundle.md @shuaytao @Ray ...@@ -531,6 +531,7 @@ zh-cn/application-dev/reference/apis/js-apis-distributedBundle.md @shuaytao @Ray
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-accountManager.md @liuzuming @ningningW @yangqing3 zh-cn/application-dev/reference/apis/js-apis-enterprise-accountManager.md @liuzuming @ningningW @yangqing3
zh-cn/application-dev/reference/apis/js-apis-enterprise-adminManager.md @liuzuming @ningningW @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-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-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-deviceInfo.md @liuzuming @ningningW @yangqing3
......
...@@ -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 |
......
...@@ -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)
......
...@@ -24,13 +24,13 @@ First thing first, familiarize yourself with the two cornerstone frameworks in O ...@@ -24,13 +24,13 @@ 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) - [Notification](notification/Readme-EN.md)
- [Window Manager](windowmanager/Readme-EN.md) - [Window Manager](windowmanager/Readme-EN.md)
- [WebGL](webgl/Readme-EN.md) - [WebGL](webgl/Readme-EN.md)
- [Media](media/Readme-EN.md) - [Media](media/Readme-EN.md)
- [Security](security/Readme-EN.md) - [Security](security/Readme-EN.md)
- [Connectivity](connectivity/Readme-EN.md) - [Connectivity](connectivity/Readme-EN.md)
- [Telephony](telephony/Readme-EN.md) - [Telephony Service](telephony/Readme-EN.md)
- [Data Management](database/Readme-EN.md) - [Data Management](database/Readme-EN.md)
- [Task Management](task-management/Readme-EN.md) - [Task Management](task-management/Readme-EN.md)
- [Device Management](device/Readme-EN.md) - [Device Management](device/Readme-EN.md)
...@@ -40,6 +40,7 @@ Then, equip yourself for developing the key features, with the following guideli ...@@ -40,6 +40,7 @@ Then, equip yourself for developing the key features, with the following guideli
- [Application Test](application-test/Readme-EN.md) - [Application Test](application-test/Readme-EN.md)
- [IDL Specifications and User Guide](IDL/idl-guidelines.md) - [IDL Specifications and User Guide](IDL/idl-guidelines.md)
- [Using Native APIs in Application Projects](napi/Readme-EN.md) - [Using Native APIs in Application Projects](napi/Readme-EN.md)
- [File Management](file-management/medialibrary-overview.md)
### Tools ### Tools
......
...@@ -24,13 +24,13 @@ First thing first, familiarize yourself with the two cornerstone frameworks in O ...@@ -24,13 +24,13 @@ 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) - [Notification](notification/notification-overview.md)
- [Window Manager](windowmanager/window-overview.md) - [Window Manager](windowmanager/window-overview.md)
- [WebGL](webgl/webgl-overview.md) - [WebGL](webgl/webgl-overview.md)
- [Media](media/audio-overview.md) - [Media](media/audio-overview.md)
- [Security](security/userauth-overview.md) - [Security](security/userauth-overview.md)
- [Connectivity](connectivity/ipc-rpc-overview.md) - [Connectivity](connectivity/ipc-rpc-overview.md)
- [Telephony](telephony/telephony-overview.md) - [Telephony Service](telephony/telephony-overview.md)
- [Data Management](database/database-mdds-overview.md) - [Data Management](database/database-mdds-overview.md)
- [Task Management](task-management/background-task-overview.md) - [Task Management](task-management/background-task-overview.md)
- [Device](device/usb-overview.md) - [Device](device/usb-overview.md)
...@@ -40,6 +40,7 @@ Then, equip yourself for developing the key features, with the following guideli ...@@ -40,6 +40,7 @@ Then, equip yourself for developing the key features, with the following guideli
- [Application Test](application-test/arkxtest-guidelines.md) - [Application Test](application-test/arkxtest-guidelines.md)
- [OpenHarmony IDL Specifications and User Guide](IDL/idl-guidelines.md) - [OpenHarmony IDL Specifications and User Guide](IDL/idl-guidelines.md)
- [Using Native APIs in Application Projects](napi/napi-guidelines.md) - [Using Native APIs in Application Projects](napi/napi-guidelines.md)
- [File Management](file-management/medialibrary-overview.md)
### Tools ### Tools
......
...@@ -17,10 +17,10 @@ ...@@ -17,10 +17,10 @@
- ExtensionAbility Component - ExtensionAbility Component
- [ExtensionAbility Component Overview](extensionability-overview.md) - [ExtensionAbility Component Overview](extensionability-overview.md)
- [ServiceExtensionAbility](serviceextensionability.md) - [ServiceExtensionAbility](serviceextensionability.md)
- [DataShareExtensionAbility (System Applications Only)](datashareextensionability.md)
- [FormExtensionAbility (Widget)](widget-development-stage.md) - [FormExtensionAbility (Widget)](widget-development-stage.md)
- [StaticSubscriberExtensionAbility](static-subscriber-extension-ability.md)
- [AccessibilityExtensionAbility](accessibilityextensionability.md) - [AccessibilityExtensionAbility](accessibilityextensionability.md)
- [EnterpriseAdminExtensionAbility](enterprise-extensionAbility.md)
- [InputMethodExtensionAbility](inputmethodextentionability.md)
- [WindowExtensionAbility](windowextensionability.md) - [WindowExtensionAbility](windowextensionability.md)
- [AbilityStage Component Container](abilitystage.md) - [AbilityStage Component Container](abilitystage.md)
- [Context](application-context-stage.md) - [Context](application-context-stage.md)
...@@ -34,15 +34,19 @@ ...@@ -34,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 (System Applications Only)](hop-cross-device-migration.md) - [Cross-Device Migration (for System Applications Only)](hop-cross-device-migration.md)
- [Multi-device Collaboration (System Applications Only)](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)
...@@ -52,6 +56,7 @@ ...@@ -52,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)
...@@ -65,7 +70,7 @@ ...@@ -65,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 (System Applications Only)](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 (System Applications Only) # DataShareExtensionAbility (for System Applications Only)
DataShareExtensionAbility provides the data sharing capability. System applications can implement a DataShareExtensionAbility or access an existing DataShareExtensionAbility in the system. Third-party applications can only access an existing DataShareExtensionAbility. For details, see [DataShare Development](../database/database-datashare-guidelines.md). 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
......
...@@ -25,6 +25,12 @@ An [ExtensionAbilityType](../reference/apis/js-apis-bundleManager.md#extensionab ...@@ -25,6 +25,12 @@ An [ExtensionAbilityType](../reference/apis/js-apis-bundleManager.md#extensionab
- [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 (System Applications Only)] # Cross-Device Migration (for System Applications Only)
## When to Use ## When to Use
...@@ -47,25 +47,16 @@ The table below describes the main APIs used for cross-device migration. For det ...@@ -47,25 +47,16 @@ The table below describes the main APIs used for cross-device migration. For det
## How to Develop ## How to Develop
1. Configure the data synchronization permission in the **module.json5** file. The sample code is as follows: 1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
```json
{
"module": {
"requestPermissions":[
{
"name" : "ohos.permission.DISTRIBUTED_DATASYNC",
}
]
}
}
```
2. Configure the fields related to cross-device migration in the configuration file. 2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
- Configure the application to support migration.
Set the **continuable** field in the **module.json5** file to **true**. The default value is **false**. If this parameter is set to **false**, the application cannot be continued on the target device. 3. Configure the fields related to cross-device migration in the configuration file.
Configure the application to support migration.
Set the **continuable** field in the **module.json5** file to **true**. The default value is **false**. If this parameter is set to **false**, the application cannot be continued on the target device.
```json ```json
{ {
"module": { "module": {
...@@ -80,47 +71,31 @@ The table below describes the main APIs used for cross-device migration. For det ...@@ -80,47 +71,31 @@ The table below describes the main APIs used for cross-device migration. For det
} }
``` ```
- Configure the application launch type. For details, see [UIAbility Component Launch Type](uiability-launch-type.md). Configure the application launch type. For details, see [UIAbility Component Launch Type](uiability-launch-type.md).
3. Request the data synchronization permission. The sample code for displaying a dialog box to request the permission is as follows:
```ts
requestPermission() {
let context = this.context
let permissions: Array<string> = ['ohos.permission.DISTRIBUTED_DATASYNC']
context.requestPermissionsFromUser(permissions).then((data) => {
console.info("Succeed to request permission from user with data: "+ JSON.stringify(data))
}).catch((error) => {
console.info("Failed to request permission from user with error: "+ JSON.stringify(error))
})
}
```
4. Implement [onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) in the UIAbility of the initiator. 4. Implement [onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) in the UIAbility of the initiator.
[onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) is called on the initiator. You can save the data in this method to implement application compatibility check and migration decision. [onContinue()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncontinue) is called on the initiator. You can save the data in this method to implement application compatibility check and migration decision.
- Saving migrated data: You can save the data to be migrated in key-value pairs in **wantParam**. - Saving migrated data: You can save the data to be migrated in key-value pairs in **wantParam**.
- Checking application compatibility: You can obtain the version number of the target application from **wantParam** and check the compatibility between the target application and the current application. - Checking application compatibility: You can obtain the version number of the target application from **wantParam** and check the compatibility between the target application and the current application.
- Making a migration decision: You can determine whether to support the migration based on the return value of **onContinue()**. For details about the return value, see [Available APIs](#available-apis). - Making a migration decision: You can determine whether to support the migration based on the return value of **onContinue()**. For details about the return value, see [Available APIs](#available-apis).
The sample code is as follows: The sample code is as follows:
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
import AbilityConstant from '@ohos.app.ability.AbilityConstant'; import AbilityConstant from '@ohos.app.ability.AbilityConstant';
onContinue(wantParam : {[key: string]: any}) { onContinue(wantParam : {[key: string]: any}) {
console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`) console.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`)
let workInput = AppStorage.Get<string>('ContinueWork'); let workInput = AppStorage.Get<string>('ContinueWork');
// Set the user input data into wantParam. // Set the user input data into wantParam.
wantParam["work"] = workInput // set user input data into want params wantParam["work"] = workInput // set user input data into want params
console.info(`onContinue input = ${wantParam["input"]}`); console.info(`onContinue input = ${wantParam["input"]}`);
return AbilityConstant.OnContinueResult.AGREE return AbilityConstant.OnContinueResult.AGREE
} }
``` ```
5. Implement **onCreate()** and **onNewWant()** in the UIAbility of the target application to implement data restoration. 5. Implement **onCreate()** and **onNewWant()** in the UIAbility of the target application to implement data restoration.
- Implementation example of **onCreate** in the multi-instance scenario - Implementation example of **onCreate** in the multi-instance scenario
......
...@@ -33,7 +33,7 @@ In the **ets** directory of the target module, right-click and choose **New** > ...@@ -33,7 +33,7 @@ In the **ets** directory of the target module, right-click and choose **New** >
> **NOTE** > **NOTE**
> >
> When compiling the input method application, use the signature at the system_core level. Otherwise, the application will not be able to start the keyboard. > 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 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.
......
...@@ -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 (System Applications Only)](#implementing-a-background-service-system-applications-only) - [Implementing a Background Service (for System Applications Only)](#implementing-a-background-service-for-system-applications-only)
- [Starting a Background Service (System Applications Only)](#starting-a-background-service-system-applications-only) - [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,7 +33,7 @@ This topic describes how to use ServiceExtensionAbility in the following scenari ...@@ -33,7 +33,7 @@ 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 (System Applications Only) ## Implementing a Background Service (for System Applications Only)
[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.
...@@ -164,7 +164,7 @@ To implement a background service, manually create a ServiceExtensionAbility com ...@@ -164,7 +164,7 @@ To implement a background service, manually create a ServiceExtensionAbility com
``` ```
## Starting a Background Service (System Applications Only) ## Starting a Background Service (for System Applications Only)
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.
......
...@@ -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 (System Applications Only) # Starting a Remote PageAbility (for System Applications Only)
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.
......
# 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
...@@ -5,10 +5,25 @@ ...@@ -5,10 +5,25 @@
UIAbility is a type of application component that provides the UI 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. 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. You are advised to use one UIAbility component to carry the same functional module, with multiple pages (if necessary). 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. 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
......
...@@ -14,7 +14,7 @@ the context is [WindowExtensionContext](../reference/apis/js-apis-inner-applicat ...@@ -14,7 +14,7 @@ the context is [WindowExtensionContext](../reference/apis/js-apis-inner-applicat
> >
## Setting an Embedded Ability (System Applications Only) ## Setting an Embedded Ability (for System Applications Only)
The **WindowExtensionAbility** class provides **onConnect()**, **onDisconnect()**, and **onWindowReady()** lifecycle callbacks, which can be overridden. The **WindowExtensionAbility** class provides **onConnect()**, **onDisconnect()**, and **onWindowReady()** lifecycle callbacks, which can be overridden.
...@@ -78,7 +78,7 @@ To implement an embedded application, manually create a WindowExtensionAbility i ...@@ -78,7 +78,7 @@ To implement an embedded application, manually create a WindowExtensionAbility i
``` ```
## Starting an Embedded Ability (System Applications Only) ## Starting an Embedded Ability (for System Applications Only)
System applications can load the created WindowExtensionAbility through the AbilityComponent. System applications can load the created WindowExtensionAbility through the AbilityComponent.
......
# 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
......
...@@ -63,7 +63,7 @@ For the complete list of APIs and example code, see [Network Sharing](../referen ...@@ -63,7 +63,7 @@ For the complete list of APIs and example code, see [Network Sharing](../referen
}); });
// Call startSharing to start network sharing of the specified type. // Call startSharing to start network sharing of the specified type.
sharing.startSharing(SharingIfaceType.SHARING_WIFI, (error) => { sharing.startSharing(sharing.SharingIfaceType.SHARING_WIFI, (error) => {
console.log(JSON.stringify(error)); console.log(JSON.stringify(error));
}); });
``` ```
...@@ -88,7 +88,7 @@ For the complete list of APIs and example code, see [Network Sharing](../referen ...@@ -88,7 +88,7 @@ For the complete list of APIs and example code, see [Network Sharing](../referen
}); });
// Call stopSharing to stop network sharing of the specified type. // Call stopSharing to stop network sharing of the specified type.
sharing.stopSharing(SharingIfaceType.SHARING_WIFI, (error) => { sharing.stopSharing(sharing.SharingIfaceType.SHARING_WIFI, (error) => {
console.log(JSON.stringify(error)); console.log(JSON.stringify(error));
}); });
``` ```
...@@ -107,7 +107,7 @@ For the complete list of APIs and example code, see [Network Sharing](../referen ...@@ -107,7 +107,7 @@ For the complete list of APIs and example code, see [Network Sharing](../referen
import sharing from '@ohos.net.sharing' import sharing from '@ohos.net.sharing'
// Call startSharing to start network sharing of the specified type. // Call startSharing to start network sharing of the specified type.
sharing.startSharing(SharingIfaceType.SHARING_WIFI, (error) => { sharing.startSharing(sharing.SharingIfaceType.SHARING_WIFI, (error) => {
console.log(JSON.stringify(error)); console.log(JSON.stringify(error));
}); });
...@@ -118,7 +118,7 @@ For the complete list of APIs and example code, see [Network Sharing](../referen ...@@ -118,7 +118,7 @@ For the complete list of APIs and example code, see [Network Sharing](../referen
}); });
// Call stopSharing to stop network sharing of the specified type and clear the data volume of network sharing. // Call stopSharing to stop network sharing of the specified type and clear the data volume of network sharing.
sharing.stopSharing(SharingIfaceType.SHARING_WIFI, (error) => { sharing.stopSharing(sharing.SharingIfaceType.SHARING_WIFI, (error) => {
console.log(JSON.stringify(error)); console.log(JSON.stringify(error));
}); });
......
...@@ -49,6 +49,7 @@ TLS Socket connection functions are mainly provided by the **tls_socket** module ...@@ -49,6 +49,7 @@ TLS Socket connection functions are mainly provided by the **tls_socket** module
| API| Description| | API| Description|
| -------- | -------- | | -------- | -------- |
| constructTLSSocketInstance() | Creates a **TLSSocket** object.|
| bind() | Binds the IP address and port number.| | bind() | Binds the IP address and port number.|
| close(type:&nbsp;'error') | Closes a Socket connection.| | close(type:&nbsp;'error') | Closes a Socket connection.|
| connect() | Sets up a connection to the specified IP address and port number.| | connect() | Sets up a connection to the specified IP address and port number.|
...@@ -189,7 +190,7 @@ TLS Socket connection process on the client: ...@@ -189,7 +190,7 @@ TLS Socket connection process on the client:
let tlsTwoWay = socket.constructTLSSocketInstance(); let tlsTwoWay = socket.constructTLSSocketInstance();
// Subscribe to TLS Socket connection events. // Subscribe to TLS Socket connection events.
tcp.on('message', value => { tlsTwoWay.on('message', value => {
console.log("on message") console.log("on message")
let buffer = value.message let buffer = value.message
let dataView = new DataView(buffer) let dataView = new DataView(buffer)
...@@ -199,10 +200,10 @@ TLS Socket connection process on the client: ...@@ -199,10 +200,10 @@ TLS Socket connection process on the client:
} }
console.log("on connect received:" + str) console.log("on connect received:" + str)
}); });
tcp.on('connect', () => { tlsTwoWay.on('connect', () => {
console.log("on connect") console.log("on connect")
}); });
tcp.on('close', () => { tlsTwoWay.on('close', () => {
console.log("on close") console.log("on close")
}); });
...@@ -245,23 +246,23 @@ TLS Socket connection process on the client: ...@@ -245,23 +246,23 @@ TLS Socket connection process on the client:
console.log(data); console.log(data);
}); });
// Enable the TLS Socket connection to be automatically closed after use. Then, disable listening for TLS Socket connection events. // Enable the TCP Socket connection to be automatically closed after use. Then, disable listening for TCP Socket connection events.
tls.close((err) => { tlsTwoWay.close((err) => {
if (err) { if (err) {
console.log("close callback error = " + err); console.log("close callback error = " + err);
} else { } else {
console.log("close success"); console.log("close success");
} }
tls.off('message'); tlsTwoWay.off('message');
tls.off('connect'); tlsTwoWay.off('connect');
tls.off('close'); tlsTwoWay.off('close');
}); });
// Create a TLS Socket connection (for one-way authentication). // Create a TLS Socket connection (for one-way authentication).
let tlsOneWay = socket.constructTLSSocketInstance(); // One way authentication let tlsOneWay = socket.constructTLSSocketInstance(); // One way authentication
// Subscribe to TLS Socket connection events. // Subscribe to TLS Socket connection events.
tcp.on('message', value => { tlsTwoWay.on('message', value => {
console.log("on message") console.log("on message")
let buffer = value.message let buffer = value.message
let dataView = new DataView(buffer) let dataView = new DataView(buffer)
...@@ -271,10 +272,10 @@ TLS Socket connection process on the client: ...@@ -271,10 +272,10 @@ TLS Socket connection process on the client:
} }
console.log("on connect received:" + str) console.log("on connect received:" + str)
}); });
tcp.on('connect', () => { tlsTwoWay.on('connect', () => {
console.log("on connect") console.log("on connect")
}); });
tcp.on('close', () => { tlsTwoWay.on('close', () => {
console.log("on close") console.log("on close")
}); });
...@@ -306,22 +307,15 @@ TLS Socket connection process on the client: ...@@ -306,22 +307,15 @@ TLS Socket connection process on the client:
console.log(data); console.log(data);
}); });
// Enable the TLS Socket connection to be automatically closed after use. Then, disable listening for TLS Socket connection events. // Enable the TCP Socket connection to be automatically closed after use. Then, disable listening for TCP Socket connection events.
tls.close((err) => { tlsTwoWay.close((err) => {
if (err) { if (err) {
console.log("close callback error = " + err); console.log("close callback error = " + err);
} else { } else {
console.log("close success"); console.log("close success");
} }
tls.off('message'); tlsTwoWay.off('message');
tls.off('connect'); tlsTwoWay.off('connect');
tls.off('close'); tlsTwoWay.off('close');
}); });
``` ```
## Samples
The following samples are provided to help you better understand how to develop Socket connection features:
- [`Socket`: Socket Connection (ArkTS) (API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/Network/Socket)
- [UDP Socket (ArkTS) (API9)](https://gitee.com/openharmony/codelabs/tree/master/NetworkManagement/UdpDemoOH)
- [TCP Socket (ArkTS) (API9)](https://gitee.com/openharmony/codelabs/tree/master/NetworkManagement/TcpSocketDemo)
...@@ -34,7 +34,7 @@ There are two roles in **DataShare**: ...@@ -34,7 +34,7 @@ There are two roles in **DataShare**:
- Data provider: adds, deletes, modifies, and queries data, opens files, and shares data. - Data provider: adds, deletes, modifies, and queries data, opens files, and shares data.
- Data consumer: accesses the data provided by the provider using **DataShareHelper**. - Data consumer: accesses the data provided by the provider using **DataShareHelper**.
### Data Provider Application Development (Only for System Applications) ### Data Provider Application Development (for System Applications Only)
[DataShareExtensionAbility](../reference/apis/js-apis-application-dataShareExtensionAbility.md) provides the following APIs. You can override these APIs as required. [DataShareExtensionAbility](../reference/apis/js-apis-application-dataShareExtensionAbility.md) provides the following APIs. You can override these APIs as required.
......
...@@ -169,7 +169,7 @@ The following uses a single KV store as an example to describe the development p ...@@ -169,7 +169,7 @@ The following uses a single KV store as an example to describe the development p
console.log(`dataChange callback call data: ${data}`); console.log(`dataChange callback call data: ${data}`);
}); });
}catch(e){ }catch(e){
console.error(`An unexpected error occured. Code is ${e.code}, message is ${e.message}`); console.error(`An unexpected error occurred. Code is ${e.code}, message is ${e.message}`);
} }
``` ```
......
...@@ -15,11 +15,11 @@ import pointer from '@ohos.multimodalInput.pointer'; ...@@ -15,11 +15,11 @@ import pointer from '@ohos.multimodalInput.pointer';
The following table lists the common APIs for mouse pointer management. For details about the APIs, see [ohos.multimodalInput.pointer](../reference/apis/js-apis-pointer.md). The following table lists the common APIs for mouse pointer management. For details about the APIs, see [ohos.multimodalInput.pointer](../reference/apis/js-apis-pointer.md).
| Instance | API | Description | | Instance | API | Description |
| ------- | ------------------------------------------------------------ | --------------------------------------------------------------- | | ------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| pointer | function isPointerVisible(callback: AsyncCallback\<boolean>): void; | Checks the visible status of the mouse pointer. | | pointer | function isPointerVisible(callback: AsyncCallback\<boolean>): void; | Checks the visible status of the mouse pointer. |
| pointer | function setPointerVisible(visible: boolean, callback: AsyncCallback\<void>): void; | Sets the visible status of the mouse pointer. This setting takes effect for the mouse pointer globally. | | pointer | function setPointerVisible(visible: boolean, callback: AsyncCallback\<void>): void; | Sets the visible status of the mouse pointer. This setting takes effect for the mouse pointer globally.|
| pointer | function setPointerStyle(windowId: number, pointerStyle: PointerStyle, callback: AsyncCallback\<void>): void; | Sets the mouse pointer style. This setting takes effect for the mouse pointer style of a specified window. | | pointer | function setPointerStyle(windowId: number, pointerStyle: PointerStyle, callback: AsyncCallback\<void>): void; | Sets the mouse pointer style. This setting takes effect for the mouse pointer style of a specified window. |
| pointer | function getPointerStyle(windowId: number, callback: AsyncCallback\<PointerStyle>): void; | Obtains the mouse pointer style. | | pointer | function getPointerStyle(windowId: number, callback: AsyncCallback\<PointerStyle>): void; | Obtains the mouse pointer style. |
## Hiding the Mouse Pointer ## Hiding the Mouse Pointer
...@@ -77,43 +77,48 @@ When designing a color picker, you can have the mouse pointer switched to the co ...@@ -77,43 +77,48 @@ When designing a color picker, you can have the mouse pointer switched to the co
5. Set the mouse pointer to the default style. 5. Set the mouse pointer to the default style.
```js ```js
import pointer from '@ohos.multimodalInput.pointer';
import window from '@ohos.window'; import window from '@ohos.window';
// 1. Enable the color pickup function. // 1. Enable the color pickup function.
// 2. Obtain the window ID. // 2. Obtain the window ID.
window.getTopWindow((error, windowClass) => { window.getLastWindow(this.context, (error, windowClass) => {
windowClass.getProperties((error, data) => { if (error.code) {
var windowId = data.id; console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(error));
if (windowId < 0) { return;
console.log(`Invalid windowId`); }
return; var windowId = windowClass.getWindowProperties().id;
} if (windowId < 0) {
try { console.log(`Invalid windowId`);
// 3. Set the mouse pointer to the color picker style. return;
pointer.setPointerStyle(windowId, pointer.PointerStyle.COLOR_SUCKER).then(() => { }
console.log(`Successfully set mouse pointer style`); try {
}); // 3. Set the mouse pointer to the color picker style.
} catch (error) { pointer.setPointerStyle(windowId, pointer.PointerStyle.COLOR_SUCKER).then(() => {
console.log(`Failed to set the pointer style, error=${JSON.stringify(error)}, msg=${JSON.stringify(message)}`); console.log(`Successfully set mouse pointer style`);
} });
}); } catch (error) {
console.log(`Failed to set the pointer style, error=${JSON.stringify(error)}, msg=${JSON.stringify(`message`)}`);
}
}); });
// 4. End color pickup. // 4. End color pickup.
window.getTopWindow((error, windowClass) => { window.getLastWindow(this.context, (error, windowClass) => {
windowClass.getProperties((error, data) => { if (error.code) {
var windowId = data.id; console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(error));
if (windowId < 0) { return;
console.log(`Invalid windowId`); }
return; var windowId = windowClass.getWindowProperties().id;
} if (windowId < 0) {
try { console.log(`Invalid windowId`);
// 5. Set the mouse pointer to the default style. return;
pointer.setPointerStyle(windowId, pointer.PointerStyle.DEFAULT).then(() => { }
console.log(`Successfully set mouse pointer style`); try {
}); // 5. Set the mouse pointer to the default style.
} catch (error) { pointer.setPointerStyle(windowId, pointer.PointerStyle.DEFAULT).then(() => {
console.log(`Failed to set the pointer style, error=${JSON.stringify(error)}, msg=${JSON.stringify(message)}`); console.log(`Successfully set mouse pointer style`);
} });
}); } catch (error) {
console.log(`Failed to set the pointer style, error=${JSON.stringify(error)}, msg=${JSON.stringify(`message`)}`);
}
}); });
``` ```
...@@ -130,8 +130,6 @@ You can set a USB device as the USB host to connect to other USB devices for dat ...@@ -130,8 +130,6 @@ You can set a USB device as the USB host to connect to other USB devices for dat
usb.bulkTransfer(pipe, inEndpoint, dataUint8Array, 15000).then(dataLength => { usb.bulkTransfer(pipe, inEndpoint, dataUint8Array, 15000).then(dataLength => {
if (dataLength >= 0) { if (dataLength >= 0) {
console.info("usb readData result Length : " + dataLength); console.info("usb readData result Length : " + dataLength);
let resultStr = this.ab2str(dataUint8Array); // Convert uint8 data into a string.
console.info("usb readData buffer : " + resultStr);
} else { } else {
console.info("usb readData failed : " + dataLength); console.info("usb readData failed : " + dataLength);
} }
......
# Development of Application Recovery # Application Recovery Development
## When to Use ## When to Use
During application running, some unexpected behaviors are inevitable. For example, unprocessed exceptions and errors are thrown, and the call or running constraints of the framework are violated. During application running, some unexpected behaviors are inevitable. For example, unprocessed exceptions and errors are thrown, and the call or running constraints of the recovery framework are violated.
By default, the processes will exit as exception handling. However, if user data is generated during application use, process exits may interrupt user operations and cause data loss. Process exit is treated as the default exception handling method. However, if user data is generated during application use, process exit may interrupt user operations and cause data loss.
In this way, application recovery APIs may help you save temporary data, restart an application after it exits, and restore its status and data, which deliver a better user experience. Application recovery helps to restore the application state and save temporary data upon next startup in the case of an abnormal process exit, thus providing more consistent user experience. The application state includes two parts, namely, the page stack of the and the data saved in **onSaveState**.
Currently, the APIs support only the development of an application that adopts the stage model, single process, and single ability. In API version 9, application recovery is supported only for a single ability of the application developed using the stage model. Application state saving and automatic restart are performed when a JsError occurs.
In API version 10, application recovery is also supported for multiple abilities of the application developed using the stage model. Application state storage and restore are performed when an AppFreeze occurs. If an application is killed in control mode, the application state will be restored upon next startup.
## Available APIs ## Available APIs
The application recovery APIs are provided by the **appRecovery** module, which can be imported via **import**. For details, please refer to [Development Example](#development-example). This document describes behaviors of APIs in API version 9, and the content will update with changes. The application recovery APIs are provided by the **appRecovery** module, which can be imported via **import**. For details, see [Development Example](#development-example).
### Available APIs ### Available APIs
| API | Description | | API | Description |
| ------------------------------------------------------------ | ------------------------------------------------------------ | | ------------------------------------------------------------ | ---------------------------------------------------- |
| enableAppRecovery(restart?: RestartFlag, saveOccasion?: SaveOccasionFlag, saveMode?: SaveModeFlag) : void; | Enables the application recovery function. | | enableAppRecovery(restart?: RestartFlag, saveOccasion?: SaveOccasionFlag, saveMode?: SaveModeFlag) : void;<sup>9+</sup> | Enables application recovery. After this API is called, the first ability that is displayed when the application is started from the initiator can be restored.|
| saveAppState(): boolean; | Saves the ability status of an application. | | saveAppState(): boolean;<sup>9+</sup> | Saves the state of the ability that supports recovery in the current application.|
| restartApp(): void; | Restarts the current process. If there is saved ability status, it will be passed to the **want** parameter's **wantParam** attribute of the **onCreate** lifecycle callback of the ability.| | restartApp(): void;<sup>9+</sup> | Restarts the current process and starts the ability specified by **setRestartWant**. If no ability is specified, a foreground ability that supports recovery is restarted.|
| saveAppState(context?: UIAbilityContext): boolean;<sup>10+</sup> | Saves the ability state specified by **Context**.|
| setRestartWant(want: Want): void;<sup>10+</sup> | Sets the abilities to restart when **restartApp** is actively called and **RestartFlag** is not **NO_RESTART**. The abilities must be under the same bundle name and must be a **UiAbility**.|
No error will be thrown if the preceding APIs are used in the troubleshooting scenario. The following are some notes on API usage:
**enableAppRecovery**: This API should be called during application initialization. For example, you can call this API in **onCreate** of **AbilityStage**. For details, see [Parameter Description](../reference/apis/js-apis-app-ability-appRecovery.md).
**saveAppState**: After this API is called, the recovery framework invokes **onSaveState** for all abilities that support recovery in the current process. If you choose to save data in **onSaveState**, the related data and ability page stack are persistently stored in the local cache of the application. To save data of the specified ability, you need to specify the context corresponding to that ability.
**setRestartWant**: This API specifies the ability to be restarted by **appRecovery**.
The APIs are used for troubleshooting and do not return any exception. Therefore, you need to be familiar with when they are used. **restartApp**: After this API is called, the recovery framework kills the current process and restarts the ability specified by **setRestartWant**, with **APP_RECOVERY** set as the startup cause. In API version 9 and scenarios where an ability is not specified by **setRestartWant**, the last foreground ability that supports recovery is started. If the no foreground ability supports recovery, the application crashes. If a saved state is available for the restarted ability, the saved state is passed as the **wantParam** attribute in the **want** parameter of the ability's **onCreate** callback.
**enableAppRecovery**: This API should be called during application initialization. For example, you can call this API in **onCreate** of **AbilityStage**. For details, please refer to the [parameter description](../reference/apis/js-apis-app-ability-appRecovery.md). ### Application State Management
Since API version 10, application recovery is not limited to automatic restart in the case of an exception. Therefore, you need to understand when the application will load the saved state.
If the last exit of an application is not initiated by a user and a saved state is available for recovery, the startup reason is set to **APP_RECOVERY** when the application is started by the user next time, and the recovery state of the application is cleared.
The application recovery status flag is set when **saveAppState** is actively or passively called. The flag is cleared when the application exits normally or the saved state is consumed. (A normal exit is usually triggered by pressing the back key or clearing recent tasks.)
**saveAppState**: After this API is called, the framework calls back **onSaveState** of the ability. If data saving is agreed to in this method, relevant data and the page stack of the ability are persisted to the local cache of the application. ![Application recovery status management](./figures/application_recovery_status_management.png)
**restartApp**: After this API is called, the framework kills the current application process and restarts the ability in the foreground, with **APP_RECOVERY** specified as the startup cause. ### Application State Saving and Restore
API version 10 or later supports saving of the application state when an application is suspended. If a JsError occurs, **onSaveState** is called in the main thread. If an AppFreeze occurs, however, the main thread may be suspended, and therefore **onSaveState** is called in a non-main thread. The following figure shows the main service flow.
### Framework Fault Management Process ![Application recovery from the freezing state](./figures/application_recovery_from_freezing.png)
When the application is suspended, the callback is not executed in the JS thread. Therefore, you are advised not to use the imported dynamic Native library or access the **thread_local** object created by the main thread in the code of the **onSaveState** callback.
### Framework Fault Management
Fault management is an important way for applications to deliver a better user experience. The application framework offers three methods for application fault management: fault listening, fault rectification, and fault query. Fault management is an important way for applications to deliver a better user experience. The application framework offers three methods for application fault management: fault listening, fault rectification, and fault query.
- Fault listening refers to the process of registering [ErrorObserver](../reference/apis/js-apis-application-errorManager.md#errorobserver) via [errorManager](../reference/apis/js-apis-application-errorManager.md), listening for fault occurrence, and notifying the fault listener. - Fault listening refers to the process of registering an [ErrorObserver](../reference/apis/js-apis-inner-application-errorObserver.md) via [errorManager](../reference/apis/js-apis-app-ability-errorManager.md), listening for faults, and notifying the listener of the faults.
- Fault rectification refers to [appRecovery](../reference/apis/js-apis-app-ability-appRecovery.md) and restarts an application to restore its status previous to a fault. - Fault rectification refers to the process of restoring the application state and data through [appRecovery](../reference/apis/js-apis-app-ability-appRecovery.md).
- Fault query indicates that [faultLogger](../reference/apis/js-apis-faultLogger.md) obtains the fault information using its query API. - Fault query is the process of calling APIs of [faultLogger](../reference/apis/js-apis-faultLogger.md) to obtain the fault information.
The figure below does not illustrate the time when [faultLogger](../reference/apis/js-apis-faultLogger.md) is called. You can refer to [LastExitReason](../reference/apis/js-apis-app-ability-abilityConstant.md#abilityconstantlastexitreason) passed during application initialization to determine whether to call [faultLogger](../reference/apis/js-apis-faultLogger.md) to query the information about the last fault. The figure below does not illustrate the time when [faultLogger](../reference/apis/js-apis-faultLogger.md) is called. You can refer to the [LastExitReason](../reference/apis/js-apis-app-ability-abilityConstant.md#abilityconstantlastexitreason) passed during application initialization to determine whether to call [faultLogger](../reference/apis/js-apis-faultLogger.md) to query information about the previous fault.
![Fault rectification process](./figures/fault_rectification.png) ![Fault rectification process](./figures/fault_rectification.png)
It is recommended that you call [errorManager](../reference/apis/js-apis-app-ability-errorManager.md) to handle the exception. After the processing is complete, you can call the **saveAppState** API and restart the application.
If you do not register [ErrorObserver](../reference/apis/js-apis-inner-application-errorObserver.md) or enable application recovery, the application process will exit according to the default processing logic of the system. Users can restart the application from the home screen.
If you have enabled application recovery, the recovery framework first checks whether application state saving is supported and whether the application state saving is enabled. If so, the recovery framework invokes [onSaveState](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonsavestate) of the [Ability](../reference/apis/js-apis-app-ability-uiAbility.md). Finally, the application is restarted.
It is recommended that you call [errorManager](../reference/apis/js-apis-application-errorManager.md) to process the exception. After the processing is complete, you can call the status saving API and restart the application. ### Supported Application Recovery Scenarios
If you do not register [ErrorObserver](../reference/apis/js-apis-application-errorManager.md#errorobserver) or enable application recovery, the application process will exit according to the default processing logic of the system. Users can restart the application from the home screen.
If you have enabled application recovery, the framework first checks whether a fault allows for ability status saving and whether you have configured ability status saving. If so, [onSaveState](../reference/apis/js-apis-application-ability.md#abilityonsavestate) of [Ability](../reference/apis/js-apis-application-ability.md#ability) is called back. Finally, the application is restarted.
### Scenarios Supported by Application Fault Management APIs
Common fault types include JavaScript application crash, application freezing, and C++ application crash. Generally, an application is closed when a crash occurs. Application freezing occurs when the application does not respond. The fault type can be ignored for the upper layer of an application. The recovery framework implements fault management in different scenarios based on the fault type. Common fault types include JavaScript application crash, application freezing, and C++ application crash. Generally, an application is closed when a crash occurs. Application freezing occurs when the application does not respond. The fault type can be ignored for the upper layer of an application. The recovery framework implements fault management in different scenarios based on the fault type.
| Fault | Fault Listening| Status Saving| Automatic Restart| Log Query| | Fault | Fault Listening | State Saving| Automatic Restart| Log Query|
| ------------------------------------------------------------ | -------- | -------- | -------- | -------- | | ----------|--------- |--------- |--------- |--------- |
| [JS_CRASH](../reference/apis/js-apis-faultLogger.md#faulttype) | Supported | Supported | Supported | Supported | | [JS_CRASH](../reference/apis/js-apis-faultLogger.md#faulttype) | Supported|Supported|Supported|Supported|
| [APP_FREEZE](../reference/apis/js-apis-faultLogger.md#faulttype) | Not supported | Not supported | Supported | Supported | | [APP_FREEZE](../reference/apis/js-apis-faultLogger.md#faulttype) | Not supported|Supported|Supported|Supported|
| [CPP_CRASH](../reference/apis/js-apis-faultLogger.md#faulttype) | Not supported | Not supported | Not supported | Supported | | [CPP_CRASH](../reference/apis/js-apis-faultLogger.md#faulttype) | Not supported|Not supported|Not supported|Supported|
**Status Saving** in the table header means status saving when a fault occurs. To protect user data as much as possible in the application freezing fault, you can adopt either the periodic or automatic way, and the latter will save user data when an ability is switched to the background. **State Saving** in the table header means saving of the application state when a fault occurs. To protect user data as much as possible when an AppFreeze occurs, you can adopt either the periodic or automatic way, and the latter will save user data when an ability is switched to the background.
...@@ -78,11 +96,23 @@ export default class MyAbilityStage extends AbilityStage { ...@@ -78,11 +96,23 @@ export default class MyAbilityStage extends AbilityStage {
appRecovery.SaveModeFlag.SAVE_WITH_FILE); appRecovery.SaveModeFlag.SAVE_WITH_FILE);
} }
} }
```
### Enabling Application Recovery for the Specified Abilities
Generally, the ability configuration list is named **module.json5**.
```json
{
"abilities": [
{
"name": "EntryAbility",
"recoverable": true,
}]
}
``` ```
### Saving and Restoring Data ### Saving and Restoring Data
After enabling **appRecovery**, you can use this function by either actively or passively saving the status and restoring data in the ability. After enabling **appRecovery**, you can use this function by either actively or passively saving the application state and restoring data in the ability.
The following is an example of **EntryAbility**: The following is an example of **EntryAbility**:
#### Importing the Service Package #### Importing the Service Package
...@@ -93,9 +123,9 @@ import appRecovery from '@ohos.app.ability.appRecovery'; ...@@ -93,9 +123,9 @@ import appRecovery from '@ohos.app.ability.appRecovery';
import AbilityConstant from '@ohos.app.ability.AbilityConstant'; import AbilityConstant from '@ohos.app.ability.AbilityConstant';
``` ```
#### Actively Saving Status and Restoring Data #### Actively Saving the Application State and Restoring Data
- Define and register the [ErrorObserver](../reference/apis/js-apis-application-errorManager.md#errorobserver) callback. - Define and register the [ErrorObserver](../reference/apis/js-apis-inner-application-errorObserver.md) callback.
```ts ```ts
var registerId = -1; var registerId = -1;
...@@ -108,7 +138,7 @@ import AbilityConstant from '@ohos.app.ability.AbilityConstant'; ...@@ -108,7 +138,7 @@ import AbilityConstant from '@ohos.app.ability.AbilityConstant';
} }
onWindowStageCreate(windowStage) { onWindowStageCreate(windowStage) {
// Main window is created. Set a main page for this ability. // Main window is created, set main page for this ability
console.log("[Demo] EntryAbility onWindowStageCreate") console.log("[Demo] EntryAbility onWindowStageCreate")
globalThis.registerObserver = (() => { globalThis.registerObserver = (() => {
...@@ -125,7 +155,7 @@ After the callback triggers **appRecovery.saveAppState()**, **onSaveState(state, ...@@ -125,7 +155,7 @@ After the callback triggers **appRecovery.saveAppState()**, **onSaveState(state,
```ts ```ts
onSaveState(state, wantParams) { onSaveState(state, wantParams) {
// Save application data. // Ability has called to save app data
console.log("[Demo] EntryAbility onSaveState") console.log("[Demo] EntryAbility onSaveState")
wantParams["myData"] = "my1234567"; wantParams["myData"] = "my1234567";
return AbilityConstant.onSaveResult.ALL_AGREE; return AbilityConstant.onSaveResult.ALL_AGREE;
...@@ -134,7 +164,7 @@ After the callback triggers **appRecovery.saveAppState()**, **onSaveState(state, ...@@ -134,7 +164,7 @@ After the callback triggers **appRecovery.saveAppState()**, **onSaveState(state,
- Restore data. - Restore data.
After the callback triggers **appRecovery.restartApp()**, the application is restarted. After the restart, **onCreate(want, launchParam)** of **EntryAbility** is called, and the saved data is in **parameters** of **want**. After the callback triggers **appRecovery.restartApp()**, the application is restarted. After the restart, **onCreate(want, launchParam)** of **EntryAbility** is called, and the saved data is stored in **parameters** of **want**.
```ts ```ts
storage: LocalStorage storage: LocalStorage
...@@ -150,11 +180,11 @@ onCreate(want, launchParam) { ...@@ -150,11 +180,11 @@ onCreate(want, launchParam) {
} }
``` ```
- Deregister **ErrorObserver callback**. - Unregister the **ErrorObserver** callback.
```ts ```ts
onWindowStageDestroy() { onWindowStageDestroy() {
// Main window is destroyed to release UI resources. // Main window is destroyed, release UI related resources
console.log("[Demo] EntryAbility onWindowStageDestroy") console.log("[Demo] EntryAbility onWindowStageDestroy")
globalThis.unRegisterObserver = (() => { globalThis.unRegisterObserver = (() => {
...@@ -165,9 +195,9 @@ onWindowStageDestroy() { ...@@ -165,9 +195,9 @@ onWindowStageDestroy() {
} }
``` ```
#### Passively Saving Status and Restoring Data #### Passively Saving the Application State and Restoring Data
This is triggered by the recovery framework. You do not need to register **ErrorObserver callback**. You only need to implement **onSaveState** of the ability for status saving and **onCreate** of the ability for data restoration. This is triggered by the recovery framework. You do not need to register an **ErrorObserver** callback. You only need to implement **onSaveState** for application state saving and **onCreate** for data restore.
```ts ```ts
export default class EntryAbility extends Ability { export default class EntryAbility extends Ability {
...@@ -184,7 +214,7 @@ export default class EntryAbility extends Ability { ...@@ -184,7 +214,7 @@ export default class EntryAbility extends Ability {
} }
onSaveState(state, wantParams) { onSaveState(state, wantParams) {
// Save application data. // Ability has called to save app data
console.log("[Demo] EntryAbility onSaveState") console.log("[Demo] EntryAbility onSaveState")
wantParams["myData"] = "my1234567"; wantParams["myData"] = "my1234567";
return AbilityConstant.onSaveResult.ALL_AGREE; return AbilityConstant.onSaveResult.ALL_AGREE;
......
...@@ -45,7 +45,7 @@ The following table provides only a brief description of related APIs. For detai ...@@ -45,7 +45,7 @@ The following table provides only a brief description of related APIs. For detai
The following example illustrates how to log and subscribe to button click events of users. The following example illustrates how to log and subscribe to button click events of users.
1. Create an eTS application project. In the displayed **Project** window, choose **entry** > **src** > **main** > **ets** > **entryability** > **EntryAbility.ts**, and double-click **EntryAbility.ts**. Then, add an event watcher to subscribe to button click events. The complete sample code is as follows: 1. Create an ArkTS application project. In the displayed **Project** window, choose **entry** > **src** > **main** > **ets** > **entryability** > **EntryAbility.ts**, and double-click **EntryAbility.ts**. Then, add an event watcher to subscribe to button click events. The complete sample code is as follows:
```js ```js
import hilog from '@ohos.hilog'; import hilog from '@ohos.hilog';
......
...@@ -18,5 +18,4 @@ ...@@ -18,5 +18,4 @@
- [Native API Usage](faqs-native.md) - [Native API Usage](faqs-native.md)
- [Usage of Third- and Fourth-Party Libraries](faqs-third-party-library.md) - [Usage of Third- and Fourth-Party Libraries](faqs-third-party-library.md)
- [IDE Usage](faqs-ide.md) - [IDE Usage](faqs-ide.md)
- [hdc_std Command Usage](faqs-hdc-std.md)
- [Development Board](faqs-development-board.md) - [Development Board](faqs-development-board.md)
\ No newline at end of file
...@@ -2,23 +2,21 @@ ...@@ -2,23 +2,21 @@
## How do I obtain the DPI of a device? ## How do I obtain the DPI of a device?
Applicable to: OpenHarmony SDK 3.2.2.5, stage model of API version 9 Applicable to: OpenHarmony 3.2 Beta5, stage model of API version 9
Import the **\@ohos.display** module and call the **getDefaultDisplay** API.
Example: Import the **@ohos.display** module and call the **getDefaultDisplaySync** API.
**Example**
``` ```
import display from '@ohos.display'; import display from '@ohos.display';
display.getDefaultDisplay((err, data) => { let displayClass = null;
if (err.code) { try {
console.error('Test Failed to obtain the default display object. Code: ' + JSON.stringify(err)); displayClass = display.getDefaultDisplaySync();
return; console.info('Test densityDPI:' + JSON.stringify(data.densityDPI));
} } catch (exception) {
console.info('Test Succeeded in obtaining the default display object. Data:' + JSON.stringify(data)); console.error('Failed to obtain the default display object. Code: ' + JSON.stringify(exception));
console.info('Test densityDPI:' + JSON.stringify(data.densityDPI)); }
});
``` ```
## How do I obtain the type of the device where the application is running? ## How do I obtain the type of the device where the application is running?
......
# hdc_std Command Usage
## Common Log Commands
Applicable to: OpenHarmony SDK 3.2.2.5
Clearing logs: hdc_std shell hilog -r
Increasing the buffer size to 20 MB: hdc_std shell hilog -G 20M
Capturing logs: hdc_std shell hilog &gt; log.txt
## What should I do to avoid log flow control?
Applicable to: OpenHarmony SDK 3.2.5.3, stage model of API version 9
- Disabling log flow control: hdc_std shell hilog -Q pidoff
- Disabling the privacy flag: hdc_std shell hilog -p off
- Increasing the log buffer to 200 MB: hdc_std shell hilog -G 200M
- Enabling the log function of the specific domain (that is, disabling the global log function): hdc_std shell hilog –b D –D 0xd0xxxxx
After performing the preceding operations, restart the DevEco Studio.
## What should I do if the HAP installed on the development board through the IDE cannot be opened?
Applicable to: OpenHarmony SDK 3.2.5.3, stage model of API version 9
Check whether the SDK version is consistent with the system version on the development board. You are advised to use the SDK version and system version that are released on the same day.
## How do I upload files using the hdc command?
Applicable to: OpenHarmony SDK 3.2.2.5
Run the **hdc_std file send** command.
## How do I prevent the screen of the RK3568 development board from turning off?
Applicable to: OpenHarmony SDK 3.2.5.3, stage model of API version 9
Run the **hdc_std shell "power-shell setmode 602"** command.
## How do I start an ability using the hdc command?
Applicable to: OpenHarmony SDK 3.2.5.3, stage model of API version 9
Run the **hdc\_std shell aa start -a AbilityName -b bundleName -m moduleName** command.
## How do I change the read and write permissions on a file directory on the development board?
Applicable to: OpenHarmony SDK 3.2.5.6, stage model of API version 9
Run the **hdc\_std shell mount -o remount,rw /** command.
## What should I do if the error message "Unknown file option -r" is displayed when hdc_std file recv is run?
Applicable to: OpenHarmony SDK 3.2.5.6, stage model of API version 9
1. Use the the hdc tool in the device image or SDK of the same version.
2. Remove any Chinese characters or spaces from the directory specified for the hdc tool.
## How do I uninstall an application using the hdc command?
Applicable to: OpenHarmony SDK 3.2.2.5
Run the **hdc\_std uninstall [-k] [package_name]** command.
## How do I check whether the system is 32-bit or 64-bit?
Applicable to: OpenHarmony SDK 3.2.5.5
Run the **hdc\_std shell getconf LONG_BIT** command.
If **64** is returned, the system is a 64-bit one. Otherwise, the system is a 32-bit one.
## How do I view the component tree structure?
Applicable to: OpenHarmony SDK 3.2.5.5
1. Run the **hdc\_std shell** command to launch the CLI.
2. Run the **aa dump -a** command to find **abilityID**.
3. Run the **aa dump -i [abilityID] -c -render** command to view the component tree.
...@@ -147,7 +147,7 @@ async function example() { ...@@ -147,7 +147,7 @@ async function example() {
## Obtaining Images and Videos in an Album ## Obtaining Images and Videos in an Album
You can obtain media assets in an album in either of the following ways: You can obtain media assets in an album in either of the following ways:
- Call [MediaLibrary.getFileAssets](../reference/apis/js-apis-medialibrary.md#getfileassets7-1) with an album specified, as described in [Querying Media Assets with the Specfied Album Name](#querying-media-assets-with-the-specified-album-name). - Call [MediaLibrary.getFileAssets](../reference/apis/js-apis-medialibrary.md#getfileassets7-1) with an album specified, as described in [Querying Media Assets with the Specified Album Name](#querying-media-assets-with-the-specified-album-name).
- Call [Album.getFileAssets](../reference/apis/js-apis-medialibrary.md#getfileassets7-3) to obtain an **Album** instance, so as to obtain the media assets in it. - Call [Album.getFileAssets](../reference/apis/js-apis-medialibrary.md#getfileassets7-3) to obtain an **Album** instance, so as to obtain the media assets in it.
**Prerequisites** **Prerequisites**
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
The **intl** module provides basic i18n capabilities, such as time and date formatting, number formatting, and string sorting, through the standard i18n APIs defined in ECMA 402. For more details about APIs and their usage, see [intl](../reference/apis/js-apis-intl.md). The **intl** module provides basic i18n capabilities, such as time and date formatting, number formatting, and string sorting, through the standard i18n APIs defined in ECMA 402. For more details about APIs and their usage, see [intl](../reference/apis/js-apis-intl.md).
The [I18N](i18n-guidelines.md) module provides enhanced I18N capabilities through supplementary interfaces that are not defined in ECMA 402. It works with the Intl module to provide a complete suite of I18N capabilities. The [i18n](../reference/apis/js-apis-i18n.md) module provides enhanced I18N capabilities through supplementary interfaces that are not defined in ECMA 402. It works with the Intl module to provide a complete suite of I18N capabilities.
## Setting Locale Information ## Setting Locale Information
...@@ -111,7 +111,7 @@ The [I18N](i18n-guidelines.md) module provides enhanced I18N capabilities throug ...@@ -111,7 +111,7 @@ The [I18N](i18n-guidelines.md) module provides enhanced I18N capabilities throug
let dateTimeFormat = new Intl.DateTimeFormat(); let dateTimeFormat = new Intl.DateTimeFormat();
``` ```
Alternatively, use your own locale and formatting parameters to create a **DateTimeFormat** object. Formatting parameters are optional. For a full list of formatting parameters, see [DateTimeOptions](../reference/apis/js-apis-intl.md#datetimeoptions). Alternatively, use your own locale and formatting parameters to create a **DateTimeFormat** object. Formatting parameters are optional. For a full list of formatting parameters, see [DateTimeOptions](../reference/apis/js-apis-intl.md#datetimeoptions9).
```js ```js
let options = {dateStyle: "full", timeStyle: "full"}; let options = {dateStyle: "full", timeStyle: "full"};
...@@ -150,7 +150,7 @@ The [I18N](i18n-guidelines.md) module provides enhanced I18N capabilities throug ...@@ -150,7 +150,7 @@ The [I18N](i18n-guidelines.md) module provides enhanced I18N capabilities throug
let resolvedOptions = dateTimeFormat.resolvedOptions(); // resolvedOptions = {"locale": "zh-CN", "calendar": "gregorian", "dateStyle":"full", "timeStyle":"full", "timeZone": "CST"} let resolvedOptions = dateTimeFormat.resolvedOptions(); // resolvedOptions = {"locale": "zh-CN", "calendar": "gregorian", "dateStyle":"full", "timeStyle":"full", "timeZone": "CST"}
``` ```
## Number Formatting ## Formatting Numbers
[NumberFormat](../reference/apis/js-apis-intl.md#numberformat) provides APIs to implement the number formatting specific to a locale. [NumberFormat](../reference/apis/js-apis-intl.md#numberformat) provides APIs to implement the number formatting specific to a locale.
...@@ -181,7 +181,7 @@ The [I18N](i18n-guidelines.md) module provides enhanced I18N capabilities throug ...@@ -181,7 +181,7 @@ The [I18N](i18n-guidelines.md) module provides enhanced I18N capabilities throug
let numberFormat = new Intl.NumberFormat(); let numberFormat = new Intl.NumberFormat();
``` ```
Alternatively, use your own locale and formatting parameters to create a **NumberFormat** object. Formatting parameters are optional. For a full list of formatting parameters, see [NumberOptions](../reference/apis/js-apis-intl.md#numberoptions). Alternatively, use your own locale and formatting parameters to create a **NumberFormat** object. Formatting parameters are optional. For a full list of formatting parameters, see [NumberOptions](../reference/apis/js-apis-intl.md#numberoptions9).
```js ```js
let options = {compactDisplay: "short", notation: "compact"}; let options = {compactDisplay: "short", notation: "compact"};
...@@ -209,7 +209,7 @@ The [I18N](i18n-guidelines.md) module provides enhanced I18N capabilities throug ...@@ -209,7 +209,7 @@ The [I18N](i18n-guidelines.md) module provides enhanced I18N capabilities throug
let resolvedOptions = numberFormat.resolvedOptions(); // resolvedOptions = {"locale": "zh-CN", "compactDisplay": "short", "notation": "compact", "numberingSystem": "Latn"} let resolvedOptions = numberFormat.resolvedOptions(); // resolvedOptions = {"locale": "zh-CN", "compactDisplay": "short", "notation": "compact", "numberingSystem": "Latn"}
``` ```
## String Sorting ## Sorting Strings
Users in different regions have different requirements for string sorting. [Collator](../reference/apis/js-apis-intl.md#collator8) provides APIs to sort character strings specific to a locale. Users in different regions have different requirements for string sorting. [Collator](../reference/apis/js-apis-intl.md#collator8) provides APIs to sort character strings specific to a locale.
...@@ -317,7 +317,7 @@ According to grammars in certain languages, the singular or plural form of a nou ...@@ -317,7 +317,7 @@ According to grammars in certain languages, the singular or plural form of a nou
let categoryResult = pluralRules.select(number); // categoryResult = "other" let categoryResult = pluralRules.select(number); // categoryResult = "other"
``` ```
## Formatting Relative Time ## Formatting the Relative Time
[RelativeTimeFormat](../reference/apis/js-apis-intl.md#relativetimeformat8) provides APIs to format the relative time for a specific locale. [RelativeTimeFormat](../reference/apis/js-apis-intl.md#relativetimeformat8) provides APIs to format the relative time for a specific locale.
...@@ -385,9 +385,3 @@ According to grammars in certain languages, the singular or plural form of a nou ...@@ -385,9 +385,3 @@ According to grammars in certain languages, the singular or plural form of a nou
let relativeTimeFormat = new Intl.RelativeTimeFormat("zh-CN", {numeric: "always", style: "long"}); let relativeTimeFormat = new Intl.RelativeTimeFormat("zh-CN", {numeric: "always", style: "long"});
let options = relativeTimeFormat.resolvedOptions(); // options = {"locale": "zh-CN", "style": "long", "numeric": "always", "numberingSystem": "latn"} let options = relativeTimeFormat.resolvedOptions(); // options = {"locale": "zh-CN", "style": "long", "numeric": "always", "numberingSystem": "latn"}
``` ```
## Samples
The following sample is provided to help you better understand how to develop internationalization capabilities:
-[`International`: Internationalization (ArkTS) (API9) (Full SDK)] (https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Internationalnation/International)
...@@ -12,10 +12,10 @@ ...@@ -12,10 +12,10 @@
- [Audio Routing and Device Management Development](audio-routing-manager.md) - [Audio Routing and Device Management Development](audio-routing-manager.md)
- [AVPlayer Development (Recommended)](avplayer-playback.md) - [AVPlayer Development (Recommended)](avplayer-playback.md)
- [AVRecorder Development (Recommended)](avrecorder.md) - [AVRecorder Development (Recommended)](avrecorder.md)
- [Audio Playback Development (To Be Deprecated)](audio-playback.md) - [Audio Playback Development (To Be Deprecated Soon)](audio-playback.md)
- [Audio Recording Development (To Be Deprecated)](audio-recorder.md) - [Audio Recording Development (To Be Deprecated Soon)](audio-recorder.md)
- [Video Playback Development (To Be Deprecated)](video-playback.md) - [Video Playback Development (To Be Deprecated Soon)](video-playback.md)
- [Video Recording Development (To Be Deprecated)](video-recorder.md) - [Video Recording Development (To Be Deprecated Soon)](video-recorder.md)
- AVSession - AVSession
- [AVSession Overview](avsession-overview.md) - [AVSession Overview](avsession-overview.md)
......
...@@ -27,32 +27,43 @@ Before developing the audio data collection feature, configure the **ohos.permis ...@@ -27,32 +27,43 @@ Before developing the audio data collection feature, configure the **ohos.permis
For details about the APIs, see [AudioCapturer in Audio Management](../reference/apis/js-apis-audio.md#audiocapturer8). For details about the APIs, see [AudioCapturer in Audio Management](../reference/apis/js-apis-audio.md#audiocapturer8).
1. Use **createAudioCapturer()** to create an **AudioCapturer** instance. 1. Use **createAudioCapturer()** to create a global **AudioCapturer** instance.
Set parameters of the **AudioCapturer** instance in **audioCapturerOptions**. This instance is used to capture audio, control and obtain the recording state, and register a callback for notification. Set parameters of the **AudioCapturer** instance in **audioCapturerOptions**. This instance is used to capture audio, control and obtain the recording state, and register a callback for notification.
```js ```js
import audio from '@ohos.multimedia.audio'; import audio from '@ohos.multimedia.audio';
import fs from '@ohos.file.fs'; // It will be used for the call of the read function in step 3.
// Perform a self-test on APIs related to audio rendering.
@Entry
@Component
struct AudioRenderer {
@State message: string = 'Hello World'
private audioCapturer: audio.AudioCapturer; // It will be called globally.
async initAudioCapturer(){
let audioStreamInfo = {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100,
channels: audio.AudioChannel.CHANNEL_1,
sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW
}
let audioCapturerInfo = {
source: audio.SourceType.SOURCE_TYPE_MIC,
capturerFlags: 0 // 0 is the extended flag bit of the audio capturer. The default value is 0.
}
let audioCapturerOptions = {
streamInfo: audioStreamInfo,
capturerInfo: audioCapturerInfo
}
this.audioCapturer = await audio.createAudioCapturer(audioCapturerOptions);
console.log('AudioRecLog: Create audio capturer success.');
}
let audioStreamInfo = {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100,
channels: audio.AudioChannel.CHANNEL_1,
sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW
}
let audioCapturerInfo = {
source: audio.SourceType.SOURCE_TYPE_MIC,
capturerFlags: 0 // 0 is the extended flag bit of the audio capturer. The default value is 0.
}
let audioCapturerOptions = {
streamInfo: audioStreamInfo,
capturerInfo: audioCapturerInfo
}
let audioCapturer = await audio.createAudioCapturer(audioCapturerOptions);
console.log('AudioRecLog: Create audio capturer success.');
``` ```
2. Use **start()** to start audio recording. 2. Use **start()** to start audio recording.
...@@ -60,23 +71,18 @@ For details about the APIs, see [AudioCapturer in Audio Management](../reference ...@@ -60,23 +71,18 @@ For details about the APIs, see [AudioCapturer in Audio Management](../reference
The capturer state will be **STATE_RUNNING** once the audio capturer is started. The application can then begin reading buffers. The capturer state will be **STATE_RUNNING** once the audio capturer is started. The application can then begin reading buffers.
```js ```js
import audio from '@ohos.multimedia.audio'; async startCapturer() {
let state = this.audioCapturer.state;
async function startCapturer() {
let state = audioCapturer.state;
// The audio capturer should be in the STATE_PREPARED, STATE_PAUSED, or STATE_STOPPED state after being started. // The audio capturer should be in the STATE_PREPARED, STATE_PAUSED, or STATE_STOPPED state after being started.
if (state != audio.AudioState.STATE_PREPARED || state != audio.AudioState.STATE_PAUSED || if (state == audio.AudioState.STATE_PREPARED || state == audio.AudioState.STATE_PAUSED ||
state != audio.AudioState.STATE_STOPPED) { state == audio.AudioState.STATE_STOPPED) {
console.info('Capturer is not in a correct state to start'); await this.audioCapturer.start();
return; state = this.audioCapturer.state;
} if (state == audio.AudioState.STATE_RUNNING) {
await audioCapturer.start(); console.info('AudioRecLog: Capturer started');
} else {
state = audioCapturer.state; console.error('AudioRecLog: Capturer start failed');
if (state == audio.AudioState.STATE_RUNNING) { }
console.info('AudioRecLog: Capturer started');
} else {
console.error('AudioRecLog: Capturer start failed');
} }
} }
``` ```
...@@ -86,91 +92,88 @@ For details about the APIs, see [AudioCapturer in Audio Management](../reference ...@@ -86,91 +92,88 @@ For details about the APIs, see [AudioCapturer in Audio Management](../reference
The following example shows how to write recorded data into a file. The following example shows how to write recorded data into a file.
```js ```js
import fs from '@ohos.file.fs'; async readData(){
let state = this.audioCapturer.state;
let state = audioCapturer.state; // The read operation can be performed only when the state is STATE_RUNNING.
// The read operation can be performed only when the state is STATE_RUNNING. if (state != audio.AudioState.STATE_RUNNING) {
if (state != audio.AudioState.STATE_RUNNING) { console.info('Capturer is not in a correct state to read');
console.info('Capturer is not in a correct state to read'); return;
return;
}
const path = '/data/data/.pulse_dir/capture_js.wav'; // Path for storing the collected audio file.
let file = fs.openSync(filePath, 0o2);
let fd = file.fd;
if (file !== null) {
console.info('AudioRecLog: file created');
} else {
console.info('AudioRecLog: file create : FAILED');
return;
}
if (fd !== null) {
console.info('AudioRecLog: file fd opened in append mode');
}
let numBuffersToCapture = 150; // Write data for 150 times.
let count = 0;
while (numBuffersToCapture) {
let bufferSize = await audioCapturer.getBufferSize();
let buffer = await audioCapturer.read(bufferSize, true);
let options = {
offset: count * this.bufferSize,
length: this.bufferSize
} }
if (typeof(buffer) == undefined) { const path = '/data/data/.pulse_dir/capture_js.wav'; // Path for storing the collected audio file.
console.info('AudioRecLog: read buffer failed'); let file = fs.openSync(path, 0o2);
let fd = file.fd;
if (file !== null) {
console.info('AudioRecLog: file created');
} else { } else {
let number = fs.writeSync(fd, buffer, options); console.info('AudioRecLog: file create : FAILED');
console.info(`AudioRecLog: data written: ${number}`); return;
} }
numBuffersToCapture--; if (fd !== null) {
count++; console.info('AudioRecLog: file fd opened in append mode');
}
let numBuffersToCapture = 150; // Write data for 150 times.
let count = 0;
while (numBuffersToCapture) {
this.bufferSize = await this.audioCapturer.getBufferSize();
let buffer = await this.audioCapturer.read(this.bufferSize, true);
let options = {
offset: count * this.bufferSize,
length: this.bufferSize
}
if (typeof(buffer) == undefined) {
console.info('AudioRecLog: read buffer failed');
} else {
let number = fs.writeSync(fd, buffer, options);
console.info(`AudioRecLog: data written: ${number}`);
}
numBuffersToCapture--;
count++;
}
} }
``` ```
4. Once the recording is complete, call **stop()** to stop the recording. 4. Once the recording is complete, call **stop()** to stop the recording.
```js ```js
async function StopCapturer() { async StopCapturer() {
let state = audioCapturer.state; let state = this.audioCapturer.state;
// The audio capturer can be stopped only when it is in STATE_RUNNING or STATE_PAUSED state. // The audio capturer can be stopped only when it is in STATE_RUNNING or STATE_PAUSED state.
if (state != audio.AudioState.STATE_RUNNING && state != audio.AudioState.STATE_PAUSED) { if (state != audio.AudioState.STATE_RUNNING && state != audio.AudioState.STATE_PAUSED) {
console.info('AudioRecLog: Capturer is not running or paused'); console.info('AudioRecLog: Capturer is not running or paused');
return; return;
} }
await audioCapturer.stop(); await this.audioCapturer.stop();
state = audioCapturer.state; state = this.audioCapturer.state;
if (state == audio.AudioState.STATE_STOPPED) { if (state == audio.AudioState.STATE_STOPPED) {
console.info('AudioRecLog: Capturer stopped'); console.info('AudioRecLog: Capturer stopped');
} else { } else {
console.error('AudioRecLog: Capturer stop failed'); console.error('AudioRecLog: Capturer stop failed');
} }
} }
``` ```
5. After the task is complete, call **release()** to release related resources. 5. After the task is complete, call **release()** to release related resources.
```js ```js
async function releaseCapturer() { async releaseCapturer() {
let state = audioCapturer.state; let state = this.audioCapturer.state;
// The audio capturer can be released only when it is not in the STATE_RELEASED or STATE_NEW state. // The audio capturer can be released only when it is not in the STATE_RELEASED or STATE_NEW state.
if (state == audio.AudioState.STATE_RELEASED || state == audio.AudioState.STATE_NEW) { if (state == audio.AudioState.STATE_RELEASED || state == audio.AudioState.STATE_NEW) {
console.info('AudioRecLog: Capturer already released'); console.info('AudioRecLog: Capturer already released');
return; return;
} }
await audioCapturer.release(); await this.audioCapturer.release();
state = audioCapturer.state; state = this.audioCapturer.state;
if (state == audio.AudioState.STATE_RELEASED) { if (state == audio.AudioState.STATE_RELEASED) {
console.info('AudioRecLog: Capturer released'); console.info('AudioRecLog: Capturer released');
} else { } else {
console.info('AudioRecLog: Capturer release failed'); console.info('AudioRecLog: Capturer release failed');
} }
} }
``` ```
6. (Optional) Obtain the audio capturer information. 6. (Optional) Obtain the audio capturer information.
...@@ -178,23 +181,20 @@ For details about the APIs, see [AudioCapturer in Audio Management](../reference ...@@ -178,23 +181,20 @@ For details about the APIs, see [AudioCapturer in Audio Management](../reference
You can use the following code to obtain the audio capturer information: You can use the following code to obtain the audio capturer information:
```js ```js
// Obtain the audio capturer state. async getAudioCapturerInfo(){
let state = audioCapturer.state; // Obtain the audio capturer state.
let state = this.audioCapturer.state;
// Obtain the audio capturer information. // Obtain the audio capturer information.
let audioCapturerInfo : audio.AuduioCapturerInfo = await audioCapturer.getCapturerInfo(); let audioCapturerInfo : audio.AudioCapturerInfo = await this.audioCapturer.getCapturerInfo();
// Obtain the audio stream information.
// Obtain the audio stream information. let audioStreamInfo : audio.AudioStreamInfo = await this.audioCapturer.getStreamInfo();
let audioStreamInfo : audio.AudioStreamInfo = await audioCapturer.getStreamInfo(); // Obtain the audio stream ID.
let audioStreamId : number = await this.audioCapturer.getAudioStreamId();
// Obtain the audio stream ID. // Obtain the Unix timestamp, in nanoseconds.
let audioStreamId : number = await audioCapturer.getAudioStreamId(); let audioTime : number = await this.audioCapturer.getAudioTime();
// Obtain a proper minimum buffer size.
// Obtain the Unix timestamp, in nanoseconds. let bufferSize : number = await this.audioCapturer.getBufferSize();
let audioTime : number = await audioCapturer.getAudioTime(); }
// Obtain a proper minimum buffer size.
let bufferSize : number = await audioCapturer.getBufferSize();
``` ```
7. (Optional) Use **on('markReach')** to subscribe to the mark reached event, and use **off('markReach')** to unsubscribe from the event. 7. (Optional) Use **on('markReach')** to subscribe to the mark reached event, and use **off('markReach')** to unsubscribe from the event.
...@@ -202,12 +202,13 @@ For details about the APIs, see [AudioCapturer in Audio Management](../reference ...@@ -202,12 +202,13 @@ For details about the APIs, see [AudioCapturer in Audio Management](../reference
After the mark reached event is subscribed to, when the number of frames collected by the audio capturer reaches the specified value, a callback is triggered and the specified value is returned. After the mark reached event is subscribed to, when the number of frames collected by the audio capturer reaches the specified value, a callback is triggered and the specified value is returned.
```js ```js
audioCapturer.on('markReach', (reachNumber) => { async markReach(){
console.info('Mark reach event Received'); this.audioCapturer.on('markReach', 10, (reachNumber) => {
console.info(`The Capturer reached frame: ${reachNumber}`); console.info('Mark reach event Received');
}); console.info(`The Capturer reached frame: ${reachNumber}`);
});
audioCapturer.off('markReach'); // Unsubscribe from the mark reached event. This event will no longer be listened for. this.audioCapturer.off('markReach'); // Unsubscribe from the mark reached event. This event will no longer be listened for.
}
``` ```
8. (Optional) Use **on('periodReach')** to subscribe to the period reached event, and use **off('periodReach')** to unsubscribe from the event. 8. (Optional) Use **on('periodReach')** to subscribe to the period reached event, and use **off('periodReach')** to unsubscribe from the event.
...@@ -215,40 +216,43 @@ For details about the APIs, see [AudioCapturer in Audio Management](../reference ...@@ -215,40 +216,43 @@ For details about the APIs, see [AudioCapturer in Audio Management](../reference
After the period reached event is subscribed to, each time the number of frames collected by the audio capturer reaches the specified value, a callback is triggered and the specified value is returned. After the period reached event is subscribed to, each time the number of frames collected by the audio capturer reaches the specified value, a callback is triggered and the specified value is returned.
```js ```js
audioCapturer.on('periodReach', (reachNumber) => { async periodReach(){
console.info('Period reach event Received'); this.audioCapturer.on('periodReach', 10, (reachNumber) => {
console.info(`In this period, the Capturer reached frame: ${reachNumber}`); console.info('Period reach event Received');
}); console.info(`In this period, the Capturer reached frame: ${reachNumber}`);
});
audioCapturer.off('periodReach'); // Unsubscribe from the period reached event. This event will no longer be listened for. this.audioCapturer.off('periodReach'); // Unsubscribe from the period reached event. This event will no longer be listened for.
}
``` ```
9. If your application needs to perform some operations when the audio capturer state is updated, it can subscribe to the state change event. When the audio capturer state is updated, the application receives a callback containing the event type. 9. If your application needs to perform some operations when the audio capturer state is updated, it can subscribe to the state change event. When the audio capturer state is updated, the application receives a callback containing the event type.
```js ```js
audioCapturer.on('stateChange', (state) => { async stateChange(){
console.info(`AudioCapturerLog: Changed State to : ${state}`) this.audioCapturer.on('stateChange', (state) => {
switch (state) { console.info(`AudioCapturerLog: Changed State to : ${state}`)
case audio.AudioState.STATE_PREPARED: switch (state) {
console.info('--------CHANGE IN AUDIO STATE----------PREPARED--------------'); case audio.AudioState.STATE_PREPARED:
console.info('Audio State is : Prepared'); console.info('--------CHANGE IN AUDIO STATE----------PREPARED--------------');
break; console.info('Audio State is : Prepared');
case audio.AudioState.STATE_RUNNING: break;
console.info('--------CHANGE IN AUDIO STATE----------RUNNING--------------'); case audio.AudioState.STATE_RUNNING:
console.info('Audio State is : Running'); console.info('--------CHANGE IN AUDIO STATE----------RUNNING--------------');
break; console.info('Audio State is : Running');
case audio.AudioState.STATE_STOPPED: break;
console.info('--------CHANGE IN AUDIO STATE----------STOPPED--------------'); case audio.AudioState.STATE_STOPPED:
console.info('Audio State is : stopped'); console.info('--------CHANGE IN AUDIO STATE----------STOPPED--------------');
break; console.info('Audio State is : stopped');
case audio.AudioState.STATE_RELEASED: break;
console.info('--------CHANGE IN AUDIO STATE----------RELEASED--------------'); case audio.AudioState.STATE_RELEASED:
console.info('Audio State is : released'); console.info('--------CHANGE IN AUDIO STATE----------RELEASED--------------');
break; console.info('Audio State is : released');
default: break;
console.info('--------CHANGE IN AUDIO STATE----------INVALID--------------'); default:
console.info('Audio State is : invalid'); console.info('--------CHANGE IN AUDIO STATE----------INVALID--------------');
break; console.info('Audio State is : invalid');
} break;
}); }
});
}
``` ```
...@@ -292,13 +292,13 @@ export class AVPlayerDemo { ...@@ -292,13 +292,13 @@ export class AVPlayerDemo {
async avPlayerDemo() { async avPlayerDemo() {
// Create an AVPlayer instance. // Create an AVPlayer instance.
this.avPlayer = await media.createAVPlayer() this.avPlayer = await media.createAVPlayer()
let fdPath = 'fd://' let fileDescriptor = undefined
let pathDir = "/data/storage/el2/base/haps/entry/files" // The path used here is an example. Obtain the path based on project requirements. // Use getRawFileDescriptor of the resource management module to obtain the media assets in the application, and use the fdSrc attribute of the AVPlayer to initialize the media assets.
// The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\H264_AAC.mp4 /data/app/el2/100/base/ohos.acts.multimedia.media.avplayer/haps/entry/files" command. // For details on the fd/offset/length parameter, see the Media API. The globalThis.abilityContext parameter is a system environment variable and is saved as a global variable on the main page during the system boost.
let path = pathDir + '/H264_AAC.mp4' await globalThis.abilityContext.resourceManager.getRawFileDescriptor('H264_AAC.mp4').then((value) => {
let file = await fs.open(path) fileDescriptor = {fd: value.fd, offset: value.offset, length: value.length}
fdPath = fdPath + '' + file.fd })
this.avPlayer.url = fdPath this.avPlayer.fdSrc = fileDescriptor
} }
} }
``` ```
......
...@@ -244,7 +244,7 @@ The development process of the Neural Network Runtime consists of three phases: ...@@ -244,7 +244,7 @@ The development process of the Neural Network Runtime consists of three phases:
// Create a compilation instance to pass the model to the underlying hardware for compilation. // Create a compilation instance to pass the model to the underlying hardware for compilation.
OH_NNCompilation* compilation = OH_NNCompilation_Construct(model); OH_NNCompilation* compilation = OH_NNCompilation_Construct(model);
if (compilation == nullptr) { if (compilation == nullptr) {
std::cout << "CreateCompilation failed, error happended when creating compilation." << std::endl; std::cout << "CreateCompilation failed, error happened when creating compilation." << std::endl;
return OH_NN_MEMORY_ERROR; return OH_NN_MEMORY_ERROR;
} }
......
# Notification Subscription (Open Only to System Applications) # Notification Subscription (for System Applications Only)
To receive notifications, an application must subscribe to notifications first. The notification subsystem provides two types of subscription APIs, allowing applications to subscribe to notifications from all applications or notifications from a specific application. To receive notifications, an application must subscribe to notifications first. The notification subsystem provides two types of subscription APIs, allowing applications to subscribe to notifications from all applications or notifications from a specific application.
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册