提交 27105540 编写于 作者: L LiAn 提交者: Gitee

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

Signed-off-by: NLiAn <lian15@huawei.com>
...@@ -73,8 +73,8 @@ BackupExtensionAbility is a class derived from the [ExtensionAbility](../applica ...@@ -73,8 +73,8 @@ BackupExtensionAbility is a class derived from the [ExtensionAbility](../applica
"data/storage/el2/base/files/", "data/storage/el2/base/files/",
"data/storage/el2/base/preferences/", "data/storage/el2/base/preferences/",
"data/storage/el2/base/haps/*/database/", "data/storage/el2/base/haps/*/database/",
"data/storage/el2/base/haps/*/base/files/", "data/storage/el2/base/haps/*/files/",
"data/storage/el2/base/haps/*/base/preferences/", "data/storage/el2/base/haps/*/preferences/",
] ]
} }
``` ```
...@@ -42,7 +42,7 @@ let fetchOptions = { ...@@ -42,7 +42,7 @@ let fetchOptions = {
}; };
``` ```
Call **PhotoAccessHelper.getAssets** to obtain the image asset. Call **PhotoAccessHelper.getAssets** to obtain image assets.
```ts ```ts
try { try {
...@@ -55,7 +55,7 @@ try { ...@@ -55,7 +55,7 @@ try {
} }
``` ```
### Obtaining an Image or Video by URI ### Obtaining an Image or Video Asset by URI
Example: Obtain the image with the file URI **file://media/Photo/1**. Example: Obtain the image with the file URI **file://media/Photo/1**.
...@@ -70,7 +70,7 @@ let fetchOptions = { ...@@ -70,7 +70,7 @@ let fetchOptions = {
}; };
``` ```
Call **PhotoAccessHelper.getAssets** to obtain the image asset. Call **PhotoAccessHelper.getAssets** to obtain image assets.
```ts ```ts
try { try {
...@@ -103,7 +103,7 @@ let fetchOptions = { ...@@ -103,7 +103,7 @@ let fetchOptions = {
}; };
``` ```
Call **PhotoAccessHelper.getAssets** to obtain the image assets. Call **PhotoAccessHelper.getAssets** to obtain image assets.
```ts ```ts
try { try {
...@@ -250,7 +250,7 @@ The files moved to the trash will be retained for 30 days, and deleted permanent ...@@ -250,7 +250,7 @@ The files moved to the trash will be retained for 30 days, and deleted permanent
**Prerequisites** **Prerequisites**
- A **photoAccessHelper** instance is obtained - A **photoAccessHelper** instance is obtained.
- The application has the **ohos.permission.WRITE_IMAGEVIDEO** and **ohos.permission.READ_IMAGEVIDEO** permissions. - The application has the **ohos.permission.WRITE_IMAGEVIDEO** and **ohos.permission.READ_IMAGEVIDEO** permissions.
Example: Move the first file in the result set to the trash. Example: Move the first file in the result set to the trash.
......
...@@ -5,7 +5,7 @@ The **photoAccessHelper** module provides APIs for managing system albums, inclu ...@@ -5,7 +5,7 @@ The **photoAccessHelper** module provides APIs for managing system albums, inclu
> **NOTE** > **NOTE**
> >
> Before you start, refer to [photoAccessHelper Overview](photoAccessHelper-overview.md) to learn how to obtain a **photoAccessHelper** instance and apply for permissions required. > Before you start, refer to [photoAccessHelper Overview](photoAccessHelper-overview.md) to learn how to obtain a **photoAccessHelper** instance and apply for permissions required.
> By default, the **photoAccessHelper** instance obtained in [photoAccessHelper Overview](photoAccessHelper-overview.md) is used when **photoAccessHelper** APIs are used. If the code for obtaining the **photoAccessHelper** instance is not added, an error indicating that **photoAccessHelper** is not defined is reported. > By default, the **PhotoAccessHelper** instance obtained in [photoAccessHelper Overview](photoAccessHelper-overview.md) is used when **PhotoAccessHelper** APIs are used. If the code for obtaining the **PhotoAccessHelper** instance is not added, an error indicating that **PhotoAccessHelper** is not defined is reported.
To ensure application running efficiency, most **photoAccessHelper** calls are asynchronous in callback or promise mode. The following code samples use promise-based APIs. For details about the APIs, see [Album Management](../reference/apis/js-apis-photoAccessHelper.md). To ensure application running efficiency, most **photoAccessHelper** calls are asynchronous in callback or promise mode. The following code samples use promise-based APIs. For details about the APIs, see [Album Management](../reference/apis/js-apis-photoAccessHelper.md).
Unless otherwise specified, all the media assets to be obtained in this document exist in the database. If no media asset is obtained when the sample code is executed, check whether the media assets exist in the database. Unless otherwise specified, all the media assets to be obtained in this document exist in the database. If no media asset is obtained when the sample code is executed, check whether the media assets exist in the database.
...@@ -133,8 +133,8 @@ Example: Unfavorite an image. ...@@ -133,8 +133,8 @@ Example: Unfavorite an image.
**How to Develop** **How to Develop**
1. [Obtain the image and videos in **Favorites**](#obtaining-images-and-videos-in-favorites). 1. [Obtain the image and videos in **Favorites**](#obtaining-images-and-videos-in-favorites).
2. Set **isFavorite** to **false**. 2. Set **favoriteState** to **false**.
3. Use **FileAsset.favorite** to remove the image from **Favorites**. 3. Use **FileAsset.setFavorite** to remove the image from **Favorites**.
```ts ```ts
......
...@@ -2,55 +2,100 @@ ...@@ -2,55 +2,100 @@
When a user needs to download a file from the network to a local directory or save a user file into another directory, use **FilePicker** to save the file. When a user needs to download a file from the network to a local directory or save a user file into another directory, use **FilePicker** to save the file.
The operations for saving images, audio or video clips, and documents are similar. Call **save()** of the corresponding picker instance and pass in **saveOptions**. The operations for saving images, audio or video clips, and documents are similar. Call **save()** of the corresponding picker instance and pass in **saveOptions**. No permission is required if **FilePicker** is used to access files.
The **save()** interface saves the file in the file manager, not in the Gallery. The **save()** method saves the file in the file manager, not in the Gallery.
## Saving Images or Video Files ## Saving Images or Video Files
1. Import the **picker** module and **fs** module. For example, select an image from **Gallery** and save it to the file manager.
1. Import the [picker](../reference/apis/js-apis-file-picker.md), [fs](../reference/apis/js-apis-file-fs.md), [photoAccessHelper](../reference/apis/js-apis-photoAccessHelper.md), and [dataSharePredicates](../reference/apis/js-apis-data-dataSharePredicates.md) modules.
```ts ```ts
import picker from '@ohos.file.picker'; import picker from '@ohos.file.picker';
import fs from '@ohos.file.fs'; import fs from '@ohos.file.fs';
import photoAccessHelper from '@ohos.file.photoAccessHelper';
import dataSharePredicates from '@ohos.data.dataSharePredicates';
``` ```
2. Create a **photoSaveOptions** instance. 2. Obtain the thumbnail of the first image on the device. Before performing this operation, ensure that at least one image exists on the device.
```ts ```ts
const photoSaveOptions = new picker.PhotoSaveOptions(); // Create a photoSaveOptions instance. const context = getContext(this);
photoSaveOptions.newFileNames = ["PhotoViewPicker01.jpg"]; // (Optional) Set the names of the files to save. let photoAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
let pixelmapArrayBuffer;
async getPixelmap() {
try {
let predicates = new dataSharePredicates.DataSharePredicates();
let fetchOption = {
fetchColumns: [],
predicates: predicates
};
let fetchResult = await photoAccessHelper.getAssets(fetchOption);
console.info('[picker] getThumbnail fetchResult: ' + fetchResult);
const asset = await fetchResult.getFirstObject();
console.info('[picker] getThumbnail asset displayName = ', asset.displayName);
asset.getThumbnail().then((pixelMap) => {
let pixelBytesNumber = pixelMap.getPixelBytesNumber();
const readBuffer = new ArrayBuffer(pixelBytesNumber);
pixelMap.readPixelsToBuffer(readBuffer).then(() => {
pixelmapArrayBuffer = readBuffer;
})
}).catch((err) => {
console.error('[picker] getThumbnail failed with error: ' + err);
});
} catch (error) {
console.error('[picker] getThumbnail error = ' + error);
}
}
``` ```
3. Create a **photoViewPicker** instance and call [save()](../reference/apis/js-apis-file-picker.md#save) to open the **FilePicker** page to save the files. After the user selects the target folder, the file saving operation is complete. After the files are saved successfully, the URIs of the files saved are returned. 3. Create a **photoViewPicker** instance and call [save()](../reference/apis/js-apis-file-picker.md#save) to open the **FilePicker** page to save the image. After the user selects the target folder, the file saving operation is complete. After the image is saved successfully, the URI of the saved image is returned.
The permission on the URIs returned by **save()** is read/write. Further file operations can be performed based on the URIs in the result set. Note that the URI cannot be directly used in the **picker** callback to open a file. You need to define a global variable to save the URI and use a button to trigger file opening. The permission on the URI returned by **save()** is read/write. Further operations can be performed based on the URI in the result set. Note that the URI cannot be directly used in the **picker** callback to open a file. You need to define a global variable to save the URI and use a button to trigger file opening.
```ts ```ts
let uri = null; let uri:string;
const photoViewPicker = new picker.PhotoViewPicker(); async photoViewPickerSave() {
photoViewPicker.save(photoSaveOptions).then((photoSaveResult) => { try {
uri = photoSaveResult[0]; const photoSaveOptions = new picker.PhotoSaveOptions(); // Create a photoSaveOptions instance.
console.info('photoViewPicker.save to file succeed and uri is:' + uri); photoSaveOptions.newFileNames = ["PhotoViewPicker01.png"]; // (Optional) Name of the file to be saved. The file name in the square brackets can be customized and must be unique. If the file name already exists on the device, change the file name. Otherwise, an error will be returned.
}).catch((err) => {
console.error(`Invoke photoViewPicker.save failed, code is ${err.code}, message is ${err.message}`); const photoViewPicker = new picker.PhotoViewPicker();
}) try {
let photoSaveResult = await photoViewPicker.save(photoSaveOptions);
if (photoSaveResult != undefined) {
console.info("[picker] photoViewPickerSave photoSaveResult = " + JSON.stringify(photoSaveResult));
this.uri = photoSaveResult[0];
console.info('photoViewPicker.save to file succeed and uri is:' + photoSaveResult[0]);
}
} catch (err) {
console.error(`[picker] Invoke photoViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
}
} catch (error) {
console.info("[picker] photoViewPickerSave error = " + error);
}
}
``` ```
4. Use a button to trigger invocation of other functions. Use [fs.openSync()](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. Note that the **mode** parameter of **fs.openSync()** must be **fs.OpenMode.READ_WRITE**. 4. Use a button to trigger invocation of other functions. Use [fs.openSync()](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. Note that the **mode** parameter of **fs.openSync()** must be **fs.OpenMode.READ_WRITE**.
```ts Use [fs.write](../reference/apis/js-apis-file-fs.md#fswrite) to edit and modify the file based on the FD. After the modification is complete, close the FD.
let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
console.info('file fd: ' + file.fd);
```
5. Use [fs.writeSync()](../reference/apis/js-apis-file-fs.md#writesync) to edit the file based on the FD, and then close the FD.
```ts ```ts
let writeLen = fs.writeSync(file.fd, 'hello, world'); async writeOnly(uri) {
console.info('write data to file succeed and size is:' + writeLen); try {
fs.closeSync(file); let file = fs.openSync(uri, fs.OpenMode.WRITE_ONLY);
let writeLen = await fs.write(file.fd, pixelmapArrayBuffer);
fs.closeSync(file);
console.info("[picker] writeOnly writeLen = " + writeLen);
} catch (error) {
console.info("[picker] writeOnly error: " + error);
}
}
``` ```
## Saving Documents ## Saving Documents
......
...@@ -353,7 +353,7 @@ A constructor used to create a **SessionBackup** instance. ...@@ -353,7 +353,7 @@ A constructor used to create a **SessionBackup** instance.
```js ```js
import fs from '@ohos.file.fs'; import fs from '@ohos.file.fs';
let generalCallbacks = backup.GeneralCallbacks({ let generalCallbacks = ({
onFileReady: (err, file) => { onFileReady: (err, file) => {
if (err) { if (err) {
console.error('onFileReady failed with err: ' + err); console.error('onFileReady failed with err: ' + err);
...@@ -568,7 +568,7 @@ A constructor used to create a **SessionRestore** instance. ...@@ -568,7 +568,7 @@ A constructor used to create a **SessionRestore** instance.
```js ```js
import fs from '@ohos.file.fs'; import fs from '@ohos.file.fs';
let generalCallbacks = backup.GeneralCallbacks({ let generalCallbacks = ({
onFileReady: (err, file) => { onFileReady: (err, file) => {
if (err) { if (err) {
console.error('onFileReady failed with err: ' + err); console.error('onFileReady failed with err: ' + err);
......
# @ohos.file.picker (File Picker) # @ohos.file.picker (File Picker)
**Picker** encapsulates the system applications such as **PhotoViewPicker**, **DocumentViewPicker** and **AudioViewPicker** to provide capabilities of selecting and saving files of different types. The application can select the picker as required.
> **NOTE** > **NOTE**
> >
> The initial APIs of this module are supported since API version 9. Newly added APIs will be marked with a superscript to indicate their earliest API version. > The initial APIs of this module are supported since API version 9. Newly added APIs will be marked with a superscript to indicate their earliest API version.
**Picker** encapsulates the system applications such as **PhotoViewPicker**, **DocumentViewPicker** and **AudioViewPicker** to provide capabilities of selecting and saving files of different types. The application can select the picker as required.
## Modules to Import ## Modules to Import
```js ```js
...@@ -138,7 +138,7 @@ async function example() { ...@@ -138,7 +138,7 @@ async function example() {
save(option?: PhotoSaveOptions) : Promise&lt;Array&lt;string&gt;&gt; save(option?: PhotoSaveOptions) : Promise&lt;Array&lt;string&gt;&gt;
Saves one or more images or videos in a **photoPicker** page. This API uses a promise to return the result. You can pass in **PhotoSaveOptions** to specify the file names of the images or videos to save. Saves one or more images or videos in a **photoPicker** page. This API uses a promise to return the result. You can pass in **PhotoSaveOptions** to specify the file names of the images or videos to save. The **save()** API saves the file in the file manager, not in the Gallery.
**System capability**: SystemCapability.FileManagement.UserFileService **System capability**: SystemCapability.FileManagement.UserFileService
...@@ -177,7 +177,7 @@ async function example() { ...@@ -177,7 +177,7 @@ async function example() {
save(option: PhotoSaveOptions, callback: AsyncCallback&lt;Array&lt;string&gt;&gt;) : void save(option: PhotoSaveOptions, callback: AsyncCallback&lt;Array&lt;string&gt;&gt;) : void
Saves one or more images or videos in a **photoPicker** page. This API uses an asynchronous callback to return the result. You can pass in **PhotoSaveOptions** to specify the file names of the images or videos to save. Saves one or more images or videos in a **photoPicker** page. This API uses an asynchronous callback to return the result. You can pass in **PhotoSaveOptions** to specify the file names of the images or videos to save. The **save()** API saves the file in the file manager, not in the Gallery.
**System capability**: SystemCapability.FileManagement.UserFileService **System capability**: SystemCapability.FileManagement.UserFileService
...@@ -213,7 +213,7 @@ async function example() { ...@@ -213,7 +213,7 @@ async function example() {
save(callback: AsyncCallback&lt;Array&lt;string&gt;&gt;) : void save(callback: AsyncCallback&lt;Array&lt;string&gt;&gt;) : void
Saves one or more images or videos in a **photoPicker** page. This API uses an asynchronous callback to return the result. Saves one or more images or videos in a **photoPicker** page. This API uses an asynchronous callback to return the result. The **save()** API saves the file in the file manager, not in the Gallery.
**System capability**: SystemCapability.FileManagement.UserFileService **System capability**: SystemCapability.FileManagement.UserFileService
...@@ -727,7 +727,7 @@ Defines information about the images or videos selected. ...@@ -727,7 +727,7 @@ Defines information about the images or videos selected.
| Name | Type | Readable| Writable| Description | | Name | Type | Readable| Writable| Description |
| ----------------------- | ------------------- | ---- | ---- | ------------------------------ | | ----------------------- | ------------------- | ---- | ---- | ------------------------------ |
| photoUris | Array&lt;string&gt; | Yes | Yes | URIs of the media files selected.| | photoUris | Array&lt;string&gt; | Yes | Yes | URIs of the media files selected.|
| isOriginalPhoto | boolean | Yes | Yes | Whether the selected media file is the original image.| | isOriginalPhoto | boolean | Yes | Yes | Whether the selected media file is the original image.|
## PhotoSaveOptions ## PhotoSaveOptions
......
...@@ -4,7 +4,7 @@ The **photoAccessHelper** module provides APIs for album management, including c ...@@ -4,7 +4,7 @@ The **photoAccessHelper** module provides APIs for album management, including c
> **NOTE** > **NOTE**
> >
> - The initial APIs of this module are supported since API version 10. Newly added APIs will be marked with a superscript to indicate their earliest API version. > The initial APIs of this module are supported since API version 10. Newly added APIs will be marked with a superscript to indicate their earliest API version.
## Modules to Import ## Modules to Import
...@@ -341,7 +341,7 @@ For details about the error codes, see [File Management Error Codes](../errorcod ...@@ -341,7 +341,7 @@ For details about the error codes, see [File Management Error Codes](../errorcod
| ID| Error Message| | ID| Error Message|
| -------- | ---------------------------------------- | | -------- | ---------------------------------------- |
| 202 | Called by non-system application. | | 202 | Called by non-system application. |
| 401 | if type displayName is not string. | | 401 | if type displayName is not string. |
| 14000001 | if type of displayName is invalid. | | 14000001 | if type of displayName is invalid. |
...@@ -401,9 +401,9 @@ async function example() { ...@@ -401,9 +401,9 @@ async function example() {
let options = { let options = {
title: 'testPhoto' title: 'testPhoto'
} }
phAccessHelper.createAsset(photoType, extension, options, (err, photoAsset) => { phAccessHelper.createAsset(photoType, extension, options, (err, uri) => {
if (photoAsset != undefined) { if (uri != undefined) {
console.info('createAsset file displayName' + photoAsset.displayName); console.info('createAsset uri' + uri);
console.info('createAsset successfully'); console.info('createAsset successfully');
} else { } else {
console.error('createAsset failed, message = ', err); console.error('createAsset failed, message = ', err);
...@@ -445,9 +445,9 @@ async function example() { ...@@ -445,9 +445,9 @@ async function example() {
console.info('createAssetDemo'); console.info('createAssetDemo');
let photoType = photoAccessHelper.PhotoType.IMAGE; let photoType = photoAccessHelper.PhotoType.IMAGE;
let extension = 'jpg'; let extension = 'jpg';
phAccessHelper.createAsset(photoType, extension, (err, photoAsset) => { phAccessHelper.createAsset(photoType, extension, (err, uri) => {
if (photoAsset != undefined) { if (uri != undefined) {
console.info('createAsset file displayName' + photoAsset.displayName); console.info('createAsset uri' + uri);
console.info('createAsset successfully'); console.info('createAsset successfully');
} else { } else {
console.error('createAsset failed, message = ', err); console.error('createAsset failed, message = ', err);
...@@ -499,8 +499,8 @@ async function example() { ...@@ -499,8 +499,8 @@ async function example() {
let options = { let options = {
title: 'testPhoto' title: 'testPhoto'
} }
let photoAsset = await phAccessHelper.createAsset(photoType,extension, options); let uri = await phAccessHelper.createAsset(photoType, extension, options);
console.info('createAsset file displayName' + photoAsset.displayName); console.info('createAsset uri' + uri);
console.info('createAsset successfully'); console.info('createAsset successfully');
} catch (err) { } catch (err) {
console.error('createAsset failed, message = ', err); console.error('createAsset failed, message = ', err);
...@@ -1077,15 +1077,15 @@ async function example() { ...@@ -1077,15 +1077,15 @@ async function example() {
//file had changed, do something //file had changed, do something
} }
// Register onCallback1. // Register onCallback1.
phAccessHelper.registerChange(photoAsset.uri, false, onCallback1); phAccessHelper.registerChange(photoAsset.uri, false, onCallback1);
// Register onCallback2. // Register onCallback2.
phAccessHelper.registerChange(photoAsset.uri, false, onCallback2); phAccessHelper.registerChange(photoAsset.uri, false, onCallback2);
photoAsset.favorite(true, (err) => { photoAsset.setFavorite(true, (err) => {
if (err == undefined) { if (err == undefined) {
console.info('favorite successfully'); console.info('setFavorite successfully');
} else { } else {
console.error('favorite failed with error:' + err); console.error('setFavorite failed with error:' + err);
} }
}); });
} }
...@@ -1145,11 +1145,11 @@ async function example() { ...@@ -1145,11 +1145,11 @@ async function example() {
phAccessHelper.registerChange(photoAsset.uri, false, onCallback2); phAccessHelper.registerChange(photoAsset.uri, false, onCallback2);
// Unregister the listening of onCallback1. // Unregister the listening of onCallback1.
phAccessHelper.unRegisterChange(photoAsset.uri, onCallback1); phAccessHelper.unRegisterChange(photoAsset.uri, onCallback1);
photoAsset.favorite(true, (err) => { photoAsset.setFavorite(true, (err) => {
if (err == undefined) { if (err == undefined) {
console.info('favorite successfully'); console.info('setFavorite successfully');
} else { } else {
console.error('favorite failed with error:' + err); console.error('setFavorite failed with error:' + err);
} }
}); });
} }
...@@ -1539,7 +1539,7 @@ For details about the error codes, see [Universal Error Codes](../errorcodes/err ...@@ -1539,7 +1539,7 @@ For details about the error codes, see [Universal Error Codes](../errorcodes/err
| -------- | ---------------------------------------- | | -------- | ---------------------------------------- |
| 401 | if values to commit is invalid. | | 401 | if values to commit is invalid. |
**Example** **Example**
```ts ```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates'; import dataSharePredicates from '@ohos.data.dataSharePredicates';
...@@ -2839,7 +2839,7 @@ Obtains image and video assets. This API uses an asynchronous callback to return ...@@ -2839,7 +2839,7 @@ Obtains image and video assets. This API uses an asynchronous callback to return
| Name | Type | Mandatory| Description | | Name | Type | Mandatory| Description |
| -------- | ------------------------- | ---- | ---------- | | -------- | ------------------------- | ---- | ---------- |
| options | [FetchOptions](#fetchoptions) | Yes | Options for fetching the album files.| | options | [FetchOptions](#fetchoptions) | Yes | Options for fetching the albums.|
| callback | AsyncCallback&lt;[FetchResult](#fetchresult)&lt;[PhotoAsset](#photoasset)&gt;&gt; | Yes | Callback invoked to return the image and video assets obtained.| | callback | AsyncCallback&lt;[FetchResult](#fetchresult)&lt;[PhotoAsset](#photoasset)&gt;&gt; | Yes | Callback invoked to return the image and video assets obtained.|
**Error codes** **Error codes**
...@@ -2856,17 +2856,17 @@ For details about the error codes, see [Universal Error Codes](../errorcodes/err ...@@ -2856,17 +2856,17 @@ For details about the error codes, see [Universal Error Codes](../errorcodes/err
import dataSharePredicates from '@ohos.data.dataSharePredicates'; import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() { async function example() {
console.info('albumGetPhotoAssetsDemoCallback'); console.info('albumGetAssetsDemoCallback');
let predicates = new dataSharePredicates.DataSharePredicates(); let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = { let albumFetchOptions = {
fetchColumns: [],
predicates: predicates predicates: predicates
}; };
let fetchOption = { let fetchOption = {
fetchColumns: [], fetchColumns: [],
predicates: predicates predicates: predicates
}; };
const albumList = await phAccessHelper.getAlbums(albumFetchOptions); const albumList = await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, albumFetchOptions);
const album = await albumList.getFirstObject(); const album = await albumList.getFirstObject();
album.getAssets(fetchOption, (err, albumFetchResult) => { album.getAssets(fetchOption, (err, albumFetchResult) => {
if (albumFetchResult != undefined) { if (albumFetchResult != undefined) {
...@@ -2914,17 +2914,18 @@ For details about the error codes, see [Universal Error Codes](../errorcodes/err ...@@ -2914,17 +2914,18 @@ For details about the error codes, see [Universal Error Codes](../errorcodes/err
import dataSharePredicates from '@ohos.data.dataSharePredicates'; import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() { async function example() {
console.info('albumGetPhotoAssetsDemoPromise'); console.info('albumGetAssetsDemoPromise');
let predicates = new dataSharePredicates.DataSharePredicates(); let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = { let albumFetchOptions = {
fetchColumns: [],
predicates: predicates predicates: predicates
}; };
let fetchOption = { let fetchOption = {
fetchColumns: [], fetchColumns: [],
predicates: predicates predicates: predicates
}; };
const albumList = await phAccessHelper.getAlbums(albumFetchOptions); const albumList = await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, albumFetchOptions);
const album = await albumList.getFirstObject(); const album = await albumList.getFirstObject();
album.getAssets(fetchOption).then((albumFetchResult) => { album.getAssets(fetchOption).then((albumFetchResult) => {
console.info('album getPhotoAssets successfully, getCount: ' + albumFetchResult.getCount()); console.info('album getPhotoAssets successfully, getCount: ' + albumFetchResult.getCount());
...@@ -2967,9 +2968,10 @@ async function example() { ...@@ -2967,9 +2968,10 @@ async function example() {
console.info('albumCommitModifyDemo'); console.info('albumCommitModifyDemo');
let predicates = new dataSharePredicates.DataSharePredicates(); let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = { let albumFetchOptions = {
fetchColumns: [],
predicates: predicates predicates: predicates
}; };
const albumList = await phAccessHelper.getAlbums(albumFetchOptions); const albumList = await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, albumFetchOptions);
const album = await albumList.getFirstObject(); const album = await albumList.getFirstObject();
album.albumName = 'hello'; album.albumName = 'hello';
album.commitModify((err) => { album.commitModify((err) => {
...@@ -3015,9 +3017,10 @@ async function example() { ...@@ -3015,9 +3017,10 @@ async function example() {
console.info('albumCommitModifyDemo'); console.info('albumCommitModifyDemo');
let predicates = new dataSharePredicates.DataSharePredicates(); let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = { let albumFetchOptions = {
fetchColumns: [],
predicates: predicates predicates: predicates
}; };
const albumList = await phAccessHelper.getAlbums(albumFetchOptions); const albumList = await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, albumFetchOptions);
const album = await albumList.getFirstObject(); const album = await albumList.getFirstObject();
album.albumName = 'hello'; album.albumName = 'hello';
album.commitModify().then(() => { album.commitModify().then(() => {
...@@ -3496,6 +3499,131 @@ async function example() { ...@@ -3496,6 +3499,131 @@ async function example() {
} }
``` ```
### setCoverUri
setCoverUri(uri: string, callback: AsyncCallback&lt;void&gt;): void;
Sets the album cover. This API uses an asynchronous callback to return the result.
**NOTE**<br>This API can be used to set the user album cover, but not the system album cover.
**System API**: This is a system API.
**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO
**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | ------------------------- | ---- | ---------- |
| uri | string | Yes | URI of the file to be set as the album cover.|
| callback | AsyncCallback&lt;void&gt; | Yes | Callback that returns no value.|
**Error codes**
For details about the error codes, see [Universal Error Codes](../errorcodes/errorcode-universal.md).
| ID| Error Message|
| -------- | ---------------------------------------- |
| 202 | Called by non-system application. |
| 401 | if parameter is invalid. |
**Example**
```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() {
try {
console.info('setCoverUriDemoCallback');
let predicates = new dataSharePredicates.DataSharePredicates();
let fetchOption = {
fetchColumns: [],
predicates: predicates
};
let albumFetchResult = await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC);
let album = await albumFetchResult.getFirstObject();
let fetchResult = await album.getAssets(fetchOption);
let asset = await fetchResult.getFirstObject();
album.setCoverUri(asset.uri, (err) => {
if (err === undefined) {
console.info('album setCoverUri successfully');
} else {
console.error('album setCoverUri failed with error: ' + err);
}
});
} catch (err) {
console.error('setCoverUriDemoCallback failed with error: ' + err);
}
}
```
### setCoverUri
setCoverUri(uri: string): Promise&lt;void&gt;;
Sets the album cover. This API uses a promise to return the result.
**NOTE**<br>This API can be used to set the user album cover, but not the system album cover.
**System API**: This is a system API.
**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO
**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | ------------------------- | ---- | ---------- |
| uri | string | Yes | URI of the file to be set as the album cover.|
**Return value**
| Type | Description |
| --------------------------------------- | ----------------- |
|Promise&lt;void&gt; | Promise that returns no value.|
**Error codes**
For details about the error codes, see [Universal Error Codes](../errorcodes/errorcode-universal.md).
| ID| Error Message|
| -------- | ---------------------------------------- |
| 202 | Called by non-system application. |
| 401 | if parameter is invalid. |
**Example**
```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() {
try {
console.info('setCoverUriDemoCallback');
let predicates = new dataSharePredicates.DataSharePredicates();
let fetchOption = {
fetchColumns: [],
predicates: predicates
};
let albumFetchResult = await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC);
let album = await albumFetchResult.getFirstObject();
let fetchResult = await album.getAssets(fetchOption);
let asset = await fetchResult.getFirstObject();
album.setCoverUri(asset.uri, (err) => {
if (err === undefined) {
console.info('album setCoverUri successfully');
} else {
console.error('album setCoverUri failed with error: ' + err);
}
});
} catch (err) {
console.error('setCoverUriDemoCallback failed with error: ' + err);
}
}
```
## MemberType ## MemberType
Enumerates the member types. Enumerates the member types.
...@@ -3597,6 +3725,7 @@ Defines the key information about an image or video file. ...@@ -3597,6 +3725,7 @@ Defines the key information about an image or video file.
| POSITION | 'position' | File location type. **System API**: This is a system API. | | POSITION | 'position' | File location type. **System API**: This is a system API. |
| DATE_TRASHED | 'date_trashed' | Date when the file was deleted. The value is the number of seconds between the time when the file is deleted and January 1, 1970. **System API**: This is a system API. | | DATE_TRASHED | 'date_trashed' | Date when the file was deleted. The value is the number of seconds between the time when the file is deleted and January 1, 1970. **System API**: This is a system API. |
| HIDDEN | 'hidden' | Whether the file is hidden. **System API**: This is a system API. | | HIDDEN | 'hidden' | Whether the file is hidden. **System API**: This is a system API. |
| CAMERA_SHOT_KEY | 'camera_shot_key' | Key for the Untra Snamshot feature, which allows the camera to take photos or record videos with the screen off. (This parameter is available only for the system camera, and the key value is defined by the system camera.)<br/>**System API**: This is a system API. |
## AlbumKeys ## AlbumKeys
...@@ -3618,6 +3747,7 @@ Defines the options for creating an image or video asset. ...@@ -3618,6 +3747,7 @@ Defines the options for creating an image or video asset.
| Name | Type | Mandatory| Description | | Name | Type | Mandatory| Description |
| ---------------------- | ------------------- | ---- | ------------------------------------------------ | | ---------------------- | ------------------- | ---- | ------------------------------------------------ |
| subtype | [PhotoSubtype](#photosubtype) | No | Subtype of the image or video. **System API**: This is a system API. | | subtype | [PhotoSubtype](#photosubtype) | No | Subtype of the image or video. **System API**: This is a system API. |
| cameraShotKey | string | No | Key for the Untra Snamshot feature, which allows the camera to take photos or record videos with the screen off. (This parameter is available only for the system camera, and the key value is defined by the system camera.)<br/>**System API**: This is a system API. |
## CreateOptions ## CreateOptions
......
...@@ -53,12 +53,12 @@ For details about the error codes, see [Ability Error Codes](../errorcodes/error ...@@ -53,12 +53,12 @@ For details about the error codes, see [Ability Error Codes](../errorcodes/error
```js ```js
import uriPermissionManager from '@ohos.application.uriPermissionManager'; import uriPermissionManager from '@ohos.application.uriPermissionManager';
import WantConstant from '@ohos.ability.wantConstant'; import WantConstant from '@ohos.ability.wantConstant';
import fileio from '@ohos.fileio'; import fs from '@ohos.file.fs';
import fileUri from '@ohos.file.fileuri'; import fileUri from '@ohos.file.fileuri';
let targetBundleName = 'com.example.test_case1' let targetBundleName = 'com.example.test_case1'
let path = "file://com.example.test_case1/data/storage/el2/base/haps/entry_test/files/newDir"; let path = "file://com.example.test_case1/data/storage/el2/base/haps/entry_test/files/newDir";
fileio.mkdir(path, function (err) { fs.mkdir(path, function (err) {
if (err) { if (err) {
console.log("mkdir error"+err.message) console.log("mkdir error"+err.message)
} else { } else {
...@@ -115,13 +115,13 @@ By default, an application can authorize its own URIs to another application. If ...@@ -115,13 +115,13 @@ By default, an application can authorize its own URIs to another application. If
```js ```js
import uriPermissionManager from '@ohos.application.uriPermissionManager'; import uriPermissionManager from '@ohos.application.uriPermissionManager';
import WantConstant from '@ohos.ability.wantConstant'; import WantConstant from '@ohos.ability.wantConstant';
import fileio from '@ohos.fileio'; import fs from '@ohos.file.fs';
import fileUri from '@ohos.file.fileuri'; import fileUri from '@ohos.file.fileuri';
let targetBundleName = 'com.example.test_case1' let targetBundleName = 'com.example.test_case1'
let path = "file://com.example.test_case1/data/storage/el2/base/haps/entry_test/files/newDir"; let path = "file://com.example.test_case1/data/storage/el2/base/haps/entry_test/files/newDir";
fileio.mkdir(path, function (err) { fs.mkdir(path, function (err) {
if (err) { if (err) {
console.log("mkdir error"+err.message) console.log("mkdir error"+err.message)
} else { } else {
......
...@@ -481,113 +481,6 @@ async function example() { ...@@ -481,113 +481,6 @@ async function example() {
} }
``` ```
### getPhotoAlbums
getPhotoAlbums(options: AlbumFetchOptions, callback: AsyncCallback&lt;FetchResult&lt;Album&gt;&gt;): void;
Obtains image and video albums. This API uses an asynchronous callback to return the result.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Required permissions**: ohos.permission.READ_IMAGEVIDEO
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | ------------------------ | ---- | ------------------------- |
| options | [AlbumFetchOptions](#albumfetchoptions) | Yes | Options for fetching the albums. |
| callback | AsyncCallback&lt;[FetchResult](#fetchresult)&lt;[Album](#album)&gt;&gt; | Yes | Callback invoked to return the image and video albums obtained.|
**Error codes**
For details about the error codes, see [File Management Error Codes](../errorcodes/errorcode-filemanagement.md).
| ID| Error Message|
| -------- | ---------------------------------------- |
| 13900020 | if type options is not AlbumFetchOptions. |
**Example**
```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() {
console.info('getPhotoAlbumsDemo');
let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = {
predicates: predicates
};
mgr.getPhotoAlbums(albumFetchOptions, (err, fetchResult) => {
if (fetchResult != undefined) {
console.info('albums.count = ' + fetchResult.getCount());
fetchResult.getFirstObject((err, album) => {
if (album != undefined) {
console.info('first album.albumName = ' + album.albumName);
} else {
console.error('album is undefined, err = ', err);
}
});
} else {
console.error('getPhotoAlbums fail, message = ', err);
}
});
}
```
### getPhotoAlbums
getPhotoAlbums(options: AlbumFetchOptions): Promise&lt;FetchResult&lt;Album&gt;&gt;;
Obtains image and video albums. This API uses a promise to return the result.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Required permissions**: ohos.permission.READ_IMAGEVIDEO
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | ------------------------ | ---- | ------------------------- |
| options | [AlbumFetchOptions](#albumfetchoptions) | Yes | Options for fetching the albums. |
**Return value**
| Type | Description |
| --------------------------- | -------------- |
| Promise&lt;[FetchResult](#fetchresult)&lt;[Album](#album)&gt;&gt; | Promise used to return the image and video albums obtained.|
**Error codes**
For details about the error codes, see [File Management Error Codes](../errorcodes/errorcode-filemanagement.md).
| ID| Error Message|
| -------- | ---------------------------------------- |
| 13900020 | if type options is not AlbumFetchOptions. |
**Example**
```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() {
console.info('getPhotoAlbumsDemo');
let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = {
predicates: predicates
};
try {
let fetchResult = await mgr.getPhotoAlbums(albumFetchOptions);
console.info('album.count = ' + fetchResult.getCount());
const album = await fetchResult.getFirstObject();
console.info('first album.albumName = ' + album.albumName);
} catch (err) {
console.error('getPhotoAlbums fail, message = ' + err);
}
}
```
### createAlbum<sup>10+</sup> ### createAlbum<sup>10+</sup>
createAlbum(name: string, callback: AsyncCallback&lt;Album&gt;): void; createAlbum(name: string, callback: AsyncCallback&lt;Album&gt;): void;
...@@ -935,12 +828,124 @@ async function example() { ...@@ -935,12 +828,124 @@ async function example() {
} }
``` ```
### getPhotoAlbums
getPhotoAlbums(options: AlbumFetchOptions, callback: AsyncCallback&lt;FetchResult&lt;Album&gt;&gt;): void;
Obtains image and video albums. This API uses an asynchronous callback to return the result.
This API will be deprecated. Use [getAlbums<sup>10+</sup>](#getalbums10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Required permissions**: ohos.permission.READ_IMAGEVIDEO
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | ------------------------ | ---- | ------------------------- |
| options | [AlbumFetchOptions](#albumfetchoptions) | Yes | Options for fetching the albums. |
| callback | AsyncCallback&lt;[FetchResult](#fetchresult)&lt;[Album](#album)&gt;&gt; | Yes | Callback invoked to return the image and video albums obtained.|
**Error codes**
For details about the error codes, see [File Management Error Codes](../errorcodes/errorcode-filemanagement.md).
| ID| Error Message|
| -------- | ---------------------------------------- |
| 13900020 | if type options is not AlbumFetchOptions. |
**Example**
```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() {
console.info('getPhotoAlbumsDemo');
let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = {
predicates: predicates
};
mgr.getPhotoAlbums(albumFetchOptions, (err, fetchResult) => {
if (fetchResult != undefined) {
console.info('albums.count = ' + fetchResult.getCount());
fetchResult.getFirstObject((err, album) => {
if (album != undefined) {
console.info('first album.albumName = ' + album.albumName);
} else {
console.error('album is undefined, err = ', err);
}
});
} else {
console.error('getPhotoAlbums fail, message = ', err);
}
});
}
```
### getPhotoAlbums
getPhotoAlbums(options: AlbumFetchOptions): Promise&lt;FetchResult&lt;Album&gt;&gt;;
Obtains image and video albums. This API uses a promise to return the result.
This API will be deprecated. Use [getAlbums<sup>10+</sup>](#getalbums10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Required permissions**: ohos.permission.READ_IMAGEVIDEO
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | ------------------------ | ---- | ------------------------- |
| options | [AlbumFetchOptions](#albumfetchoptions) | Yes | Options for fetching the albums. |
**Return value**
| Type | Description |
| --------------------------- | -------------- |
| Promise&lt;[FetchResult](#fetchresult)&lt;[Album](#album)&gt;&gt; | Promise used to return the image and video albums obtained.|
**Error codes**
For details about the error codes, see [File Management Error Codes](../errorcodes/errorcode-filemanagement.md).
| ID| Error Message|
| -------- | ---------------------------------------- |
| 13900020 | if type options is not AlbumFetchOptions. |
**Example**
```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() {
console.info('getPhotoAlbumsDemo');
let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = {
predicates: predicates
};
try {
let fetchResult = await mgr.getPhotoAlbums(albumFetchOptions);
console.info('album.count = ' + fetchResult.getCount());
const album = await fetchResult.getFirstObject();
console.info('first album.albumName = ' + album.albumName);
} catch (err) {
console.error('getPhotoAlbums fail, message = ' + err);
}
}
```
### getPrivateAlbum ### getPrivateAlbum
getPrivateAlbum(type: PrivateAlbumType, callback: AsyncCallback&lt;FetchResult&lt;PrivateAlbum&gt;&gt;): void; getPrivateAlbum(type: PrivateAlbumType, callback: AsyncCallback&lt;FetchResult&lt;PrivateAlbum&gt;&gt;): void;
Obtains the system album. This API uses an asynchronous callback to return the result. Obtains the system album. This API uses an asynchronous callback to return the result.
This API will be deprecated. Use [getAlbums<sup>10+</sup>](#getalbums10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Required permissions**: ohos.permission.READ_IMAGEVIDEO **Required permissions**: ohos.permission.READ_IMAGEVIDEO
...@@ -982,6 +987,8 @@ getPrivateAlbum(type: PrivateAlbumType): Promise&lt;FetchResult&lt;PrivateAlbum& ...@@ -982,6 +987,8 @@ getPrivateAlbum(type: PrivateAlbumType): Promise&lt;FetchResult&lt;PrivateAlbum&
Obtains the system album. This API uses a promise to return the result. Obtains the system album. This API uses a promise to return the result.
This API will be deprecated. Use [getAlbums<sup>10+</sup>](#getalbums10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Required permissions**: ohos.permission.READ_IMAGEVIDEO **Required permissions**: ohos.permission.READ_IMAGEVIDEO
...@@ -1252,102 +1259,6 @@ async function example() { ...@@ -1252,102 +1259,6 @@ async function example() {
} }
``` ```
### on
on(type: ChangeEvent, callback: Callback&lt;void&gt;): void
Subscribes to changes of the file management library. This API uses a callback to return the result.
This API will be deprecated. Use [on<sup>10+</sup>](#on10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | -------------------- | ---- | ------------------------------------------------------------ |
| type | [ChangeEvent](#changeevent) | Yes | Type of event to subscribe to.<br>**deviceChange** indicates the device change.<br>**albumChange** indicates the album change.<br>**imageChange** indicates the image change.<br>**audioChange** indicates the audio file change.<br>**videoChange** indicates the video file change.<br>**remoteFileChange** indicates the file change on the registered device.|
| callback | Callback&lt;void&gt; | Yes | Callback that returns no value. |
**Example**
```ts
async function example() {
console.info('onDemo');
let count = 0;
mgr.on('imageChange', () => {
count++;
// Image file changed. Do something.
});
try {
let testFileName = 'testFile' + Date.now() + '.jpg';
let fileAsset = await mgr.createPhotoAsset(testFileName);
console.info('createPhotoAsset file displayName' + fileAsset.displayName);
console.info('createPhotoAsset successfully');
} catch (err) {
console.error('createPhotoAsset failed, message = ' + err);
}
// Sleep 1s.
if (count > 0) {
console.info('onDemo success');
} else {
console.error('onDemo fail');
}
mgr.off('imageChange', () => {
// Unsubscription succeeds.
});
}
```
### off
off(type: ChangeEvent, callback?: Callback&lt;void&gt;): void
Unsubscribes from changes of the file management library. This API uses a callback to return the result.
This API will be deprecated. Use [off<sup>10+</sup>](#off10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | -------------------- | ---- | ------------------------------------------------------------ |
| type | [ChangeEvent](#changeevent) | Yes | Type of event to subscribe to.<br>**deviceChange** indicates the device change.<br>**albumChange** indicates the album change.<br>**imageChange** indicates the image change.<br>**audioChange** indicates the audio file change.<br>**videoChange** indicates the video file change.<br>**remoteFileChange** indicates the change of the file on a registered device.|
| callback | Callback&lt;void&gt; | No | Callback that returns no value. |
**Example**
```ts
async function example() {
console.info('offDemo');
let count = 0;
mgr.on('imageChange', () => {
count++;
// Image file changed. Do something.
});
mgr.off('imageChange', () => {
// Unsubscription succeeds.
});
try {
let testFileName = 'testFile' + Date.now() + '.jpg';
let fileAsset = await mgr.createPhotoAsset(testFileName);
console.info('createPhotoAsset file displayName' + fileAsset.displayName);
console.info('createPhotoAsset successfully');
} catch (err) {
console.error('createPhotoAsset failed, message = ' + err);
}
// Sleep 1s.
if (count == 0) {
console.info('offDemo success');
} else {
console.error('offDemo fail');
}
}
```
### getActivePeers ### getActivePeers
getActivePeers(callback: AsyncCallback&lt;Array&lt;PeerInfo&gt;&gt;): void; getActivePeers(callback: AsyncCallback&lt;Array&lt;PeerInfo&gt;&gt;): void;
...@@ -1427,7 +1338,7 @@ Obtains information about all peer devices. This API uses an asynchronous callba ...@@ -1427,7 +1338,7 @@ Obtains information about all peer devices. This API uses an asynchronous callba
| Name | Type | Mandatory| Description | | Name | Type | Mandatory| Description |
| -------- | --------------------------------- | ---- | ------------ | | -------- | --------------------------------- | ---- | ------------ |
| callback | AsyncCallback&lt;Array&lt;[PeerInfo](#peerinfo)&gt;&gt; | Yes | Callback invoked to return the information obtained.| | callback | AsyncCallback&lt;Array&lt;[PeerInfo](#peerinfo)&gt;&gt; | Yes | Callback invoked to return the peer device information obtained.|
**Example** **Example**
...@@ -1545,7 +1456,7 @@ async function example() { ...@@ -1545,7 +1456,7 @@ async function example() {
on(uri: string, forSubUri: boolean, callback: Callback&lt;ChangeData&gt;) : void on(uri: string, forSubUri: boolean, callback: Callback&lt;ChangeData&gt;) : void
Enables listening for the specified URI. This API uses a callback to return the result. Registers a listener for the specified URI.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -1591,7 +1502,7 @@ async function example() { ...@@ -1591,7 +1502,7 @@ async function example() {
// File changed. Do something. // File changed. Do something.
} }
// Register onCallback1. // Register onCallback1.
mgr.on(fileAsset.uri, false, onCallback1); mgr.on(fileAsset.uri, false, onCallback1);
// Register onCallback2. // Register onCallback2.
mgr.on(fileAsset.uri, false, onCallback2); mgr.on(fileAsset.uri, false, onCallback2);
...@@ -1609,7 +1520,7 @@ async function example() { ...@@ -1609,7 +1520,7 @@ async function example() {
off(uri: string, callback?: Callback&lt;ChangeData&gt;): void off(uri: string, callback?: Callback&lt;ChangeData&gt;): void
Disables listening for the specified URI. Multiple callbacks can be registered for a URI for listening. You can use **off()** to disable the listening of the specified callbacks or all callbacks. Unregisters the listener for the specified URI. Multiple callbacks can be registered for a URI for listening. You can use this API to unregister the specified callbacks or all callbacks.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -1618,7 +1529,7 @@ Disables listening for the specified URI. Multiple callbacks can be registered f ...@@ -1618,7 +1529,7 @@ Disables listening for the specified URI. Multiple callbacks can be registered f
| Name | Type | Mandatory| Description | | Name | Type | Mandatory| Description |
| -------- | ------------------------------------------- | ---- | ------------------------------------------------------------ | | -------- | ------------------------------------------- | ---- | ------------------------------------------------------------ |
| uri | string | Yes | URI of the file asset or album, or [DefaultChangeUri](#defaultchangeuri10).| | uri | string | Yes | URI of the file asset or album, or [DefaultChangeUri](#defaultchangeuri10).|
| callback | Callback&lt;[ChangeData](#changedata10)&gt; | No | Callback registered by [on<sup>10+</sup>](#on10). If this parameter is not specified, all callbacks registered for the URI will be unregistered. <br>**NOTE**: The specified callback will not be invoked.| | callback | Callback&lt;[ChangeData](#changedata10)&gt; | No | Callback registered by [on<sup>10+</sup>](#on10). If this parameter is not specified, all listener callbacks registered for the URI will be unregistered. <br>**NOTE**: The specified callback will not be invoked.|
**Error codes** **Error codes**
...@@ -1667,6 +1578,102 @@ async function example() { ...@@ -1667,6 +1578,102 @@ async function example() {
} }
``` ```
### on
on(type: ChangeEvent, callback: Callback&lt;void&gt;): void
Subscribes to changes of the file management library. This API uses a callback to return the result.
This API will be deprecated. Use [on<sup>10+</sup>](#on10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | -------------------- | ---- | ------------------------------------------------------------ |
| type | [ChangeEvent](#changeevent) | Yes | Type of event to subscribe to.<br>**deviceChange** indicates the device change.<br>**albumChange** indicates the album change.<br>**imageChange** indicates the image change.<br>**audioChange** indicates the audio file change.<br>**videoChange** indicates the video file change.<br>**remoteFileChange** indicates the file change on the registered device.|
| callback | Callback&lt;void&gt; | Yes | Callback that returns no value. |
**Example**
```ts
async function example() {
console.info('onDemo');
let count = 0;
mgr.on('imageChange', () => {
count++;
// Image file changed. Do something.
});
try {
let testFileName = 'testFile' + Date.now() + '.jpg';
let fileAsset = await mgr.createPhotoAsset(testFileName);
console.info('createPhotoAsset file displayName' + fileAsset.displayName);
console.info('createPhotoAsset successfully');
} catch (err) {
console.error('createPhotoAsset failed, message = ' + err);
}
// Sleep 1s.
if (count > 0) {
console.info('onDemo success');
} else {
console.error('onDemo fail');
}
mgr.off('imageChange', () => {
// Unsubscription succeeds.
});
}
```
### off
off(type: ChangeEvent, callback?: Callback&lt;void&gt;): void
Unsubscribes from changes of the file management library. This API uses a callback to return the result.
This API will be deprecated. Use [off<sup>10+</sup>](#off10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | -------------------- | ---- | ------------------------------------------------------------ |
| type | [ChangeEvent](#changeevent) | Yes | Type of event to subscribe to.<br>**deviceChange** indicates the device change.<br>**albumChange** indicates the album change.<br>**imageChange** indicates the image change.<br>**audioChange** indicates the audio file change.<br>**videoChange** indicates the video file change.<br>**remoteFileChange** indicates the change of the file on a registered device.|
| callback | Callback&lt;void&gt; | No | Callback that returns no value. |
**Example**
```ts
async function example() {
console.info('offDemo');
let count = 0;
mgr.on('imageChange', () => {
count++;
// Image file changed. Do something.
});
mgr.off('imageChange', () => {
// Unsubscription succeeds.
});
try {
let testFileName = 'testFile' + Date.now() + '.jpg';
let fileAsset = await mgr.createPhotoAsset(testFileName);
console.info('createPhotoAsset file displayName' + fileAsset.displayName);
console.info('createPhotoAsset successfully');
} catch (err) {
console.error('createPhotoAsset failed, message = ' + err);
}
// Sleep 1s.
if (count == 0) {
console.info('offDemo success');
} else {
console.error('offDemo fail');
}
}
```
## FileAsset ## FileAsset
Provides APIs for encapsulating file asset attributes. Provides APIs for encapsulating file asset attributes.
...@@ -1818,7 +1825,7 @@ Commits the modification on the file metadata to the database. This API uses a p ...@@ -1818,7 +1825,7 @@ Commits the modification on the file metadata to the database. This API uses a p
| ------------------- | ---------- | | ------------------- | ---------- |
| Promise&lt;void&gt; | Promise that returns no value.| | Promise&lt;void&gt; | Promise that returns no value.|
**Example** **Example**
```ts ```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates'; import dataSharePredicates from '@ohos.data.dataSharePredicates';
...@@ -3488,6 +3495,8 @@ async function example() { ...@@ -3488,6 +3495,8 @@ async function example() {
Provides APIs for managing the system albums. Provides APIs for managing the system albums.
This API will be discarded. Use [Album](#album) instead.
### Attributes ### Attributes
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -3506,6 +3515,8 @@ getPhotoAssets(options: FetchOptions, callback: AsyncCallback&lt;FetchResult&lt; ...@@ -3506,6 +3515,8 @@ getPhotoAssets(options: FetchOptions, callback: AsyncCallback&lt;FetchResult&lt;
Obtains image and video assets from a system album. This API uses an asynchronous callback to return the result. Obtains image and video assets from a system album. This API uses an asynchronous callback to return the result.
This API will be deprecated. Use [Album.getPhotoAssets](#getphotoassets-2) instead.
**Required permissions**: ohos.permission.READ_IMAGEVIDEO **Required permissions**: ohos.permission.READ_IMAGEVIDEO
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -3557,6 +3568,8 @@ getPhotoAssets(options: FetchOptions): Promise&lt;FetchResult&lt;FileAsset&gt;&g ...@@ -3557,6 +3568,8 @@ getPhotoAssets(options: FetchOptions): Promise&lt;FetchResult&lt;FileAsset&gt;&g
Obtains image and video assets from a system album. This API uses a promise to return the result. Obtains image and video assets from a system album. This API uses a promise to return the result.
This API will be deprecated. Use [Album.getPhotoAssets](#getphotoassets-3) instead.
**Required permissions**: ohos.permission.READ_IMAGEVIDEO **Required permissions**: ohos.permission.READ_IMAGEVIDEO
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -3607,6 +3620,8 @@ delete(uri: string, callback: AsyncCallback&lt;void&gt;): void; ...@@ -3607,6 +3620,8 @@ delete(uri: string, callback: AsyncCallback&lt;void&gt;): void;
Deletes files from a system album. Deletes files from a system album.
This API will be deprecated. Use [Album.deletePhotoAssets](#deletephotoassets10) instead.
**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO **Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -3651,6 +3666,8 @@ delete(uri: string): Promise&lt;void&gt;; ...@@ -3651,6 +3666,8 @@ delete(uri: string): Promise&lt;void&gt;;
Deletes files from a system album. Deletes files from a system album.
This API will be deprecated. Use [Album.deletePhotoAssets](#deletephotoassets10) instead.
**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO **Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -3689,7 +3706,7 @@ async function example() { ...@@ -3689,7 +3706,7 @@ async function example() {
}).catch((err) => { }).catch((err) => {
console.error('trashAlbum.delete failed, message = ', err); console.error('trashAlbum.delete failed, message = ', err);
}); });
} }
``` ```
### recover ### recover
...@@ -3698,6 +3715,8 @@ recover(uri: string, callback: AsyncCallback&lt;void&gt;): void; ...@@ -3698,6 +3715,8 @@ recover(uri: string, callback: AsyncCallback&lt;void&gt;): void;
Recovers files in a system album. Recovers files in a system album.
This API will be deprecated. Use [Album.recoverPhotoAssets](#recoverphotoassets10) instead.
**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO **Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -3742,6 +3761,8 @@ recover(uri: string): Promise&lt;void&gt;; ...@@ -3742,6 +3761,8 @@ recover(uri: string): Promise&lt;void&gt;;
Recovers files in a system album. Recovers files in a system album.
This API will be deprecated. Use [Album.recoverPhotoAssets](#recoverphotoassets10) instead.
**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO **Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -3890,6 +3911,8 @@ Enumerate the album subtypes. ...@@ -3890,6 +3911,8 @@ Enumerate the album subtypes.
Enumerates the system album types. Enumerates the system album types.
This API will be deprecated. Use [AlbumType](#albumtype10) and [AlbumSubType](#albumsubtype10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
| Name | Value| Description | | Name | Value| Description |
...@@ -3938,6 +3961,7 @@ Defines the key information about an image or video file. ...@@ -3938,6 +3961,7 @@ Defines the key information about an image or video file.
| POSITION<sup>10+</sup> | position | File location type. | | POSITION<sup>10+</sup> | position | File location type. |
| DATE_TRASHED<sup>10+</sup> | date_trashed | Date when the file was deleted. The value is the number of seconds between the time when the file is deleted and January 1, 1970. | | DATE_TRASHED<sup>10+</sup> | date_trashed | Date when the file was deleted. The value is the number of seconds between the time when the file is deleted and January 1, 1970. |
| HIDDEN<sup>10+</sup> | hidden | Whether the file is hidden. | | HIDDEN<sup>10+</sup> | hidden | Whether the file is hidden. |
| CAMERA_SHOT_KEY<sup>10+</sup> | camera_shot_key | Key for the Untra Snamshot feature, which allows the camera to take photos or record videos with the screen off. (This parameter is available only for the system camera, and the key value is defined by the system camera.) |
## AlbumKey ## AlbumKey
...@@ -3962,6 +3986,7 @@ Options for creating an image or video asset. ...@@ -3962,6 +3986,7 @@ Options for creating an image or video asset.
| Name | Type | Mandatory| Description | | Name | Type | Mandatory| Description |
| ---------------------- | ------------------- | ---- | ------------------------------------------------ | | ---------------------- | ------------------- | ---- | ------------------------------------------------ |
| subType | [PhotoSubType](#photosubtype10) | No | Subtype of the image or video. | | subType | [PhotoSubType](#photosubtype10) | No | Subtype of the image or video. |
| cameraShotKey | string | No | Key for the Untra Snamshot feature, which allows the camera to take photos or record videos with the screen off. (This parameter is available only for the system camera, and the key value is defined by the system camera.) |
## FetchOptions ## FetchOptions
......
...@@ -100,6 +100,18 @@ Allows an application to read telephony information. ...@@ -100,6 +100,18 @@ Allows an application to read telephony information.
**Start version**: 8 **Start version**: 8
## ohos.permission.GET_PHONE_NUMBERS
Allows an application to obtain the phone numbers of the device.
**Permission level**: system_basic
**Authorization mode**: system_grant
**Enable via ACL**: TRUE
**Start version**: 10
## ohos.permission.REQUIRE_FORM ## ohos.permission.REQUIRE_FORM
Allows an application to obtain the Ability Form. Allows an application to obtain the Ability Form.
...@@ -776,7 +788,7 @@ Allows an application to listen for input events. Only the system signed applica ...@@ -776,7 +788,7 @@ Allows an application to listen for input events. Only the system signed applica
## ohos.permission.MANAGE_MISSIONS ## ohos.permission.MANAGE_MISSIONS
Allows an application to manage ability mission stacks. Allows an application to manage missions in the system.
**Permission level**: system_core **Permission level**: system_core
...@@ -860,7 +872,7 @@ Allows an SA to call the network management, Wi-Fi, network adapter listening, a ...@@ -860,7 +872,7 @@ Allows an SA to call the network management, Wi-Fi, network adapter listening, a
## ohos.permission.SET_ABILITY_CONTROLLER ## ohos.permission.SET_ABILITY_CONTROLLER
Allows an application to set the start and stop of an ability. Allows an application to intercept the startup of the Ability component. This permission is used for testing, such as the stability test.
**Permission level**: system_basic **Permission level**: system_basic
...@@ -956,7 +968,7 @@ Allows an application to clear application data. ...@@ -956,7 +968,7 @@ Allows an application to clear application data.
## ohos.permission.RUNNING_STATE_OBSERVER ## ohos.permission.RUNNING_STATE_OBSERVER
Allows an application to observe the application status. Allows an application to listen for its status.
**Permission level**: system_basic **Permission level**: system_basic
...@@ -1004,7 +1016,7 @@ Allows a system application to obtain Wi-Fi parameters. ...@@ -1004,7 +1016,7 @@ Allows a system application to obtain Wi-Fi parameters.
## ohos.permission.SET_WIFI_INFO ## ohos.permission.SET_WIFI_INFO
Allows an application to set Wi-Fi devices. Allows an application to set a Wi-Fi device.
**Permission level**: normal **Permission level**: normal
...@@ -1280,7 +1292,7 @@ Allows a device administrator application to set the screen-off time. ...@@ -1280,7 +1292,7 @@ Allows a device administrator application to set the screen-off time.
## ohos.permission.ENTERPRISE_INSTALL_BUNDLE ## ohos.permission.ENTERPRISE_INSTALL_BUNDLE
Allows a device administrator application to install and uninstall bundles. Allows a device administrator application to install and uninstall applications.
**Permission level**: system_core **Permission level**: system_core
...@@ -1656,7 +1668,7 @@ Allows an application to access geographical locations in the user's media file. ...@@ -1656,7 +1668,7 @@ Allows an application to access geographical locations in the user's media file.
## ohos.permission.CAMERA ## ohos.permission.CAMERA
Allows an application to use the camera to take photos and record videos. Allows an application to use the camera.
**Permission level**: normal **Permission level**: normal
...@@ -2683,3 +2695,39 @@ Allows an application to listen for the card running status. ...@@ -2683,3 +2695,39 @@ Allows an application to listen for the card running status.
**Enable via ACL**: TRUE **Enable via ACL**: TRUE
**Start version**: 10 **Start version**: 10
## ohos.permission.MANAGE_DEVICE_AUTH_CRED
Allows an application to call interfaces of the DeviceAuthCredMgr application.
**Permission level**: system_basic
**Authorization mode**: system_grant
**Enable ACL**: FALSE
**Start version**: 10
## ohos.permission.UNINSTALL_BUNDLE
Allows an application to uninstall applications.
**Permission level**: system_core
**Authorization mode**: system_grant
**Enable via ACL**: TRUE
**Start version**: 10
## ohos.permission.RECOVER_BUNDLE
Allows an application to restore pre-installed applications.
**Permission level**: system_core
**Authorization mode**: system_grant
**Enable via ACL**: TRUE
**Start version**: 10
...@@ -22,8 +22,8 @@ New IP provides at least 1% higher payload transmission efficiency than IPv4 and ...@@ -22,8 +22,8 @@ New IP provides at least 1% higher payload transmission efficiency than IPv4 and
| Scenario | Header Overhead (Bytes) | Payload Transmission Efficiency<br>(Wi-Fi MTU = 1500 Bytes, BT MTU = 255 Bytes)| | Scenario | Header Overhead (Bytes) | Payload Transmission Efficiency<br>(Wi-Fi MTU = 1500 Bytes, BT MTU = 255 Bytes)|
| --------------- | ------------ | ------------------------------------------- | | --------------- | ------------ | ------------------------------------------- |
| IPv4 for Wi-Fi | 30 + 8 + 20 = 58 | (1500 - 58)/1500 = 96.13% | | IPv4 for Wi-Fi | 30 + 8 + 20 = 58 | (1500 - 58)/1500 = 96.13% |
| IPv6 for Wi-Fi | 30 + 8 + 40 = 78 | (1500 - 78)/1500 = 94.8% | | IPv6 for Wi-Fi | 30 + 8 + 40 = 78 | (1500 - 78)/1500 = 94.8% |
| New IP for Wi-Fi | 30 + 8 + 5 = 43 | (1500 - 43)/1500 = 97.13% | | New IP for Wi-Fi | 30 + 8 + 5 = 43 | (1500 - 43)/1500 = 97.13% |
## Variable-Length Header Format ## Variable-Length Header Format
...@@ -97,7 +97,7 @@ Only the Linux 5.10 kernel of the RK3568 development board supports the New IP k ...@@ -97,7 +97,7 @@ Only the Linux 5.10 kernel of the RK3568 development board supports the New IP k
# kernel/linux/config/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig # kernel/linux/config/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig
CONFIG_NEWIP=y // Enable the New IP kernel protocol stack. CONFIG_NEWIP=y // Enable the New IP kernel protocol stack.
CONFIG_NEWIP_HOOKS=y // Enable New IP stub functions to be dynamically registered non-disruptively. This feature must be enabled when New IP is enabled. CONFIG_NEWIP_HOOKS=y // Enable New IP stub functions to be dynamically registered non-disruptively. This feature must be enabled when New IP is enabled.
VENDOR_HOOKS=y // Enable the basic kernel instrumentation framework. New IP depends on this setting. It is enabled by default for the RK3568 development board. HCK_VENDOR_HOOKS=y // Enable the basic kernel instrumentation framework. New IP depends on this framework. It is enabled by default on the RK3568 development board.
``` ```
Run the following command to check whether the New IP protocol stack is successfully enabled: Run the following command to check whether the New IP protocol stack is successfully enabled:
...@@ -119,8 +119,18 @@ out/kernel/OBJ/linux-5.10/net/newip/tcp_nip_output.o ...@@ -119,8 +119,18 @@ out/kernel/OBJ/linux-5.10/net/newip/tcp_nip_output.o
```c ```c
/* Register the New IP ehash function with the kernel. */ /* Register the New IP ehash function with the kernel. */
register_trace_ninet_ehashfn_hook(&ninet_ehashfn_hook, NULL); /* Call the newip hook function in sk_ehashfn function (net\ipv4\inet_hashtables.c):
*/
void nip_ninet_ehashfn(const struct sock *sk, u32 *ret)
{
*ret = ninet_ehashfn(sock_net(sk), &sk->SK_NIP_RCV_SADDR,
sk->sk_num, &sk->SK_NIP_DADDR, sk->sk_dport);
}
void nip_ninet_ehashfn_lhck_register(void)
{
REGISTER_HCK_LITE_HOOK(nip_ninet_ehashfn_lhck, nip_ninet_ehashfn);
}
/* Add the New IP stack processing to the general entry function of IPv4/IPv6 stacks. */ /* Add the New IP stack processing to the general entry function of IPv4/IPv6 stacks. */
static u32 sk_ehashfn(const struct sock *sk) static u32 sk_ehashfn(const struct sock *sk)
...@@ -134,14 +144,12 @@ static u32 sk_ehashfn(const struct sock *sk) ...@@ -134,14 +144,12 @@ static u32 sk_ehashfn(const struct sock *sk)
&sk->sk_v6_daddr, sk->sk_dport); &sk->sk_v6_daddr, sk->sk_dport);
#endif #endif
if (trace_vendor_ninet_ehashfn_enabled()) { if (sk->sk_family == AF_NINET) {
if (sk->sk_family == AF_NINET) { u32 ret = 0;
u32 ret = 0;
/* Register the New IP ehash function. */ /* Register the New IP ehash function. */
trace_vendor_ninet_ehashfn(sk, &ret); CALL_HCK_LITE_HOOK(nip_ninet_ehashfn_lhck, sk, &ret);
return ret; return ret;
}
} }
/* IPv4 */ /* IPv4 */
return inet_ehashfn(sock_net(sk), return inet_ehashfn(sock_net(sk),
...@@ -166,8 +174,8 @@ The user-mode application calls **socket()** to create a New IP socket and uses ...@@ -166,8 +174,8 @@ The user-mode application calls **socket()** to create a New IP socket and uses
| API | Input | Output | Return Value | Description | | API | Input | Output | Return Value | Description |
| -------- | ------------------------------------------------------------ | ---------------------------------------------- | ---------------- | ------------------------------------------------------------ | | -------- | ------------------------------------------------------------ | ---------------------------------------------- | ---------------- | ------------------------------------------------------------ |
| socket | int **domain**, int type, int **protocol** | NA | Socket handle **sockfd**.| Creates a New IP socket. <br>**domain** must be **AF_NINET**, which indicates a New IP socket.<br>**protocol** can be **IPPROTO_TCP** or **IPPROTO_UDP**.<br>This API returns the handle of the **socket** instance created.| | socket | int **domain**, int type, int **protocol** | NA | Socket handle **sockfd**.| Creates a New IP socket. <br>**domain** must be **AF_NINET**, which indicates a New IP socket.<br>**protocol** can be **IPPROTO_TCP** or **IPPROTO_UDP**.<br>This API returns the handle of the **socket** instance created. |
| bind | int sockfd, const **struct sockaddr_nin** *myaddr, socklen_t addrlen | NA | Error code, which is an integer. | Binds the **socket** instance to the specified IP address and port.<br> **myaddr->sin_family** must be **AF_NINET**.| | bind | int sockfd, const **struct sockaddr_nin** *myaddr, socklen_t addrlen | NA | Error code, which is an integer. | Binds the **socket** instance to the specified IP address and port.<br>**myaddr->sin_family** must be **AF_NINET**. |
| listen | int socket, int backlog | NA | Error code, which is an integer. | Listens for the New IP address and port from the server. | | listen | int socket, int backlog | NA | Error code, which is an integer. | Listens for the New IP address and port from the server. |
| connect | int sockfd, const **struct sockaddr_nin** *addr, aocklen_t addrlen | NA | Error code, which is an integer. | Sets up a connection between the client and the server. | | connect | int sockfd, const **struct sockaddr_nin** *addr, aocklen_t addrlen | NA | Error code, which is an integer. | Sets up a connection between the client and the server. |
| accept | int sockfd, **struct sockaddr_nin** *address, socklen_t *address_len | NA | **sockfd**. | Accepts the connection request from the client. | | accept | int sockfd, **struct sockaddr_nin** *address, socklen_t *address_len | NA | **sockfd**. | Accepts the connection request from the client. |
......
...@@ -441,3 +441,9 @@ export default class MySequenceable { ...@@ -441,3 +441,9 @@ export default class MySequenceable {
private str; private str;
} }
``` ```
## 相关实例
针对IDL的使用,有以下相关实例可供参考:
- [Ability与ServiceExtensionAbility通信(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/IDL/AbilityConnectServiceExtension)
\ No newline at end of file
...@@ -138,5 +138,4 @@ onAccessibilityEvent(accessibilityEvent) { ...@@ -138,5 +138,4 @@ onAccessibilityEvent(accessibilityEvent) {
针对AccessibilityExtensionAbility开发,有以下相关实例可供参考: 针对AccessibilityExtensionAbility开发,有以下相关实例可供参考:
[AccessibilityExtAbility的创建和使用(ArkTS)(API 9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/AccessibilityExtAbility) - [无障碍扩展(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/AccessibilityExtAbility)
...@@ -219,3 +219,9 @@ ...@@ -219,3 +219,9 @@
## 数据提供方开发步骤 ## 数据提供方开发步骤
参考[数据管理](../database/share-data-by-silent-access.md)开发指南。 参考[数据管理](../database/share-data-by-silent-access.md)开发指南。
## 相关实例
针对卡片代理开发,有以下相关实例可供参考:
- [应用主动添加数据代理卡片到桌面(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/RequestAddForm)
\ No newline at end of file
...@@ -60,3 +60,11 @@ ArkTS卡片相较于JS卡片具备了更加丰富的能力,但也增加了使 ...@@ -60,3 +60,11 @@ ArkTS卡片相较于JS卡片具备了更加丰富的能力,但也增加了使
- 暂不支持Hot Reload热重载。 - 暂不支持Hot Reload热重载。
- 暂不支持setTimeOut。 - 暂不支持setTimeOut。
## 相关实例
针对ArkTS卡片开发,有以下相关实例可供参考:
- [Stage模型卡片(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/FormExtAbility)
- [Stage模型卡片JS与C++通信(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/FormGame)
\ No newline at end of file
...@@ -118,5 +118,5 @@ ...@@ -118,5 +118,5 @@
针对StaticSubscriberExtensionAbility开发,可参考如下实例: 针对StaticSubscriberExtensionAbility开发,可参考如下实例:
- [StaticSubscriber:静态订阅(ArkTS)(API9)(Full SDK](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/StaticSubscriber) - [静态订阅(ArkTS)(Full SDK)(API10](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/StaticSubscriber)
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
- 若目标组件exported字段配置为false,则需校验`ohos.permission.START_INVISIBLE_ABILITY`权限 - 若目标组件exported字段配置为false,则需校验`ohos.permission.START_INVISIBLE_ABILITY`权限
- [组件exported配置参考](../quick-start/module-configuration-file.md#abilities标签) - [组件exported配置参考](../quick-start/module-configuration-file.md#abilities标签)
- **位于后台的应用,启动组件需校验BACKGROUND权限** - **位于后台的UIAbility应用,启动组件需校验BACKGROUND权限**
- 应用前后台判断标准:若应用进程获焦或所属的UIAbility位于前台则判定为前台应用,否则为后台应用 - 应用前后台判断标准:若应用进程获焦或所属的UIAbility位于前台则判定为前台应用,否则为后台应用
- 需校验`ohos.permission.START_ABILITIES_FROM_BACKGROUND`权限 - 需校验`ohos.permission.START_ABILITIES_FROM_BACKGROUND`权限
...@@ -46,7 +46,9 @@ ...@@ -46,7 +46,9 @@
设备内启动组件,不同场景下的规则不同,可分为如下两种场景: 设备内启动组件,不同场景下的规则不同,可分为如下两种场景:
- 启动或连接组件:UIAbility、ServiceExtensionAbility、DataShareExtensionAbility。 - 启动UIAbility。
- 启动ServiceExtensionAbility、DataShareExtensionAbility。
- 通过startAbilityByCall接口启动UIAbility。 - 通过startAbilityByCall接口启动UIAbility。
...@@ -57,7 +59,9 @@ ...@@ -57,7 +59,9 @@
跨设备启动组件,不同场景下的规则不同,可分为如下两种场景: 跨设备启动组件,不同场景下的规则不同,可分为如下两种场景:
- 启动或连接组件:UIAbility、ServiceExtensionAbility、DataShareExtensionAbility。 - 启动UIAbility。
- 启动ServiceExtensionAbility、DataShareExtensionAbility。
- 通过startAbilityByCall接口启动UIAbility。 - 通过startAbilityByCall接口启动UIAbility。
......
...@@ -103,11 +103,8 @@ export default class EnterpriseAdminAbility extends EnterpriseAdminExtensionAbil ...@@ -103,11 +103,8 @@ export default class EnterpriseAdminAbility extends EnterpriseAdminExtensionAbil
} }
``` ```
## 相关实例 ## 相关实例
针对EnterpriseAdminExtensionAbility开发,有以下相关示例可供参考: 针对EnterpriseAdminExtensionAbility开发,有以下相关示例可供参考:
[EnterpriseAdminExtensionAbility:EnterpriseAdminExtensionAbility的创建与使用(ArkTS) (API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/EnterpriseAdminExtensionAbility) - [企业设备管理扩展(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/EnterpriseAdminExtensionAbility)
...@@ -616,6 +616,8 @@ onUpdateForm(formId) { ...@@ -616,6 +616,8 @@ onUpdateForm(formId) {
针对卡片开发,有以下相关实例可供参考: 针对卡片开发,有以下相关实例可供参考:
- [JS多设备自适应服务卡片(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/AdaptiveServiceWidget)
- [电影卡片(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Card/MovieCard) - [电影卡片(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Card/MovieCard)
- [计步器卡片(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Card/StepsCardJS) - [计步器卡片(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Card/StepsCardJS)
\ No newline at end of file
...@@ -126,4 +126,8 @@ ...@@ -126,4 +126,8 @@
}) })
``` ```
## 相关实例
针对任务管理开发,有以下相关实例可供参考:
- [任务管理(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/MissionManager)
...@@ -60,11 +60,12 @@ ArkTS卡片与JS卡片具备不同的实现原理及特征,在场景能力上 ...@@ -60,11 +60,12 @@ ArkTS卡片与JS卡片具备不同的实现原理及特征,在场景能力上
针对Stage模型卡片提供方的开发,有以下相关实例可供参考: 针对Stage模型卡片提供方的开发,有以下相关实例可供参考:
- [ArkTS音乐卡片(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/ArkTSCard/MusicControl)
- [基于Stage模型的JS卡片(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/FormExtAbility) - [Stage模型卡片(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/FormExtAbility)
- [基于Stage模型的JS卡片(成语接龙小游戏)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/FormGame) - [Stage模型卡片JS与C++通信(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/FormGame)
- [基于Stage模型的ArkTS卡片(Canvas绘制实现的五子棋游戏卡片)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/ArkTSCard/CanvasGame) - [ArkTS卡片Canvas小游戏(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/ArkTSCard/CanvasGame)
- [基于Stage模型的ArkTS卡片(逻辑代码执行实现的计算器卡片)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/ArkTSCard/Calculator) - [ArkTS卡片计算器(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/ArkTSCard/Calculator)
...@@ -453,5 +453,8 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap ...@@ -453,5 +453,8 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap
针对ServiceExtensionAbility开发,有以下相关实例可供参考: 针对ServiceExtensionAbility开发,有以下相关实例可供参考:
- [`AbilityConnectServiceExtension`:Ability与ServiceExtensionAbility通信(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/IDL/AbilityConnectServiceExtension) - [跨任务链返回(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/TestRely/LauncherTest/CrossChainBack)
- [`StageModel`:Stage模型(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/ApplicationModels/StageModel)
- [Ability与ServiceExtensionAbility通信(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/IDL/AbilityConnectServiceExtension)
- [Stage模型(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/ApplicationModels/StageModel)
...@@ -41,3 +41,9 @@ ...@@ -41,3 +41,9 @@
| 了解线程模型 | 本章节介绍了Stage模型的线程模型以及几种常用的线程间通信方式。 | -&nbsp;[Emitter](itc-with-emitter.md)<br/>-&nbsp;[Worker](itc-with-worker.md) | | 了解线程模型 | 本章节介绍了Stage模型的线程模型以及几种常用的线程间通信方式。 | -&nbsp;[Emitter](itc-with-emitter.md)<br/>-&nbsp;[Worker](itc-with-worker.md) |
| 任务管理 | 本章节介绍了Stage模型中任务管理的基本概念和典型场景。 | -&nbsp;[任务管理场景介绍](mission-management-overview.md)<br/>-&nbsp;[任务管理与启动模式](mission-management-launch-type.md)<br/>-&nbsp;[页面栈和任务链](page-mission-stack.md) | | 任务管理 | 本章节介绍了Stage模型中任务管理的基本概念和典型场景。 | -&nbsp;[任务管理场景介绍](mission-management-overview.md)<br/>-&nbsp;[任务管理与启动模式](mission-management-launch-type.md)<br/>-&nbsp;[页面栈和任务链](page-mission-stack.md) |
| 应用配置文件 | 本章节介绍Stage模型中应用配置文件的开发要求。 | [Stage模型应用配置文件](config-file-stage.md) | | 应用配置文件 | 本章节介绍Stage模型中应用配置文件的开发要求。 | [Stage模型应用配置文件](config-file-stage.md) |
## 相关实例
针对Stage模型开发,有以下相关实例可供参考:
- [Stage模型(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/ApplicationModels/StageModel)
\ No newline at end of file
...@@ -151,3 +151,9 @@ specified启动模式为指定实例模式,针对一些特殊场景使用( ...@@ -151,3 +151,9 @@ specified启动模式为指定实例模式,针对一些特殊场景使用(
2. 在最近任务列表中关闭`文件A`的任务进程,此时`UIAbility实例1`被销毁,回到桌面,再次打开`文件A`,此时对应启动一个新的UIAbility实例,例如启动`UIAbility实例2` 2. 在最近任务列表中关闭`文件A`的任务进程,此时`UIAbility实例1`被销毁,回到桌面,再次打开`文件A`,此时对应启动一个新的UIAbility实例,例如启动`UIAbility实例2`
3. 回到桌面,打开`文件B`,此时对应启动一个新的UIAbility实例,例如启动`UIAbility实例3` 3. 回到桌面,打开`文件B`,此时对应启动一个新的UIAbility实例,例如启动`UIAbility实例3`
4. 回到桌面,再次打开`文件A`,此时仍然启动之前的`UIAbility实例2`,因为系统会自动匹配UIAbility实例的Key值,如果存在与之匹配的Key,则会启动与之绑定的UIAbility实例。在此例中,之前启动的`UIAbility实例2``文件A`绑定的Key是相同的,因此系统会拉回`UIAbility实例2`并让其获焦,而不会创建新的实例。 4. 回到桌面,再次打开`文件A`,此时仍然启动之前的`UIAbility实例2`,因为系统会自动匹配UIAbility实例的Key值,如果存在与之匹配的Key,则会启动与之绑定的UIAbility实例。在此例中,之前启动的`UIAbility实例2``文件A`绑定的Key是相同的,因此系统会拉回`UIAbility实例2`并让其获焦,而不会创建新的实例。
## 相关实例
针对UIAbility组件启动模式,有以下相关实例可供参考:
- [Ability的启动模式(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/ApplicationModels/AbilityStartMode)
\ No newline at end of file
...@@ -48,6 +48,6 @@ ...@@ -48,6 +48,6 @@
> - 匹配到一个满足条件的应用组件:直接启动该应用组件。 > - 匹配到一个满足条件的应用组件:直接启动该应用组件。
> - 匹配到多个满足条件的应用组件(UIAbility):弹出选择框让用户选择。 > - 匹配到多个满足条件的应用组件(UIAbility):弹出选择框让用户选择。
> >
> - 调用方传入的want参数中不带有abilityName和bundleName,则不允许通过隐式Want启动所有应用的ServiceExtensionAbility。 > - 对于启动ServiceExtensionAbility的场景:
> > - 调用方传入的want参数中带有abilityName,则不允许通过隐式Want启动ServiceExtensionAbility。
> - 调用方传入的want参数中带有bundleName,则允许使用startServiceExtensionAbility()方法隐式Want启动ServiceExtensionAbility,默认返回优先级最高的ServiceExtensionAbility,如果优先级相同,返回第一个。 > - 调用方传入的want参数中带有bundleName,则允许使用startServiceExtensionAbility()方法隐式Want启动ServiceExtensionAbility,默认返回优先级最高的ServiceExtensionAbility,如果优先级相同,返回第一个。
...@@ -116,4 +116,4 @@ struct Index { ...@@ -116,4 +116,4 @@ struct Index {
针对WindowExtensionAbility开发,有以下相关实例可供参考: 针对WindowExtensionAbility开发,有以下相关实例可供参考:
- [`WindowExtAbility`:WindowExtAbility的创建与使用(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/WindowManagement/WindowExtAbility) - [窗口扩展应用(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/WindowManagement/WindowExtAbility)
...@@ -36,4 +36,4 @@ ArkTS语言基础类库是OpenHarmony系统上为应用开发者提供的常用 ...@@ -36,4 +36,4 @@ ArkTS语言基础类库是OpenHarmony系统上为应用开发者提供的常用
针对语言基础类库的开发,有以下相关实例可供参考: 针对语言基础类库的开发,有以下相关实例可供参考:
- [LanguageBaseClassLibrary:语言基础类库](https://gitee.com/openharmony/applications_app_samples/tree/master/code/LaunguageBaseClassLibrary/LanguageBaseClassLibrary) - [语言基础类库(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/LaunguageBaseClassLibrary/LanguageBaseClassLibrary)
...@@ -57,4 +57,4 @@ ArkTS提供了TaskPool和Worker两种并发能力供开发者选择,其具体 ...@@ -57,4 +57,4 @@ ArkTS提供了TaskPool和Worker两种并发能力供开发者选择,其具体
针对多线程开发,有以下相关实例可供参考: 针对多线程开发,有以下相关实例可供参考:
- [ConcurrentModule:多线程任务](https://gitee.com/openharmony/applications_app_samples/tree/master/code/LaunguageBaseClassLibrary/ConcurrentModule) - [多线程任务(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/LaunguageBaseClassLibrary/ConcurrentModule)
...@@ -52,7 +52,8 @@ httpRequest.on('headersReceive', (header) => { ...@@ -52,7 +52,8 @@ httpRequest.on('headersReceive', (header) => {
console.info('header: ' + JSON.stringify(header)); console.info('header: ' + JSON.stringify(header));
}); });
httpRequest.request( httpRequest.request(
// 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定"EXAMPLE_URL", // 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
"EXAMPLE_URL",
{ {
method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
// 开发者根据自身业务需要添加header字段 // 开发者根据自身业务需要添加header字段
...@@ -81,7 +82,7 @@ httpRequest.request( ...@@ -81,7 +82,7 @@ httpRequest.request(
// 当该请求使用完毕时,调用destroy方法主动销毁 // 当该请求使用完毕时,调用destroy方法主动销毁
httpRequest.destroy(); httpRequest.destroy();
} else { } else {
console.info('error:' + JSON.stringify(err)); console.error('error:' + JSON.stringify(err));
// 取消订阅HTTP响应头事件 // 取消订阅HTTP响应头事件
httpRequest.off('headersReceive'); httpRequest.off('headersReceive');
// 当该请求使用完毕时,调用destroy方法主动销毁 // 当该请求使用完毕时,调用destroy方法主动销毁
...@@ -146,7 +147,7 @@ httpRequest.requestInStream( ...@@ -146,7 +147,7 @@ httpRequest.requestInStream(
readTimeout: 60000, // 可选,默认为60000ms。若传输的数据较大,需要较长的时间,建议增大该参数以保证数据传输正常终止 readTimeout: 60000, // 可选,默认为60000ms。若传输的数据较大,需要较长的时间,建议增大该参数以保证数据传输正常终止
usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定 usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
}, (err, data) => { }, (err, data) => {
console.info('error:' + JSON.stringify(err)); console.error('error:' + JSON.stringify(err));
console.info('ResponseCode :' + JSON.stringify(data)); console.info('ResponseCode :' + JSON.stringify(data));
// 取消订阅HTTP响应头事件 // 取消订阅HTTP响应头事件
httpRequest.off('headersReceive'); httpRequest.off('headersReceive');
...@@ -166,5 +167,8 @@ httpRequest.requestInStream( ...@@ -166,5 +167,8 @@ httpRequest.requestInStream(
针对HTTP数据请求,有以下相关实例可供参考: 针对HTTP数据请求,有以下相关实例可供参考:
- [`Http:`数据请求(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/Http) - [上传和下载(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Connectivity/Upload)
- [Http(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/Http)
- [新闻数据加载(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/NetworkManagement/NewsDataArkTS) - [新闻数据加载(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/NetworkManagement/NewsDataArkTS)
\ No newline at end of file
...@@ -355,3 +355,8 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信, ...@@ -355,3 +355,8 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
globalThis.context.disconnectServiceExtensionAbility(connectId); globalThis.context.disconnectServiceExtensionAbility(connectId);
``` ```
## 相关实例
针对IPC与RPC通信开发,有以下相关实例可供参考:
- [RPC通信(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/RPC)
...@@ -409,4 +409,4 @@ tlsTwoWay.close((err) => { ...@@ -409,4 +409,4 @@ tlsTwoWay.close((err) => {
针对Socket连接开发,有以下相关实例可供参考: 针对Socket连接开发,有以下相关实例可供参考:
- [`Socket`:Socket 连接(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/Socket) - [网络管理-Socket连接(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/Socket)
\ No newline at end of file \ No newline at end of file
...@@ -85,4 +85,4 @@ ws.connect(defaultIpAddress, (err, value) => { ...@@ -85,4 +85,4 @@ ws.connect(defaultIpAddress, (err, value) => {
针对WebSocket连接的开发,有以下相关实例可供参考: 针对WebSocket连接的开发,有以下相关实例可供参考:
- [`WebSocket`:WebSocket(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/WebSocket) - [WebSocket(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/WebSocket)
\ No newline at end of file \ No newline at end of file
...@@ -226,7 +226,11 @@ ...@@ -226,7 +226,11 @@
针对用户首选项开发,有以下相关实例可供参考: 针对用户首选项开发,有以下相关实例可供参考:
- [`Preferences`:首选项(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DataManagement/Preferences) - [游戏2048(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Game/Game2048)
- [图案密码锁(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Tools/PatternLock)
- [首选项(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DataManagement/Preferences)
- [首选项(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Data/Preferences) - [首选项(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Data/Preferences)
......
...@@ -304,4 +304,12 @@ ...@@ -304,4 +304,12 @@
localObject.setSessionId(() => { localObject.setSessionId(() => {
console.info('leave all lession.'); console.info('leave all lession.');
}); });
``` ```
\ No newline at end of file
## 相关实例
针对分布式数据对象开发,有以下相关实例可供参考:
- [分布式组网认证(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedAuthentication)
- [分布式对象(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedNote)
\ No newline at end of file
...@@ -281,4 +281,18 @@ ...@@ -281,4 +281,18 @@
针对键值型数据库开发,有以下相关实例可供参考: 针对键值型数据库开发,有以下相关实例可供参考:
- [分布式组网认证(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedAuthentication)
- [分布式数据管理(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/Kvstore)
- [分布式音乐播放(JS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/JsDistributedMusicPlayer)
- [分布式音乐播放(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/ArkTSDistributedMusicPlayer)
- [分布式计算器(JS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributeCalc)
- [分布式计算器(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/ArkTSDistributedCalc)
- [分布式五子棋(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Game/DistributedDataGobang)
- [分布式手写板(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/codelabs/tree/master/Distributed/DistributeDraw) - [分布式手写板(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/codelabs/tree/master/Distributed/DistributeDraw)
\ No newline at end of file
...@@ -171,3 +171,13 @@ ...@@ -171,3 +171,13 @@
) )
}) })
``` ```
## 相关实例
针对关系型数据库开发,有以下相关实例可供参考:
- [分布式组网认证(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedAuthentication)
-[分布式关系型数据库(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedRdb)
- [分布式帐号(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedAccount)
\ No newline at end of file
...@@ -243,4 +243,4 @@ ...@@ -243,4 +243,4 @@
针对数据共享开发,有以下相关实例可供参考: 针对数据共享开发,有以下相关实例可供参考:
- [`CrossAppDataShare`:系统应用跨应用数据共享(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/DataManagement/CrossAppDataShare) - [系统应用跨应用数据共享(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/DataManagement/CrossAppDataShare)
\ No newline at end of file \ No newline at end of file
...@@ -37,3 +37,9 @@ ...@@ -37,3 +37,9 @@
## 跨设备同步访问控制机制 ## 跨设备同步访问控制机制
数据跨设备同步时,数据管理基于设备等级和数据安全标签进行访问控制,具体可见[跨设备同步访问控制机制](access-control-by-device-and-data-level.md#跨设备同步访问控制机制) 数据跨设备同步时,数据管理基于设备等级和数据安全标签进行访问控制,具体可见[跨设备同步访问控制机制](access-control-by-device-and-data-level.md#跨设备同步访问控制机制)
## 相关实例
针对分布式开发,有以下相关实例可供参考:
- [分布式组网认证(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedAuthentication)
\ No newline at end of file
...@@ -538,5 +538,8 @@ import usageStatistics from '@ohos.resourceschedule.usageStatistics'; ...@@ -538,5 +538,8 @@ import usageStatistics from '@ohos.resourceschedule.usageStatistics';
针对设备使用信息统计,有以下相关实例可供参考: 针对设备使用信息统计,有以下相关实例可供参考:
- [`DeviceUsageStatistics`:设备使用信息统计(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceUsageStatistics/DeviceUsageStatistics) - [存储空间统计(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/DeviceManagement/StorageStatistic)
- [设备使用信息统计(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceUsageStatistics/DeviceUsageStatistics)
...@@ -406,4 +406,10 @@ ...@@ -406,4 +406,10 @@
}); });
``` ```
5. 当设备进入或者退出该围栏时,系统会自动触发WantAgent的动作。 5. 当设备进入或者退出该围栏时,系统会自动触发WantAgent的动作。
\ No newline at end of file
## 相关实例
针对位置开发,有以下相关实例可供参考:
- [位置服务(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Location)
\ No newline at end of file
...@@ -270,5 +270,6 @@ async function playCustomHaptic(fileName) { ...@@ -270,5 +270,6 @@ async function playCustomHaptic(fileName) {
针对振动开发,有以下相关实例可供参考: 针对振动开发,有以下相关实例可供参考:
- [`Vibrator`:振动(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/BasicVibration) - [振动(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/BasicVibration)
- [`CustomHaptic`:自定义振动(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/CustomHaptic)
- [自定义振动(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/CustomHaptic)
...@@ -193,3 +193,9 @@ APP_LIFECYCLE_TIMEOUT: ...@@ -193,3 +193,9 @@ APP_LIFECYCLE_TIMEOUT:
![appfreeze_20230310105874](figures/appfreeze_20230310105874.png) ![appfreeze_20230310105874](figures/appfreeze_20230310105874.png)
其他的日志信息可以参考[通用日志信息](#日志主干通用信息)进行分析。需要特别说明的是,一般情况下生命周期切换大概率主线程也会卡死。可以结合两个日志的三个堆栈、两个BinderCatcher信息,进行对比查看。 其他的日志信息可以参考[通用日志信息](#日志主干通用信息)进行分析。需要特别说明的是,一般情况下生命周期切换大概率主线程也会卡死。可以结合两个日志的三个堆栈、两个BinderCatcher信息,进行对比查看。
## 相关实例
针对故障日志获取,有以下相关实力可供参考:
- [故障日志获取(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DFX/FaultLogger)
\ No newline at end of file
...@@ -105,3 +105,9 @@ Thread name:crasher <- 异常线程名 ...@@ -105,3 +105,9 @@ Thread name:crasher <- 异常线程名
范例中的崩溃故障是由赋值给一块不可写的区域导致的,代码行为dfx_crasher.c文件的57行,修改后可以避免发生此崩溃。\ 范例中的崩溃故障是由赋值给一块不可写的区域导致的,代码行为dfx_crasher.c文件的57行,修改后可以避免发生此崩溃。\
另外,使用addr2line后,如果得出的行号看起来不是很正确,可以考虑对地址进行微调(如减1),或者考虑关闭一些编译优化,已知使用LTO的二进制可能无法正确获得行号。 另外,使用addr2line后,如果得出的行号看起来不是很正确,可以考虑对地址进行微调(如减1),或者考虑关闭一些编译优化,已知使用LTO的二进制可能无法正确获得行号。
## 相关实例
针对故障日志获取,有以下相关实力可供参考:
- [故障日志获取(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DFX/FaultLogger)
\ No newline at end of file
...@@ -151,4 +151,6 @@ HiAppEvent是在系统层面为应用开发者提供的一种事件打点机制 ...@@ -151,4 +151,6 @@ HiAppEvent是在系统层面为应用开发者提供的一种事件打点机制
针对应用事件开发,有以下相关实例可供参考: 针对应用事件开发,有以下相关实例可供参考:
- [`DotTest`:测试打点(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DFX/DotTest) - [测试打点(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DFX/DotTest)
\ No newline at end of file
- [日志打印(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DFX/Logger)
\ No newline at end of file
...@@ -21,42 +21,6 @@ try { ...@@ -21,42 +21,6 @@ try {
} }
``` ```
## 如何隐藏状态栏实现沉浸式效果
适用于:OpenHarmony 3.2 Beta5,API 9
**解决措施**
1. 可以在onWindowStageCreate方法获取windowClass对象。
```
onWindowStageCreate(windowStage) {
// Main window is created, set main page for this ability
console.log("[Demo] MainAbility onWindowStageCreate")
windowStage.getMainWindow((err, data) => {
if (err.code) {
console.error('Failed to obtain the main window.')
return;
}
// 获取到窗口对象
globalThis.windowClass = data;
})
}
```
2. 设置窗口全屏,隐藏状态栏。
```
globalThis.windowClass.setFullScreen(isFullScreen, (err, data) => {
if (err.code) {
console.error('Failed to enable the full-screen mode. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in enabling the full-screen mode. Data: ' + JSON.stringify(data));
});
```
## 如何获取窗口的宽高信息 ## 如何获取窗口的宽高信息
适用于:OpenHarmony 3.2 Beta5,API 9 Stage模型 适用于:OpenHarmony 3.2 Beta5,API 9 Stage模型
......
...@@ -78,3 +78,9 @@ BackupExtensionAbility,是[Stage模型](../../application-dev/application-mode ...@@ -78,3 +78,9 @@ BackupExtensionAbility,是[Stage模型](../../application-dev/application-mode
] ]
} }
``` ```
## 相关实例
针对应用接入数据的备份与恢复,有以下相关实例可供参考:
- [应用接入数据备份恢复(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/FileManagement/FileBackupExtension)
\ No newline at end of file
...@@ -23,3 +23,9 @@ ...@@ -23,3 +23,9 @@
**图1** 文件分类模型示意图 **图1** 文件分类模型示意图
![File classification model](figures/file-classification-model.png) ![File classification model](figures/file-classification-model.png)
## 相关实例
针对文件管理开发,有以下相关实例可供参考:
- [文件管理(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/FileManagement/FileManager)
\ No newline at end of file
...@@ -731,4 +731,12 @@ try { ...@@ -731,4 +731,12 @@ try {
```js ```js
let order = I18n.I18NUtil.getDateOrder("zh-CN"); // order = "y-L-d",表示中文中年月日的顺序为年-月-日。 let order = I18n.I18NUtil.getDateOrder("zh-CN"); // order = "y-L-d",表示中文中年月日的顺序为年-月-日。
``` ```
\ No newline at end of file
## 相关实例
针对I18n开发,有以下相关实例可供参考:
- [时区和语言设置(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Internationalnation/International)
- [国际化(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/International/International)
\ No newline at end of file
...@@ -272,7 +272,7 @@ export default struct Home { ...@@ -272,7 +272,7 @@ export default struct Home {
针对应用市场应用开发,有以下相关实例可以参考: 针对应用市场应用开发,有以下相关实例可以参考:
应用市场开发:[一多应用市场首页应用示例](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/AppMarket) - 应用市场开发:[典型页面场景:应用市场首页(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/AppMarket)
......
...@@ -247,5 +247,5 @@ struct Index { ...@@ -247,5 +247,5 @@ struct Index {
针对音乐专辑应用,有以下相关实例可供参考: 针对音乐专辑应用,有以下相关实例可供参考:
音乐专辑应用:[音乐专辑页应用示例](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/MusicAlbum) - [典型页面场景:音乐专辑页(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/MusicAlbum)
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
| [应用市场首页](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/AppMarket) | 声明式开发范式 | 本章配套的示例代码,以应用市场首页为例,演示如何使用一多能力适配多设备(或多窗口尺寸)。 | | [应用市场首页](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/AppMarket) | 声明式开发范式 | 本章配套的示例代码,以应用市场首页为例,演示如何使用一多能力适配多设备(或多窗口尺寸)。 |
| [音乐专辑页](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/MusicAlbum) | 声明式开发范式 | 本章配套的示例代码,以音乐专辑页为例,演示如何使用一多能力适配多设备(或多窗口尺寸)。 | | [音乐专辑页](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/MusicAlbum) | 声明式开发范式 | 本章配套的示例代码,以音乐专辑页为例,演示如何使用一多能力适配多设备(或多窗口尺寸)。 |
| [设置应用页面](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/Settings) | 声明式开发范式 | 本章配套的示例代码,以设置应用页面为例,演示如何使用一多能力适配多设备(或多窗口尺寸)。 | | [设置应用页面](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/Settings) | 声明式开发范式 | 本章配套的示例代码,以设置应用页面为例,演示如何使用一多能力适配多设备(或多窗口尺寸)。 |
| [分栏控件](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/MultiColumns) | 声明式开发范式 | 本示例分别展示了多场景下,一多分栏控件的响应式变化效果。 |
| [音乐专辑页](https://gitee.com/openharmony/codelabs/tree/master/ExcellentCase/MultiDeviceMusic) | 声明式开发范式 | 基于自适应和响应式布局,实现一次开发、多端部署音乐专辑页面。 | | [音乐专辑页](https://gitee.com/openharmony/codelabs/tree/master/ExcellentCase/MultiDeviceMusic) | 声明式开发范式 | 基于自适应和响应式布局,实现一次开发、多端部署音乐专辑页面。 |
| [视频应用](https://gitee.com/openharmony/codelabs/tree/master/ExcellentCase/Multi_device_V2) | 声明式开发范式 | 基于自适应布局和响应式布局能力,实现了常见的视频播放应用的主界面。 | | [视频应用](https://gitee.com/openharmony/codelabs/tree/master/ExcellentCase/Multi_device_V2) | 声明式开发范式 | 基于自适应布局和响应式布局能力,实现了常见的视频播放应用的主界面。 |
...@@ -168,4 +168,4 @@ Navigation组件支持自动切换单栏和双栏的显示效果,同时可以 ...@@ -168,4 +168,4 @@ Navigation组件支持自动切换单栏和双栏的显示效果,同时可以
针对“设置”应用页面,有以下相关实例可以参考: 针对“设置”应用页面,有以下相关实例可以参考:
设置:[设置应用示例](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/Settings) - [典型页面场景:设置应用页面(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/Settings)
...@@ -257,3 +257,9 @@ export default class VoiceCallDemoForAudioCapturer { ...@@ -257,3 +257,9 @@ export default class VoiceCallDemoForAudioCapturer {
} }
} }
``` ```
## 相关实例
针对音频通话开发,有以下相关实例可供参考:
- [音频通话示例(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/VoiceCallDemo)
\ No newline at end of file
...@@ -63,3 +63,11 @@ audio模块下的接口支持PCM编码,包括AudioRenderer、AudioCapturer、T ...@@ -63,3 +63,11 @@ audio模块下的接口支持PCM编码,包括AudioRenderer、AudioCapturer、T
小尾数指的是小端模式,即数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。这种存储模式将地址的高低和数据的位权有效结合起来,高地址部分权值高,低地址部分权值低。 小尾数指的是小端模式,即数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。这种存储模式将地址的高低和数据的位权有效结合起来,高地址部分权值高,低地址部分权值低。
media模块下的接口支持的音视频格式将在[AVPlayer和AVRecorder](avplayer-avrecorder-overview.md)的介绍中承载。 media模块下的接口支持的音视频格式将在[AVPlayer和AVRecorder](avplayer-avrecorder-overview.md)的介绍中承载。
## 相关实例
针对音视频开发,有以下相关实例可供参考:
- [音视频录制(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/AVRecorder)
- [音频管理(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/Audio)
\ No newline at end of file
...@@ -25,3 +25,9 @@ ...@@ -25,3 +25,9 @@
相机应用通过控制相机,实现图像显示(预览)、照片保存(拍照)、视频录制(录像)等基础操作。在实现基本操作过程中,相机服务会控制相机设备采集和输出数据,采集的图像数据在相机底层的设备硬件接口(HDI,Hardware Device Interfaces),直接通过BufferQueue传递到具体的功能模块进行处理。BufferQueue在应用开发中无需关注,用于将底层处理的数据及时送到上层进行图像显示。 相机应用通过控制相机,实现图像显示(预览)、照片保存(拍照)、视频录制(录像)等基础操作。在实现基本操作过程中,相机服务会控制相机设备采集和输出数据,采集的图像数据在相机底层的设备硬件接口(HDI,Hardware Device Interfaces),直接通过BufferQueue传递到具体的功能模块进行处理。BufferQueue在应用开发中无需关注,用于将底层处理的数据及时送到上层进行图像显示。
以视频录制为例进行说明,相机应用在录制视频过程中,媒体录制服务先创建一个视频Surface用于传递数据,并提供给相机服务,相机服务可控制相机设备采集视频数据,生成视频流。采集的数据通过底层相机HDI处理后,通过Surface将视频流传递给媒体录制服务,媒体录制服务对视频数据进行处理后,保存为视频文件,完成视频录制。 以视频录制为例进行说明,相机应用在录制视频过程中,媒体录制服务先创建一个视频Surface用于传递数据,并提供给相机服务,相机服务可控制相机设备采集视频数据,生成视频流。采集的数据通过底层相机HDI处理后,通过Surface将视频流传递给媒体录制服务,媒体录制服务对视频数据进行处理后,保存为视频文件,完成视频录制。
## 相关实例
针对相机开发,有以下相关实例可供参考:
- [相机和媒体库(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Media/Camera)
...@@ -36,3 +36,13 @@ ...@@ -36,3 +36,13 @@
5. [图片编码](image-encoding.md):使用图片打包器类ImagePacker,将PixelMap或ImageSource进行压缩编码,生成一张新的图片。 5. [图片编码](image-encoding.md):使用图片打包器类ImagePacker,将PixelMap或ImageSource进行压缩编码,生成一张新的图片。
除上述基本图片开发能力外,OpenHarmony还提供常用[图片工具](image-tool.md),供开发者选择使用。 除上述基本图片开发能力外,OpenHarmony还提供常用[图片工具](image-tool.md),供开发者选择使用。
## 相关实例
针对图片开发,有以下相关实例可供参考:
- [图片显示及处理(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/Image)
- [图片显示(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/ImageShow)
- [图片裁剪与分割(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/GamePuzzle)
\ No newline at end of file
...@@ -17,3 +17,13 @@ ...@@ -17,3 +17,13 @@
- 相机(camera):提供精确控制相机镜头,采集视觉信息的接口与服务。 - 相机(camera):提供精确控制相机镜头,采集视觉信息的接口与服务。
- 图片(image):提供图片编解码、图片处理接口与服务。 - 图片(image):提供图片编解码、图片处理接口与服务。
## 相关实例
针对媒体开发,有以下相关实例可供参考:
- [媒体管理合集(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/FileManagement/MediaCollections)
- [相机和媒体库(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Media/MultiMedia)
- [二维码扫描(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/QRCodeScan)
\ No newline at end of file
...@@ -331,3 +331,9 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 ...@@ -331,3 +331,9 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频
}); });
} }
``` ```
## 相关实例
针对媒体会话控制方开发,有以下相关实例可供参考:
- [媒体会话——控制方(仅对系统应用开放)(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/AVSession/MediaController)
\ No newline at end of file
...@@ -357,3 +357,9 @@ ...@@ -357,3 +357,9 @@
}); });
} }
``` ```
## 相关实例
针对媒体会话提供方开发,有以下相关实例可供参考:
- [媒体会话——提供方(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/AVSession/MediaProvider)
\ No newline at end of file
...@@ -264,4 +264,6 @@ export class AVPlayerDemo { ...@@ -264,4 +264,6 @@ export class AVPlayerDemo {
针对视频播放,有以下相关实例可供参考: 针对视频播放,有以下相关实例可供参考:
- [`VideoPlayer`:视频播放器(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/VideoPlayer) - [视频播放(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/VideoPlay)
\ No newline at end of file
- [视频播放器(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/VideoPlayer)
\ No newline at end of file
...@@ -380,5 +380,7 @@ ...@@ -380,5 +380,7 @@
``` ```
## 相关实例 ## 相关实例
- [`NdkRawfile`:获取Rawfile资源](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Native/NdkRawfile)
针对资源管理Rawfile开发,有以下相关实例可供参考:
- [获取Rawfile资源(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Native/NdkRawfile)
...@@ -899,4 +899,4 @@ XComponent({ id: 'xcomponentId1', type: 'surface', libraryname: 'nativerender' } ...@@ -899,4 +899,4 @@ XComponent({ id: 'xcomponentId1', type: 'surface', libraryname: 'nativerender' }
针对Native XComponent的使用,有以下相关实例可供参考: 针对Native XComponent的使用,有以下相关实例可供参考:
- [使用Native XComponent接口绘制图形](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Native/NdkXComponent) - [Native XComponent(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Native/NdkXComponent)
...@@ -31,4 +31,12 @@ OpenHarmony通过ANS(Advanced Notification Service,通知系统服务)对 ...@@ -31,4 +31,12 @@ OpenHarmony通过ANS(Advanced Notification Service,通知系统服务)对
基于通知的开发,有以下相关实例可供参考: 基于通知的开发,有以下相关实例可供参考:
- [`CustomNotification`:自定义通知(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Notification/CustomNotification) - [公共事件的订阅和发布(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Notification/CustomCommonEvent)
\ No newline at end of file
- [自定义通知推送(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Notification/CustomNotificationPush)
- [自定义通知角标(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Notification/CustomNotificationBadge)
- [自定义通知(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Notification/CustomNotification)
- [自定义Emitter(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Notification/CustomEmitter)
\ No newline at end of file
...@@ -192,9 +192,85 @@ struct CompA { ...@@ -192,9 +192,85 @@ struct CompA {
} }
``` ```
### 以持久化方式订阅某个事件并接收事件回调 ### 不建议借助@StorageLink的双向同步机制实现事件通知
推荐使用持久化方式订阅某个事件并接收事件回调,可以减少开销,增强代码的可读性。 不建议开发者使用@StorageLink和AppStorage的双向同步的机制来实现事件通知,AppStorage是和UI相关的数据存储,改变会带来UI的刷新,相对于一般的事件通知,UI刷新的成本较大。
TapImage中的点击事件,会触发AppStorage中tapIndex对应属性的改变。因为@StorageLink是双向同步,修改会同步会AppStorage中,所以,所有绑定AppStorage的tapIndex可见自定义组件都会被通知UI刷新。UI刷新带来的成本是巨大的,因此不建议开发者使用此方式来实现基本的事件通知功能。
```ts
// xxx.ets
class ViewData {
title: string;
uri: Resource;
color: Color = Color.Black;
constructor(title: string, uri: Resource) {
this.title = title;
this.uri = uri
}
}
@Entry
@Component
struct Gallery2 {
dataList: Array<ViewData> = [new ViewData('flower', $r('app.media.icon')), new ViewData('OMG', $r('app.media.icon')), new ViewData('OMG', $r('app.media.icon'))]
scroller: Scroller = new Scroller()
build() {
Column() {
Grid(this.scroller) {
ForEach(this.dataList, (item: ViewData, index?: number) => {
GridItem() {
TapImage({
uri: item.uri,
index: index
})
}.aspectRatio(1)
}, (item: ViewData, index?: number) => {
return JSON.stringify(item) + index;
})
}.columnsTemplate('1fr 1fr')
}
}
}
@Component
export struct TapImage {
@StorageLink('tapIndex') @Watch('onTapIndexChange') tapIndex: number = -1;
@State tapColor: Color = Color.Black;
private index: number;
private uri: Resource;
// 判断是否被选中
onTapIndexChange() {
if (this.tapIndex >= 0 && this.index === this.tapIndex) {
console.info(`tapindex: ${this.tapIndex}, index: ${this.index}, red`)
this.tapColor = Color.Red;
} else {
console.info(`tapindex: ${this.tapIndex}, index: ${this.index}, black`)
this.tapColor = Color.Black;
}
}
build() {
Column() {
Image(this.uri)
.objectFit(ImageFit.Cover)
.onClick(() => {
this.tapIndex = this.index;
})
.border({ width: 5, style: BorderStyle.Dotted, color: this.tapColor })
}
}
}
```
开发者可以使用emit订阅某个事件并接收事件回调,可以减少开销,增强代码的可读性。
```ts ```ts
...@@ -293,10 +369,9 @@ export struct TapImage { ...@@ -293,10 +369,9 @@ export struct TapImage {
} }
``` ```
以下示例为消息机制方式订阅事件,会导致回调监听的节点数较多,非常耗时,不推荐以此来实现应用代码。 以上通知事件逻辑简单,也可以简化成三元表达式。
```ts ```
// xxx.ets // xxx.ets
class ViewData { class ViewData {
title: string; title: string;
...@@ -337,22 +412,11 @@ struct Gallery2 { ...@@ -337,22 +412,11 @@ struct Gallery2 {
@Component @Component
export struct TapImage { export struct TapImage {
@StorageLink('tapIndex') @Watch('onTapIndexChange') tapIndex: number = -1; @StorageLink('tapIndex') tapIndex: number = -1;
@State tapColor: Color = Color.Black; @State tapColor: Color = Color.Black;
private index: number; private index: number;
private uri: Resource; private uri: Resource;
// 判断是否被选中
onTapIndexChange() {
if (this.tapIndex >= 0 && this.index === this.tapIndex) {
console.info(`tapindex: ${this.tapIndex}, index: ${this.index}, red`)
this.tapColor = Color.Red;
} else {
console.info(`tapindex: ${this.tapIndex}, index: ${this.index}, black`)
this.tapColor = Color.Black;
}
}
build() { build() {
Column() { Column() {
Image(this.uri) Image(this.uri)
...@@ -360,14 +424,18 @@ export struct TapImage { ...@@ -360,14 +424,18 @@ export struct TapImage {
.onClick(() => { .onClick(() => {
this.tapIndex = this.index; this.tapIndex = this.index;
}) })
.border({ width: 5, style: BorderStyle.Dotted, color: this.tapColor }) .border({
width: 5,
style: BorderStyle.Dotted,
color: (this.tapIndex >= 0 && this.index === this.tapIndex) ? Color.Red : Color.Black
})
} }
} }
} }
``` ```
## 限制条件 ## 限制条件
AppStorage与[PersistentStorage](arkts-persiststorage.md)以及[Environment](arkts-environment.md)配合使用时,需要注意以下几点: AppStorage与[PersistentStorage](arkts-persiststorage.md)以及[Environment](arkts-environment.md)配合使用时,需要注意以下几点:
......
...@@ -70,8 +70,6 @@ struct ParentComponent { ...@@ -70,8 +70,6 @@ struct ParentComponent {
- [自定义组件通用样式](#自定义组件通用样式) - [自定义组件通用样式](#自定义组件通用样式)
- [自定义属性方法](#自定义属性方法)
## 自定义组件的基本结构 ## 自定义组件的基本结构
...@@ -347,68 +345,4 @@ struct MyComponent { ...@@ -347,68 +345,4 @@ struct MyComponent {
> >
> ArkUI给自定义组件设置样式时,相当于给MyComponent2套了一个不可见的容器组件,而这些样式是设置在容器组件上的,而非直接设置给MyComponent2的Button组件。通过渲染结果我们可以很清楚的看到,背景颜色红色并没有直接生效在Button上,而是生效在Button所处的开发者不可见的容器组件上。 > ArkUI给自定义组件设置样式时,相当于给MyComponent2套了一个不可见的容器组件,而这些样式是设置在容器组件上的,而非直接设置给MyComponent2的Button组件。通过渲染结果我们可以很清楚的看到,背景颜色红色并没有直接生效在Button上,而是生效在Button所处的开发者不可见的容器组件上。
## 自定义属性方法
自定义组件不支持提供自定义属性方法,可以借助类似Controller控制器能力,提供自定义接口。
```ts
// 自定义controller
export class MyComponentController {
item: MyComponent = null;
setItem(item: MyComponent) {
this.item = item;
}
changeText(value: string) {
this.item.value = value;
}
}
// 自定义组件
@Component
export default struct MyComponent {
public controller: MyComponentController = null;
@State value: string = 'Hello World';
build() {
Column() {
Text(this.value)
.fontSize(50)
}
}
aboutToAppear() {
if (this.controller)
this.controller.setItem(this); // 绑定controller
}
}
// 使用处逻辑
@Entry
@Component
struct StyleExample {
controller = new MyComponentController();
build() {
Column() {
MyComponent({ controller: this.controller })
}
.onClick(() => {
this.controller.changeText('Text');
})
}
}
```
在上面的示例中:
1. 通过子组件MyComponent的aboutToAppear方法,把当前的this指针传递给MyComponentController的item成员变量。
2. 在StyleExample父组件中持有controller实例,调用controller的changeText方法,即相当于通过controller持有的MyComponent子组件的this指针,改变MyComponent的状态变量value的值。
通过controller的封装,MyComponent对外暴露了changeText的接口,所有持有controller的实例都可以通过调用changeText接口,改变MyComponent的状态变量value的值。
<!--no_check--> <!--no_check-->
...@@ -132,4 +132,6 @@ $$运算符:给内置组件提供TS变量的引用,使得TS变量和内置 ...@@ -132,4 +132,6 @@ $$运算符:给内置组件提供TS变量的引用,使得TS变量和内置
针对页面状态管理,有以下相关实例可供参考: 针对页面状态管理,有以下相关实例可供参考:
- [状态管理(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/StateManagement)
- [目标管理(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/TargetManagement) - [目标管理(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/TargetManagement)
\ No newline at end of file
...@@ -5,4 +5,10 @@ ...@@ -5,4 +5,10 @@
- 方便开发者将多HAP合理地组合并部署到不同的设备上。例如应用程序包含一个Entry包和两个Featrue包(Feature1和Feature2)。其中Entry包可以部署到设备A和设备B,Feature1只能部署到设备A,Feature2包只部署到设备B上,那么开发者就可以方便的组合Entry和Feature1部署到设备A上,组合Entry和Feature2部署到设备B上。 - 方便开发者将多HAP合理地组合并部署到不同的设备上。例如应用程序包含一个Entry包和两个Featrue包(Feature1和Feature2)。其中Entry包可以部署到设备A和设备B,Feature1只能部署到设备A,Feature2包只部署到设备B上,那么开发者就可以方便的组合Entry和Feature1部署到设备A上,组合Entry和Feature2部署到设备B上。
- 方便开发者按需加载所需模块,减少包大小。开发者可以将一个应用的某些HAP配置成按需加载。应用在启动阶段初始用不到的特性,可以配置暂不加载,当用户用到这些特性的时候,可由应用自动下载这些特性HAP,一定程度上减少应用包的大小。 - 方便开发者按需加载所需模块,减少包大小。开发者可以将一个应用的某些HAP配置成按需加载。应用在启动阶段初始用不到的特性,可以配置暂不加载,当用户用到这些特性的时候,可由应用自动下载这些特性HAP,一定程度上减少应用包的大小。
\ No newline at end of file
## 相关实例
针对多HAP开发,有以下相关实例可供参考:
- [多HAP(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Project/ApplicationHap/MultiHap)
\ No newline at end of file
...@@ -317,4 +317,4 @@ Image($r('sys.media.ohos_app_icon')) ...@@ -317,4 +317,4 @@ Image($r('sys.media.ohos_app_icon'))
针对访问应用资源,有以下相关实例可供参考: 针对访问应用资源,有以下相关实例可供参考:
- [`ResourceManager`:资源管理器(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/blob/master/code/BasicFeature/Resource/ResourceManager/README_zh.md) - [资源管理(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Resource/ResourceManager)
...@@ -301,6 +301,7 @@ ...@@ -301,6 +301,7 @@
- AI - AI
- [@ohos.ai.mindSporeLite (推理能力)](js-apis-mindSporeLite.md) - [@ohos.ai.mindSporeLite (推理能力)](js-apis-mindSporeLite.md)
- [@ohos.ai.intelligentVoice (智能语音)](js-apis-intelligentVoice.md)
- 电话服务 - 电话服务
- [@ohos.contact (联系人)](js-apis-contact.md) - [@ohos.contact (联系人)](js-apis-contact.md)
......
# @ohos.WallpaperExtensionAbility (WallpaperExtensionAbility) # @ohos.WallpaperExtensionAbility (WallpaperExtensionAbility)
通过本模块接口,开发者可自行开发壁纸应用,并管理壁纸应用生命周期 WallpaperExtensionAbility为壁纸拓展模块,提供应用生命周期回调和监听壁纸变化的能力
> **说明:** > **说明:**
> >
> 本模块首批接口从API version 10开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 > 本模块首批接口从API version 10开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。
> >
> 本模块接口仅可在FA模型下使用。 > 本模块接口仅可在Stage模型下使用。
> >
> 本模块接口均为系统接口。 > 本模块接口均为系统接口。
......
...@@ -4528,7 +4528,7 @@ aVCastController.on('playPrevious', () => { ...@@ -4528,7 +4528,7 @@ aVCastController.on('playPrevious', () => {
off(type: 'playPrevious'): void off(type: 'playPrevious'): void
取消设置播放一首资源的监听事件。 取消设置播放一首资源的监听事件。
**系统能力:** SystemCapability.Multimedia.AVSession.AVCast **系统能力:** SystemCapability.Multimedia.AVSession.AVCast
......
...@@ -1545,4 +1545,167 @@ bundleManager.uninstall(wantTemp, 'bundleName', 100, true).then(() => { ...@@ -1545,4 +1545,167 @@ bundleManager.uninstall(wantTemp, 'bundleName', 100, true).then(() => {
}).catch((err) => { }).catch((err) => {
console.error(`Failed to uninstall bundles. Code is ${err.code}, message is ${err.message}`); console.error(`Failed to uninstall bundles. Code is ${err.code}, message is ${err.message}`);
}); });
``` ```
\ No newline at end of file
## bundleManager.install
install(admin: Want, hapFilePaths: Array\<string>, callback: AsyncCallback\<void>): void
指定设备管理应用安装指定路径下的应用包。使用callback异步回调。
**需要权限:** ohos.permission.ENTERPRISE_INSTALL_BUNDLE
**系统能力:** SystemCapability.Customization.EnterpriseDeviceManager
**系统API**: 此接口为系统接口。
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | ---------------------------------------- | ---- | ------------------------------- |
| admin | [Want](js-apis-app-ability-want.md) | 是 | 设备管理应用。 |
| hapFilePaths | Array\<string> | 是 | 待安装应用包路径数组。 |
| callback | AsyncCallback&lt;void&gt; | 是 | 回调函数,当接口调用成功,err为null,否则为错误对象。 |
**错误码**
以下错误码的详细介绍请参见[企业设备管理错误码](../errorcodes/errorcode-enterpriseDeviceManager.md)
| 错误码ID | 错误信息 |
| ------- | ---------------------------------------------------------------------------- |
| 9200001 | the application is not an administrator of the device. |
| 9200002 | the administrator application does not have permission to manage the device. |
| 9201002 | the application install failed. |
**示例:**
```js
let wantTemp = {
bundleName: 'com.example.myapplication',
abilityName: 'EntryAbility',
};
let hapFilePaths = ['/data/storage/el2/base/haps/entry/testinstall/ExtensionTest.hap']
bundleManager.install(wantTemp, hapFilePaths, (err) => {
if (err) {
console.error(`Failed to install bundles. Code is ${err.code}, message is ${err.message}`);
}
console.info('Succeeded in installing bundles');
});
```
## bundleManager.install
install(admin: Want, hapFilePaths: Array\<string>, installParam: InstallParam, callback: AsyncCallback\<void>): void
指定设备管理应用安装指定路径下的指定安装参数的应用包,。使用callback异步回调。
**需要权限:** ohos.permission.ENTERPRISE_INSTALL_BUNDLE
**系统能力:** SystemCapability.Customization.EnterpriseDeviceManager
**系统API**: 此接口为系统接口。
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | ---------------------------------------- | ---- | ------------------------------- |
| admin | [Want](js-apis-app-ability-want.md) | 是 | 设备管理应用。 |
| hapFilePaths | Array\<string> | 是 | 待安装应用包路径数组。 |
| installParam | [InstallParam](#installparam) | 是 | 应用包安装参数。 |
| callback | AsyncCallback&lt;void&gt; | 是 | 回调函数,当接口调用成功,err为null,否则为错误对象。 |
**错误码**
以下错误码的详细介绍请参见[企业设备管理错误码](../errorcodes/errorcode-enterpriseDeviceManager.md)
| 错误码ID | 错误信息 |
| ------- | ---------------------------------------------------------------------------- |
| 9200001 | the application is not an administrator of the device. |
| 9200002 | the administrator application does not have permission to manage the device. |
| 9201002 | the application install failed. |
**示例:**
```js
let wantTemp = {
bundleName: 'com.example.myapplication',
abilityName: 'EntryAbility',
};
let hapFilePaths = ['/data/storage/el2/base/haps/entry/testinstall/ExtensionTest.hap']
let installParam = {
userId: 100,
installFlag: 1,
};
bundleManager.install(wantTemp, hapFilePaths, installParam, (err) => {
if (err) {
console.error(`Failed to install bundles. Code is ${err.code}, message is ${err.message}`);
}
console.info('Succeeded in installing bundles');
});
```
## bundleManager.install
install(admin: Want, hapFilePaths: Array\<string>, installParam?: InstallParam): Promise\<void>
指定设备管理应用安装指定路径下的应用包。使用promise异步回调。
**需要权限:** ohos.permission.ENTERPRISE_INSTALL_BUNDLE
**系统能力:** SystemCapability.Customization.EnterpriseDeviceManager
**系统API**: 此接口为系统接口。
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| ----- | ----------------------------------- | ---- | ------- |
| admin | [Want](js-apis-app-ability-want.md) | 是 | 设备管理应用。 |
| hapFilePaths | Array\<string> | 是 | 待安装应用包路径数组。 |
| installParam | [InstallParam](#installparam) | 否 | 应用包安装参数。 |
**返回值:**
| 类型 | 说明 |
| --------------------- | ------------------------- |
| Promise&lt;void&gt; | 无返回结果的Promise对象。当包安装失败时,抛出错误对象。 |
**错误码**
以下错误码的详细介绍请参见[企业设备管理错误码](../errorcodes/errorcode-enterpriseDeviceManager.md)
| 错误码ID | 错误信息 |
| ------- | ---------------------------------------------------------------------------- |
| 9200001 | the application is not an administrator of the device. |
| 9200002 | the administrator application does not have permission to manage the device. |
**示例:**
```js
let wantTemp = {
bundleName: 'com.example.myapplication',
abilityName: 'EntryAbility',
};
let hapFilePaths = ['/data/storage/el2/base/haps/entry/testinstall/ExtensionTest.hap']
bundleManager.install(wantTemp, hapFilePaths).then(() => {
console.info('Succeeded in installing bundles');
}).catch((err) => {
console.error(`Failed to install bundles. Code is ${err.code}, message is ${err.message}`);
});
```
## InstallParam
应用包安装需指定的参数信息。
**系统能力:** SystemCapability.Customization.EnterpriseDeviceManager
**系统接口:** 此接口为系统接口。
| 名称 | 类型 | 必填 | 说明 |
| ------------------------------ | ------------------------------ | ------------------ | ------------------ |
| userId | number | 否 | 指示用户id,默认值:调用方所在用户,取值范围:大于等于0。
| installFlag | number | 否 | 安装标志。枚举值:0:应用初次安装,1:应用覆盖安装,2:应用免安装,默认值为应用初次安装。 |
\ No newline at end of file
...@@ -248,7 +248,7 @@ listFile(filter?: Filter) : FileIterator ...@@ -248,7 +248,7 @@ listFile(filter?: Filter) : FileIterator
try { try {
let fileIterator = fileInfoDir.listFile(); let fileIterator = fileInfoDir.listFile();
// 含过滤器实现的listFile // 含过滤器实现的listFile
// let fileIterator = rootInfo.listFile(filter); // let fileIterator = fileInfoDir.listFile(filter);
if (!fileIterator) { if (!fileIterator) {
console.error("listFile interface returns an undefined object"); console.error("listFile interface returns an undefined object");
return; return;
...@@ -304,7 +304,7 @@ scanFile(filter?: Filter) : FileIterator; ...@@ -304,7 +304,7 @@ scanFile(filter?: Filter) : FileIterator;
try { try {
let fileIterator = fileInfoDir.scanFile(); let fileIterator = fileInfoDir.scanFile();
// 含过滤器实现的scanFile // 含过滤器实现的scanFile
// let fileIterator = rootInfo.scanFile(filter); // let fileIterator = fileInfoDir.scanFile(filter);
if (!fileIterator) { if (!fileIterator) {
console.error("scanFile interface returns an undefined object"); console.error("scanFile interface returns an undefined object");
return; return;
......
...@@ -285,7 +285,7 @@ getWindowRootElement(windowId?: number): Promise\<AccessibilityElement>; ...@@ -285,7 +285,7 @@ getWindowRootElement(windowId?: number): Promise\<AccessibilityElement>;
| 类型 | 说明 | | 类型 | 说明 |
| ----------------------------------- | ---------------------- | | ----------------------------------- | ---------------------- |
| Promise&lt;AccessibilityElement&gt; | Promise对象,返回指定屏幕的所有窗口。 | | Promise&lt;AccessibilityElement&gt; | Promise对象,返回指定窗口的根节点元素。 |
**错误码:** **错误码:**
...@@ -355,7 +355,7 @@ try { ...@@ -355,7 +355,7 @@ try {
getWindowRootElement(windowId: number, callback: AsyncCallback\<AccessibilityElement>): void; getWindowRootElement(windowId: number, callback: AsyncCallback\<AccessibilityElement>): void;
获取指定屏幕中的所有窗口, 使用callback异步回调。 获取指定窗口的根节点元素, 使用callback异步回调。
**系统能力:** SystemCapability.BarrierFree.Accessibility.Core **系统能力:** SystemCapability.BarrierFree.Accessibility.Core
......
...@@ -37,6 +37,7 @@ startAbility(want: Want, callback: AsyncCallback&lt;void&gt;): void; ...@@ -37,6 +37,7 @@ startAbility(want: Want, callback: AsyncCallback&lt;void&gt;): void;
- 调用方应用位于后台时,使用该接口启动Ability需申请`ohos.permission.START_ABILITIES_FROM_BACKGROUND`权限 - 调用方应用位于后台时,使用该接口启动Ability需申请`ohos.permission.START_ABILITIES_FROM_BACKGROUND`权限
- 跨应用场景下,目标Ability的exported属性若配置为false,调用方应用需申请`ohos.permission.START_INVISIBLE_ABILITY`权限 - 跨应用场景下,目标Ability的exported属性若配置为false,调用方应用需申请`ohos.permission.START_INVISIBLE_ABILITY`权限
- 组件启动规则详见:[组件启动规则(Stage模型)](../../application-models/component-startup-rules.md) - 组件启动规则详见:[组件启动规则(Stage模型)](../../application-models/component-startup-rules.md)
- 跨任务链启动时,如果需要跨任务链进行返回,需要参考[Want](js-apis-app-ability-want.md)中的parameter参数用法。
**系统能力**:SystemCapability.Ability.AbilityRuntime.Core **系统能力**:SystemCapability.Ability.AbilityRuntime.Core
...@@ -44,7 +45,7 @@ startAbility(want: Want, callback: AsyncCallback&lt;void&gt;): void; ...@@ -44,7 +45,7 @@ startAbility(want: Want, callback: AsyncCallback&lt;void&gt;): void;
| 参数名 | 类型 | 必填 | 说明 | | 参数名 | 类型 | 必填 | 说明 |
| -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- |
| want | [Want](js-apis-application-want.md) | 是 | 启动Ability的want信息。 | | want | [Want](js-apis-app-ability-want.md) | 是 | 启动Ability的want信息。 |
| callback | AsyncCallback&lt;void&gt; | 是 | callback形式返回启动结果。 | | callback | AsyncCallback&lt;void&gt; | 是 | callback形式返回启动结果。 |
**错误码:** **错误码:**
......
...@@ -19,6 +19,9 @@ import installer from '@ohos.bundle.installer'; ...@@ -19,6 +19,9 @@ import installer from '@ohos.bundle.installer';
| ohos.permission.INSTALL_ENTERPRISE_BUNDLE | system_core | 允许应用安装企业InHouse应用。 | | ohos.permission.INSTALL_ENTERPRISE_BUNDLE | system_core | 允许应用安装企业InHouse应用。 |
| ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE | system_core | 允许在企业设备上安装企业MDM应用包。 | | ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE | system_core | 允许在企业设备上安装企业MDM应用包。 |
| ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE | system_core | 允许在企业设备上安装企业NORMAL应用包。 | | ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE | system_core | 允许在企业设备上安装企业NORMAL应用包。 |
| ohos.permission.UNINSTALL_BUNDLE | system_core | 允许应用卸载应用。 |
| ohos.permission.RECOVER_BUNDLE | system_core | 允许应用恢复预置应用。 |
| ohos.permission.INSTALL_SELF_BUNDLE | system_core | 允许企业MDM应用在企业设备上自升级。|
权限等级参考[权限等级说明](../../security/accesstoken-overview.md#权限等级说明) 权限等级参考[权限等级说明](../../security/accesstoken-overview.md#权限等级说明)
...@@ -95,11 +98,15 @@ install(hapFilePaths: Array&lt;string&gt;, installParam: InstallParam, callback: ...@@ -95,11 +98,15 @@ install(hapFilePaths: Array&lt;string&gt;, installParam: InstallParam, callback:
**系统接口:** 此接口为系统接口。 **系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE<sup>10+</sup> **需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE<sup>10+</sup> 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE<sup>10+</sup> 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE<sup>10+</sup>
> **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限调用此接口。 > **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限调用此接口。
> >
> 安装企业应用需要ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限 > 安装企业应用需要ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限
> >
> 安装企业NORMAL应用需要ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE或ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限
>
> 安装企业MDM应用需要ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限
>
> 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限 > 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core **系统能力:** SystemCapability.BundleManager.BundleFramework.Core
...@@ -135,6 +142,7 @@ install(hapFilePaths: Array&lt;string&gt;, installParam: InstallParam, callback: ...@@ -135,6 +142,7 @@ install(hapFilePaths: Array&lt;string&gt;, installParam: InstallParam, callback:
| 17700044 | Failed to install the HAP because the isolationMode configured is not supported. | | 17700044 | Failed to install the HAP because the isolationMode configured is not supported. |
| 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. | | 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. |
| 17700048 | Failed to install the HAP because the code signature verification is failed. | | 17700048 | Failed to install the HAP because the code signature verification is failed. |
| 17700050 | Failed to install the HAP because enterprise normal/MDM bundle cannot be installed on non-enterprise device. |
**示例:** **示例:**
...@@ -170,11 +178,15 @@ install(hapFilePaths: Array&lt;string&gt;, callback: AsyncCallback&lt;void&gt;): ...@@ -170,11 +178,15 @@ install(hapFilePaths: Array&lt;string&gt;, callback: AsyncCallback&lt;void&gt;):
**系统接口:** 此接口为系统接口。 **系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE<sup>10+</sup> **需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE<sup>10+</sup> 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE<sup>10+</sup> 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE<sup>10+</sup>
> **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限调用此接口。 > **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限调用此接口。
> >
> 安装企业应用需要ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限 > 安装企业应用需要ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限
> >
> 安装企业NORMAL应用需要ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE或ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限
>
> 安装企业MDM应用需要ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限
>
> 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限 > 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core **系统能力:** SystemCapability.BundleManager.BundleFramework.Core
...@@ -208,6 +220,7 @@ install(hapFilePaths: Array&lt;string&gt;, callback: AsyncCallback&lt;void&gt;): ...@@ -208,6 +220,7 @@ install(hapFilePaths: Array&lt;string&gt;, callback: AsyncCallback&lt;void&gt;):
| 17700044 | Failed to install the HAP because the isolationMode configured is not supported. | | 17700044 | Failed to install the HAP because the isolationMode configured is not supported. |
| 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. | | 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. |
| 17700048 | Failed to install the HAP because the code signature verification is failed. | | 17700048 | Failed to install the HAP because the code signature verification is failed. |
| 17700050 | Failed to install the HAP because enterprise normal/MDM bundle cannot be installed on non-enterprise device. |
**示例:** **示例:**
...@@ -240,11 +253,15 @@ install(hapFilePaths: Array\<string\>, installParam?: InstallParam) : Promise\<v ...@@ -240,11 +253,15 @@ install(hapFilePaths: Array\<string\>, installParam?: InstallParam) : Promise\<v
**系统接口:** 此接口为系统接口。 **系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE<sup>10+</sup> **需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE<sup>10+</sup> 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE<sup>10+</sup> 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE<sup>10+</sup>
> **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限调用此接口。 > **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限调用此接口。
> >
> 安装企业应用需要ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限 > 安装企业应用需要ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限
> >
> 安装企业NORMAL应用需要ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE或ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限
>
> 安装企业MDM应用需要ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限
>
> 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限 > 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core **系统能力:** SystemCapability.BundleManager.BundleFramework.Core
...@@ -285,6 +302,7 @@ install(hapFilePaths: Array\<string\>, installParam?: InstallParam) : Promise\<v ...@@ -285,6 +302,7 @@ install(hapFilePaths: Array\<string\>, installParam?: InstallParam) : Promise\<v
| 17700044 | Failed to install the HAP because the isolationMode configured is not supported. | | 17700044 | Failed to install the HAP because the isolationMode configured is not supported. |
| 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. | | 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. |
| 17700048 | Failed to install the HAP because the code signature verification is failed. | | 17700048 | Failed to install the HAP because the code signature verification is failed. |
| 17700050 | Failed to install the HAP because enterprise normal/MDM bundle cannot be installed on non-enterprise device. |
**示例:** **示例:**
...@@ -321,7 +339,7 @@ uninstall(bundleName: string, installParam: InstallParam, callback: AsyncCallbac ...@@ -321,7 +339,7 @@ uninstall(bundleName: string, installParam: InstallParam, callback: AsyncCallbac
**系统接口:** 此接口为系统接口。 **系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_BUNDLE **需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.UNINSTALL_BUNDLE<sup>10+</sup>
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core **系统能力:** SystemCapability.BundleManager.BundleFramework.Core
...@@ -381,7 +399,7 @@ uninstall(bundleName: string, callback: AsyncCallback&lt;void&gt;): void; ...@@ -381,7 +399,7 @@ uninstall(bundleName: string, callback: AsyncCallback&lt;void&gt;): void;
**系统接口:** 此接口为系统接口。 **系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_BUNDLE **需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.UNINSTALL_BUNDLE<sup>10+</sup>
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core **系统能力:** SystemCapability.BundleManager.BundleFramework.Core
...@@ -433,7 +451,7 @@ uninstall(bundleName: string, installParam?: InstallParam) : Promise\<void\>; ...@@ -433,7 +451,7 @@ uninstall(bundleName: string, installParam?: InstallParam) : Promise\<void\>;
**系统接口:** 此接口为系统接口。 **系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_BUNDLE **需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.UNINSTALL_BUNDLE<sup>10+</sup>
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core **系统能力:** SystemCapability.BundleManager.BundleFramework.Core
...@@ -496,7 +514,7 @@ recover(bundleName: string, installParam: InstallParam, callback: AsyncCallback& ...@@ -496,7 +514,7 @@ recover(bundleName: string, installParam: InstallParam, callback: AsyncCallback&
**系统接口:** 此接口为系统接口。 **系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_BUNDLE **需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.RECOVER_BUNDLE<sup>10+</sup>
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core **系统能力:** SystemCapability.BundleManager.BundleFramework.Core
...@@ -554,7 +572,7 @@ recover(bundleName: string, callback: AsyncCallback&lt;void&gt;): void; ...@@ -554,7 +572,7 @@ recover(bundleName: string, callback: AsyncCallback&lt;void&gt;): void;
**系统接口:** 此接口为系统接口。 **系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_BUNDLE **需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.RECOVER_BUNDLE<sup>10+</sup>
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core **系统能力:** SystemCapability.BundleManager.BundleFramework.Core
...@@ -604,7 +622,7 @@ recover(bundleName: string, installParam?: InstallParam) : Promise\<void\>; ...@@ -604,7 +622,7 @@ recover(bundleName: string, installParam?: InstallParam) : Promise\<void\>;
**系统接口:** 此接口为系统接口。 **系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_BUNDLE **需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.RECOVER_BUNDLE<sup>10+</sup>
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core **系统能力:** SystemCapability.BundleManager.BundleFramework.Core
...@@ -664,7 +682,7 @@ uninstall(uninstallParam: UninstallParam, callback : AsyncCallback\<void>) : voi ...@@ -664,7 +682,7 @@ uninstall(uninstallParam: UninstallParam, callback : AsyncCallback\<void>) : voi
**系统接口:** 此接口为系统接口。 **系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_BUNDLE **需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.UNINSTALL_BUNDLE<sup>10+</sup>
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core **系统能力:** SystemCapability.BundleManager.BundleFramework.Core
...@@ -718,7 +736,7 @@ uninstall(uninstallParam: UninstallParam) : Promise\<void>; ...@@ -718,7 +736,7 @@ uninstall(uninstallParam: UninstallParam) : Promise\<void>;
**系统接口:** 此接口为系统接口。 **系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_BUNDLE **需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.UNINSTALL_BUNDLE<sup>10+</sup>
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core **系统能力:** SystemCapability.BundleManager.BundleFramework.Core
...@@ -769,6 +787,220 @@ try { ...@@ -769,6 +787,220 @@ try {
} }
``` ```
## BundleInstaller.updateBundleForSelf<sup>10+</sup>
updateBundleForSelf(hapFilePaths: Array<string>, installParam: InstallParam, callback: AsyncCallback<void>): void;
以异步方法更新当前应用,仅限企业设备上的企业MDM应用调用,且传入的hapFilePaths中的hap必须都属于当前应用,使用callback形式返回结果。
**系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_SELF_BUNDLE
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| --------------- | ---------------------------------------------------- | ---- | ------------------------------------------------------------ |
| hapFilePaths | Array&lt;string&gt; | 是 | 存储应用程序包的路径。路径应该是当前应用程序中存放HAP的数据目录。当传入的路径是一个目录时, 该目录下只能放同一个应用的HAP,且这些HAP的签名需要保持一致。 |
| installParam | [InstallParam](#installparam) | 是 | 指定安装所需的其他参数。 |
| callback | AsyncCallback&lt;void&gt; | 是 | 回调函数,安装应用成功,err为undefined,否则为错误对象。 |
**错误码:**
以下错误码的详细介绍请参见[ohos.bundle错误码](../errorcodes/errorcode-bundle.md)
| 错误码ID | 错误信息 |
| -------- | ------------------------------------------------------------ |
| 17700004 | The specified user ID is not found. |
| 17700010 | Failed to install the HAP because the HAP fails to be parsed. |
| 17700011 | Failed to install the HAP because the HAP signature fails to be verified. |
| 17700012 | Failed to install the HAP because the HAP path is invalid or the HAP is too large. |
| 17700015 | Failed to install the HAPs because they have different configuration information. |
| 17700016 | Failed to install the HAP because of insufficient system disk space. |
| 17700017 | Failed to install the HAP since the version of the HAP to install is too early. |
| 17700018 | Failed to install because the dependent module does not exist. |
| 17700031 | Failed to install the HAP because the overlay check of the HAP is failed. |
| 17700039 | Failed to install because disallow install a shared bundle by hapFilePaths. |
| 17700041 | Failed to install because enterprise device management disallow install. |
| 17700042 | Failed to install the HAP because of incorrect URI in the data proxy. |
| 17700043 | Failed to install the HAP because of low APL in the non-system data proxy (required APL: system_basic or system_core). |
| 17700044 | Failed to install the HAP because the isolationMode configured is not supported. |
| 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. |
| 17700048 | Failed to install the HAP because the code signature verification is failed. |
| 17700049 | Failed to install the HAP because the bundleName is different from the bundleName of the caller application. |
| 17700050 | Failed to install the HAP because enterprise normal/MDM bundle cannot be installed on non-enterprise device. |
| 17700051 | Failed to install the HAP because the distribution type of caller application is not enterprise_mdm. |
**示例:**
```ts
import installer from '@ohos.bundle.installer';
let hapFilePaths = ['/data/storage/el2/base/haps/entry/files/'];
let installParam = {
userId: 100,
isKeepData: false,
installFlag: 1,
};
try {
installer.getBundleInstaller().then(data => {
data.updateBundleForSelf(hapFilePaths, installParam, err => {
if (err) {
console.error('updateBundleForSelf failed:' + err.message);
} else {
console.info('updateBundleForSelf successfully.');
}
});
}).catch(error => {
console.error('getBundleInstaller failed. Cause: ' + error.message);
});
} catch (error) {
console.error('getBundleInstaller failed. Cause: ' + error.message);
}
```
## BundleInstaller.updateBundleForSelf<sup>10+</sup>
updateBundleForSelf(hapFilePaths: Array<string>, callback: AsyncCallback<void>): void;
以异步方法更新当前应用,仅限企业设备上的企业MDM应用调用,且传入的hapFilePaths中的hap必须都属于当前应用,使用callback形式返回结果。
**系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_SELF_BUNDLE
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| --------------- | ---------------------------------------------------- | ---- | ------------------------------------------------------------ |
| hapFilePaths | Array&lt;string&gt; | 是 | 存储应用程序包的路径。路径应该是当前应用程序中存放HAP的数据目录。当传入的路径是一个目录时, 该目录下只能放同一个应用的HAP,且这些HAP的签名需要保持一致。 |
| callback | AsyncCallback&lt;void&gt; | 是 | 回调函数,安装应用成功,err为undefined,否则为错误对象。 |
**错误码:**
以下错误码的详细介绍请参见[ohos.bundle错误码](../errorcodes/errorcode-bundle.md)
| 错误码ID | 错误信息 |
| -------- | ------------------------------------------------------------ |
| 17700004 | The specified user ID is not found. |
| 17700010 | Failed to install the HAP because the HAP fails to be parsed. |
| 17700011 | Failed to install the HAP because the HAP signature fails to be verified. |
| 17700012 | Failed to install the HAP because the HAP path is invalid or the HAP is too large. |
| 17700015 | Failed to install the HAPs because they have different configuration information. |
| 17700016 | Failed to install the HAP because of insufficient system disk space. |
| 17700017 | Failed to install the HAP since the version of the HAP to install is too early. |
| 17700018 | Failed to install because the dependent module does not exist. |
| 17700031 | Failed to install the HAP because the overlay check of the HAP is failed. |
| 17700039 | Failed to install because disallow install a shared bundle by hapFilePaths. |
| 17700041 | Failed to install because enterprise device management disallow install. |
| 17700042 | Failed to install the HAP because of incorrect URI in the data proxy. |
| 17700043 | Failed to install the HAP because of low APL in the non-system data proxy (required APL: system_basic or system_core). |
| 17700044 | Failed to install the HAP because the isolationMode configured is not supported. |
| 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. |
| 17700048 | Failed to install the HAP because the code signature verification is failed. |
| 17700049 | Failed to install the HAP because the bundleName is different from the bundleName of the caller application. |
| 17700050 | Failed to install the HAP because enterprise normal/MDM bundle cannot be installed on non-enterprise device. |
| 17700051 | Failed to install the HAP because the distribution type of caller application is not enterprise_mdm. |
**示例:**
```ts
import installer from '@ohos.bundle.installer';
let hapFilePaths = ['/data/storage/el2/base/haps/entry/files/'];
try {
installer.getBundleInstaller().then(data => {
data.updateBundleForSelf(hapFilePaths, err => {
if (err) {
console.error('updateBundleForSelf failed:' + err.message);
} else {
console.info('updateBundleForSelf successfully.');
}
});
}).catch(error => {
console.error('getBundleInstaller failed. Cause: ' + error.message);
});
} catch (error) {
console.error('getBundleInstaller failed. Cause: ' + error.message);
}
```
## BundleInstaller.updateBundleForSelf<sup>10+</sup>
updateBundleForSelf(hapFilePaths: Array<string>, installParam?: InstallParam): Promise<void>;
以异步方法更新当前应用,仅限企业设备上的企业MDM应用调用,且传入的hapFilePaths中的hap必须都属于当前应用,使用promise形式返回结果。
**系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_SELF_BUNDLE
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| --------------- | ---------------------------------------------------- | ---- | ------------------------------------------------------------ |
| hapFilePaths | Array&lt;string&gt; | 是 | 存储应用程序包的路径。路径应该是当前应用程序中存放HAP的数据目录。当传入的路径是一个目录时, 该目录下只能放同一个应用的HAP,且这些HAP的签名需要保持一致。 |
| installParam | [InstallParam](#installparam) | 否 | 指定安装所需的其他参数,默认值:参照[InstallParam](#installparam)的默认值。 |
**错误码:**
以下错误码的详细介绍请参见[ohos.bundle错误码](../errorcodes/errorcode-bundle.md)
| 错误码ID | 错误信息 |
| -------- | ------------------------------------------------------------ |
| 17700004 | The specified user ID is not found. |
| 17700010 | Failed to install the HAP because the HAP fails to be parsed. |
| 17700011 | Failed to install the HAP because the HAP signature fails to be verified. |
| 17700012 | Failed to install the HAP because the HAP path is invalid or the HAP is too large. |
| 17700015 | Failed to install the HAPs because they have different configuration information. |
| 17700016 | Failed to install the HAP because of insufficient system disk space. |
| 17700017 | Failed to install the HAP since the version of the HAP to install is too early. |
| 17700018 | Failed to install because the dependent module does not exist. |
| 17700031 | Failed to install the HAP because the overlay check of the HAP is failed. |
| 17700039 | Failed to install because disallow install a shared bundle by hapFilePaths. |
| 17700041 | Failed to install because enterprise device management disallow install. |
| 17700042 | Failed to install the HAP because of incorrect URI in the data proxy. |
| 17700043 | Failed to install the HAP because of low APL in the non-system data proxy (required APL: system_basic or system_core). |
| 17700044 | Failed to install the HAP because the isolationMode configured is not supported. |
| 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. |
| 17700048 | Failed to install the HAP because the code signature verification is failed. |
| 17700049 | Failed to install the HAP because the bundleName is different from the bundleName of the caller application. |
| 17700050 | Failed to install the HAP because enterprise normal/MDM bundle cannot be installed on non-enterprise device. |
| 17700051 | Failed to install the HAP because the distribution type of caller application is not enterprise_mdm. |
**示例:**
```ts
import installer from '@ohos.bundle.installer';
let hapFilePaths = ['/data/storage/el2/base/haps/entry/files/'];
let installParam = {
userId: 100,
isKeepData: false,
installFlag: 1,
};
try {
installer.getBundleInstaller().then(data => {
data.updateBundleForSelf(hapFilePaths, installParam)
.then((data) => {
console.info('updateBundleForSelf successfully: ' + JSON.stringify(data));
}).catch((error) => {
console.error('updateBundleForSelf failed:' + error.message);
});
}).catch(error => {
console.error('getBundleInstaller failed. Cause: ' + error.message);
});
} catch (error) {
console.error('getBundleInstaller failed. Cause: ' + error.message);
}
```
## HashParam ## HashParam
应用程序安装卸载哈希参数信息。 应用程序安装卸载哈希参数信息。
......
# @ohos.ai.intelligentVoice (智能语音)
智能语音主要提供了语音注册及语音唤醒相关功能。
该模块提供以下智能语音相关的常用功能:
- [IntelligentVoiceManager](#intelligentvoicemanager):智能语音管理类,明确当前智能语音提供的相关功能,当前支持语音注册、语音唤醒。在进行智能语音相关开发前,需先调用[getIntelligentVoiceManager()](#intelligentvoicegetintelligentvoicemanager)确认当前支持智能语音的相关功能,再进行语音注册和语音唤醒的相关开发。
- [EnrollIntelligentVoiceEngine](#enrollintelligentvoiceengine):实现语音注册。开发者需要先进行智能语音的注册,然后才能进行唤醒。
- [WakeupIntelligentVoiceEngine](#wakeupintelligentvoiceengine):实现语音唤醒。开发者需要先进行智能语音的注册,然后才能进行唤醒。
> **说明:**
>
> 本模块首批接口从API version 10开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。
>
## 导入模块
```js
import intelligentVoice from '@ohos.ai.intelligentVoice';
```
## intelligentVoice.getIntelligentVoiceManager
getIntelligentVoiceManager(): IntelligentVoiceManager
获取智能语音管理类。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**返回值:**
| 类型 | 说明 |
| ----------------------------- | ------------ |
| [IntelligentVoiceManager](#intelligentvoicemanager) | 智能语音管理类。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700101 | No memory. |
**示例:**
```js
var intelligentVoiceManager = null;
try {
intelligentVoiceManager = intelligentVoice.getIntelligentVoiceManager();
} catch (err) {
console.error('Get IntelligentVoiceManager failed. Code:${err.code}, message:${err.message}');
}
```
## intelligentVoice.createEnrollIntelligentVoiceEngine
createEnrollIntelligentVoiceEngine(descriptor: EnrollIntelligentVoiceEngineDescriptor, callback: AsyncCallback&lt;EnrollIntelligentVoiceEngine&gt;): void
创建智能语音注册引擎实例,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | ----------------------------------- | ---- | ---------------------- |
| descriptor | [EnrollIntelligentVoiceEngineDescriptor](#enrollintelligentvoiceenginedescriptor) | 是 | 智能语音注册引擎描述符。 |
| callback | AsyncCallback\<[EnrollIntelligentVoiceEngine](#enrollintelligentvoiceengine)\> | 是 | 返回注册智能语音引擎。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700101 | No memory. |
| 22700102 | Input parameter value error. |
**示例:**
```js
let engineDescriptor = {
wakeupPhrase: '小花小花',
}
var enrollIntelligentVoiceEngine = null;
intelligentVoice.createEnrollIntelligentVoiceEngine(engineDescriptor, (err, data) => {
if (err) {
console.error(`Failed to create enrollIntelligentVoice engine, Code:${err.code}, message:${err.message}`);
} else {
console.info('Succeeded in creating enrollIntelligentVoice engine.');
enrollIntelligentVoiceEngine = data;
}
});
```
## intelligentVoice.createEnrollIntelligentVoiceEngine
createEnrollIntelligentVoiceEngine(descriptor: EnrollIntelligentVoiceEngineDescriptor): Promise&lt;EnrollIntelligentVoiceEngine&gt;
创建智能语音注册引擎实例,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | ----------------------------------- | ---- | ---------------------- |
| descriptor | [EnrollIntelligentVoiceEngineDescriptor](#enrollintelligentvoiceenginedescriptor) | 是 | 智能语音注册引擎描述符。 |
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise\<[EnrollIntelligentVoiceEngine](#enrollintelligentvoiceengine)\> | 返回注册智能语音引擎。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700101 | No memory. |
| 22700102 | Input parameter value error. |
**示例:**
```js
var enrollIntelligentVoiceEngine = null;
let engineDescriptor = {
wakeupPhrase: '小花小花',
}
intelligentVoice.createEnrollIntelligentVoiceEngine(engineDescriptor).then((data) => {
enrollIntelligentVoiceEngine = data;
console.info('Succeeded in creating enrollIntelligentVoice engine.');
}).catch((err) => {
console.error(`Failed to create enrollIntelligentVoice engine, Code:${err.code}, message:${err.message}`);
});
```
## intelligentVoice.createWakeupIntelligentVoiceEngine
createWakeupIntelligentVoiceEngine(descriptor: WakeupIntelligentVoiceEngineDescriptor, callback: AsyncCallback&lt;WakeupIntelligentVoiceEngine&gt;): void
创建智能语音唤醒引擎实例,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | ----------------------------------- | ---- | ---------------------- |
| descriptor | [WakeupIntelligentVoiceEngineDescriptor](#wakeupintelligentvoiceenginedescriptor) | 是 | 唤醒智能语音引擎描述符。 |
| callback | AsyncCallback\<[WakeupIntelligentVoiceEngine](#wakeupintelligentvoiceengine)\> | 是 | 返回唤醒智能语音引擎。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700101 | No memory. |
| 22700102 | Input parameter value error. |
**示例:**
```js
let engineDescriptor = {
needReconfirm: true,
wakeupPhrase: '小花小花',
}
var wakeupIntelligentVoiceEngine = null;
intelligentVoice.createWakeupIntelligentVoiceEngine(engineDescriptor, (err, data) => {
if (err) {
console.error(`Failed to create wakeupIntelligentVoice engine, Code:${err.code}, message:${err.message}`);
} else {
console.info('Succeeded in creating wakeupIntelligentVoice engine.');
wakeupIntelligentVoiceEngine = data;
}
});
```
## intelligentVoice.createWakeupIntelligentVoiceEngine
createWakeupIntelligentVoiceEngine(descriptor: WakeupIntelligentVoiceEngineDescriptor): Promise&lt;WakeupIntelligentVoiceEngine&gt;
创建智能语音唤醒引擎实例,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | ----------------------------------- | ---- | ---------------------- |
| descriptor | [WakeupIntelligentVoiceEngineDescriptor](#wakeupintelligentvoiceenginedescriptor) | 是 | 唤醒智能语音引擎描述符。 |
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise\<[WakeupIntelligentVoiceEngine](#wakeupintelligentvoiceengine)> | 返回唤醒智能语音引擎。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700101 | No memory. |
| 22700102 | Input parameter value error. |
**示例:**
```js
let engineDescriptor = {
needReconfirm: true,
wakeupPhrase: '小花小花',
}
var wakeupIntelligentVoiceEngine = null;
intelligentVoice.createWakeupIntelligentVoiceEngine(engineDescriptor).then((data) => {
wakeupIntelligentVoiceEngine = data;
console.info('Succeeded in creating wakeupIntelligentVoice engine.');
}).catch((err) => {
console.error('Failed to create wakeupIntelligentVoice engine, Code:${err.code}, message:${err.message});
});
```
## IntelligentVoiceManager
智能语音管理类,使用前需要通过[getIntelligentVoiceManager()](#intelligentvoicegetintelligentvoicemanager)获取智能语音管理实例。
### getCapabilityInfo
getCapabilityInfo(): Array&lt;IntelligentVoiceEngineType&gt;
获取支持的智能语音引擎列表信息。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Array\<[IntelligentVoiceEngineType](#intelligentvoiceenginetype)\> | 支持的智能语音引擎类型数组。 |
**示例:**
```js
let info = intelligentVoiceManager.getCapabilityInfo();
```
### on('serviceChange')
on(type: 'serviceChange', callback: Callback&lt;ServiceChangeType&gt;): void
订阅服务变更事件。当智能语音业务状态发生变化时,调用回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| type | string | 是 | 系统服务变更事件,固定取值为'serviceChange',表示服务变更事件。 |
| callback | Callback\<[ServiceChangeType](#servicechangetype)\> | 是 | 服务状态变更对应的处理。|
**示例:**
```js
intelligentVoiceManager.on('serviceChange', (serviceChangeType) => {});
```
### off('serviceChange')
off(type: 'serviceChange', callback?: Callback\<ServiceChangeType\>): void
取消订阅服务变更事件。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| type | string | 是 | 系统服务变更事件,固定取值为'serviceChange'。 |
| callback | Callback\<[ServiceChangeType](#servicechangetype)\> | 否 | 服务状态变更对应的处理,无参数,则取消所有订阅,否则,取消对应的处理。|
**示例:**
```js
intelligentVoiceManager.off('serviceChange');
```
## ServiceChangeType
枚举,服务状态变更类型。
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
| 名称 | 值 | 说明 |
| ------------------------- | ---- | ------------ |
| SERVICE_UNAVAILABLE | 0 | 服务状态不可用。 |
## IntelligentVoiceEngineType
枚举,智能语音引擎类型。
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
| 名称 | 值 | 说明 |
| ------------------------- | ---- | ------------ |
| ENROLL_ENGINE_TYPE | 0 | 语音注册引擎。 |
| WAKEUP_ENGINE_TYPE | 1 | 语音唤醒引擎。 |
| UPDATE_ENGINE_TYPE | 2 | 静默升级引擎。 |
## EnrollIntelligentVoiceEngineDescriptor
注册智能语音引擎描述符。
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
| 名称 | 类型 | 必填 | 说明 |
| ------ | ----------------------------- | -------------- | ---------- |
| wakeupPhrase | string | 是 | 唤醒词。 |
## WakeupIntelligentVoiceEngineDescriptor
唤醒智能语音引擎描述符。
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
| 名称 | 类型 | 必填 | 说明 |
| ------ | ----------------------------- | -------------- | ---------- |
| needReconfirm | boolean | 是 | 是否需要再次确认唤醒结果,true为需要,false为不需要。 |
| wakeupPhrase | string | 是 | 唤醒词。 |
## EnrollEngineConfig
描述注册引擎配置。
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
| 名称 | 类型 | 必填 | 说明 |
| ------ | ----------------------------- | -------------- | ---------- |
| language | string | 是 | 注册引擎支持的语言,当前仅支持中文,取值为'zh'。 |
| region | string | 是 | 注册引擎支持的区域。当前仅支持中国,取值为'CN'。 |
## SensibilityType
枚举,唤醒灵敏度类型。
灵敏度用于调整唤醒的门限,灵敏度越高,门限越低,就越容易唤醒。
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
| 名称 | 值 | 说明 |
| ------------------------- | ---- | ------------ |
| LOW_SENSIBILITY | 1 | 低灵敏度。 |
| MIDDLE_SENSIBILITY | 2 | 中灵敏度。 |
| HIGH_SENSIBILITY | 3 | 高灵敏度。 |
## WakeupHapInfo
描述唤醒应用的hap信息。
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
| 名称 | 类型 | 必填 | 说明 |
| ------ | ----------------------------- | -------------- | ---------- |
| bundleName | string | 是 | 唤醒应用的bundleName。 |
| abilityName | string | 是 | 唤醒应用的ailityName。 |
## WakeupIntelligentVoiceEventType
枚举,唤醒智能语音事件类型。
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
| 名称 | 值 | 说明 |
| ------------------------- | ---- | ------------ |
| INTELLIGENT_VOICE_EVENT_WAKEUP_NONE | 0 | 无唤醒。 |
| INTELLIGENT_VOICE_EVENT_RECOGNIZE_COMPLETE | 1 | 唤醒识别完成。 |
## IntelligentVoiceErrorCode
枚举,智能语音错误码。
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
| 名称 | 值 | 说明 |
| ------------------------- | ---- | ------------ |
| INTELLIGENT_VOICE_NO_MEMORY | 22700101 | 内存不足。 |
| INTELLIGENT_VOICE_INVALID_PARAM | 22700102 | 参数无效。 |
| INTELLIGENT_VOICE_INIT_FAILED | 22700103 | 注册失败。 |
| INTELLIGENT_VOICE_COMMIT_ENROLL_FAILED | 22700104 | 确认注册结果失败。 |
## EnrollResult
枚举,注册结果。
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
| 名称 | 值 | 说明 |
| ------------------------- | ---- | ------------ |
| SUCCESS | 0 | 注册成功。 |
| VPR_TRAIN_FAILED | -1 | 声纹训练失败。 |
| WAKEUP_PHRASE_NOT_MATCH | -2 | 唤醒短语不匹配。 |
| TOO_NOISY | -3 | 周边环境太吵。 |
| TOO_LOUD | -4 | 声音太大。 |
| INTERVAL_LARGE | -5 | 唤醒词时间间隔太大。 |
| DIFFERENT_PERSON | -6 | 不同人注册唤醒词。 |
| UNKNOWN_ERROR | -100 | 未知错误。 |
## EnrollCallbackInfo
注册回调信息。
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
| 名称 | 类型 | 必填 | 说明 |
| ------ | ----------------------------- | -------------- | ---------- |
| result | [EnrollResult](#enrollresult) | 是 | 注册结果。 |
| context | string | 是 | 描述注册事件上下文。 |
## WakeupIntelligentVoiceEngineCallbackInfo
描述唤醒智能语音引擎回调信息。
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
| 名称 | 类型 | 必填 | 说明 |
| ------ | ----------------------------- | -------------- | ---------- |
| eventId | [WakeupIntelligentVoiceEventType](#wakeupintelligentvoiceeventtype) | 是 | 唤醒智能语音事件类型。 |
| isSuccess | boolean | 是 | 是否唤醒成功,false为唤醒失败,true为唤醒成功。 |
| context | string | 是 | 描述唤醒事件上下文。 |
## EnrollIntelligentVoiceEngine
实现注册智能语音引擎,通过[createEnrollIntelligentVoiceEngine()](#intelligentvoicecreateenrollintelligentvoiceengine)获取注册智能语音引擎。
### getSupportedRegions
getSupportedRegions(callback: AsyncCallback&lt;Array&lt;string&gt;&gt;): void
获取支持的区域,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| callback | AsyncCallback&lt;Array&lt;string&gt;&gt; | 是 | 返回支持区域的数组,当前只支持中国,对应取值为'CN'。 |
**示例:**
```js
let regions = null;
enrollIntelligentVoiceEngine.getSupportedRegions((err, data) => {
if (err) {
console.error(`Failed to get supported regions, Code:${err.code}, message:${err.message}`);
} else {
regions = data;
console.info('Succeeded in getting supported regions, regions:${regions}.');
}
});
```
### getSupportedRegions
getSupportedRegions(): Promise&lt;Array&lt;string&gt;&gt;
获取支持的区域,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise&lt;Array&lt;string&gt;&gt; | 返回支持区域的数组,当前只支持中国,对应取值为'CN'。 |
**示例:**
```js
let regions = null;
enrollIntelligentVoiceEngine.getSupportedRegions().then((data) => {
regions = data;
console.info('Succeeded in getting supported regions, regions:${regions}.');
}).catch((err) => {
console.error(`Failed to get supported regions, Code:${err.code}, message:${err.message}`);
});
```
### init
init(config: EnrollEngineConfig, callback: AsyncCallback&lt;void&gt;): void
初始化注册智能语音引擎,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| config | [EnrollEngineConfig](#enrollengineconfig) | 是 | 注册引擎配置。 |
| callback |AsyncCallback&lt;void&gt; | 是 | 返回初始化结果。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
| 22700103 | Init failed. |
**示例:**
```js
let config = {
language: "zh",
area: "CN",
}
enrollIntelligentVoiceEngine.init(config, (err) => {
if (err) {
console.error(`Failed to initialize enrollIntelligentVoice engine. Code:${err.code}, message:${err.message}`);
} else {
console.info('Succeeded in initialzing enrollIntelligentVoice engine.');
}
});
```
### init
init(config: EnrollEngineConfig): Promise&lt;void&gt;
初始化注册智能语音引擎,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| config | [EnrollEngineConfig](#enrollengineconfig) | 是 | config表示注册引擎配置。 |
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise&lt;void&gt; | 无返回结果的Promise对象。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
| 22700103 | Init failed. |
**示例:**
```js
let config = {
language: "zh",
area: "CN",
}
enrollIntelligentVoiceEngine.init(config).then(() => {
console.info('Succeeded in initializing enrollIntelligentVoice engine.');
}).catch((err) => {
console.error(`Failed to initialize enrollIntelligentVoice engine. Code:${err.code}, message:${err.message}`);
});
```
### enrollForResult
enrollForResult(isLast: boolean, callback: AsyncCallback&lt;EnrollCallbackInfo&gt;): void
获取注册结果,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| isLast | boolean | 是 | isLast表示是否为最后一次注册,false为非最后一次,true为最后一次。 |
| callback | AsyncCallback&lt;[EnrollCallbackInfo](#enrollcallbackinfo)&gt; | 是 | 返回注册结果。 |
**示例:**
```js
let isLast = true;
let callbackInfo = null;
enrollIntelligentVoiceEngine.enrollForResult(isLast, (err, data) => {
if (err) {
console.error(`Failed to enroll for result, Code:${err.code}, message:${err.message}`);
} else {
callbackInfo = data;
console.info('Succeeded in enrolling for result, info:${callbackInfo}.');
}
});
```
### enrollForResult
enrollForResult(isLast: boolean): Promise&lt;EnrollCallbackInfo&gt;
获取注册结果,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| isLast | boolean | 是 | isLast表示是否为最后一次注册,false为非最后一次,true为最后一次。 |
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise&lt;[EnrollCallbackInfo](#enrollcallbackinfo)&gt; | 返回注册结果。 |
**示例:**
```js
let isLast = true;
let callbackInfo = null;
enrollIntelligentVoiceEngine.enrollForResult(isLast).then((data) => {
callbackInfo = data;
console.info('Succeeded in enrolling for result, info:${callbackInfo}.');
}).catch((err) => {
console.error(`Failed to enroll for result, Code:${err.code}, message:${err.message}`);
});
```
### stop
stop(callback: AsyncCallback&lt;void&gt;): void
停止注册,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| callback | AsyncCallback&lt;void&gt; | 是 | 返回停止结果。 |
**示例:**
```js
enrollIntelligentVoiceEngine.stop((err) => {
if (err) {
console.error(`Failed to stop enrollIntelligentVoice engine, Code:${err.code}, message:${err.message}`);
} else {
console.info('Succeeded in stopping enrollIntelligentVoice engine.');
}
});
```
### stop
stop(): Promise&lt;void&gt;
停止注册,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise&lt;void&gt; | 无返回结果的Promise对象。 |
**示例:**
```js
enrollIntelligentVoiceEngine.stop().then(() => {
console.info('Succeeded in stopping enrollIntelligentVoice engine.');
}).catch((err) => {
console.error(`Failed to stop enrollIntelligentVoice engine, Code:${err.code}, message:${err.message}`);
});
```
### commit
commit(callback: AsyncCallback&lt;void&gt;): void
提交注册,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| callback | AsyncCallback&lt;void&gt; | 是 | 返回确认注册结果。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700104 | Commit enroll failed. |
**示例:**
```js
enrollIntelligentVoiceEngine.commit((err) => {
if (err) {
console.error(`Failed to commit enroll, Code:${err.code}, message:${err.message}`);
} else {
console.info('Succeeded in committing enroll.');
}
});
```
### commit
commit(): Promise&lt;void&gt;
提交注册,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise&lt;void&gt; | 无返回结果的Promise对象。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700104 | Commit enroll failed. |
**示例:**
```js
enrollIntelligentVoiceEngine.commit().then(() => {
console.info('Succeeded in committing enroll.');
}).catch((err) => {
console.error(`Failed to commit enroll, Code:${err.code}, message:${err.message}`);
});
```
### setWakeupHapInfo
setWakeupHapInfo(info: WakeupHapInfo, callback: AsyncCallback\<void>): void
设置唤醒应用的hap信息,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| info | [WakeupHapInfo](#wakeuphapinfo) | 是 | 唤醒hap信息。 |
| callback | AsyncCallback\<void\> | 是 | 返回设置唤醒hap信息的结果。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
let info = {
bundleName: "com.wakeup",
abilityName: "WakeUpExtAbility",
}
enrollIntelligentVoiceEngine.setWakeupHapInfo(info, (err) => {
if (err) {
console.error('Failed to set wakeup hap info, Code:${err.code}, message:${err.message}');
} else {
console.info('Succeeded in setting wakeup hap info.');
}
});
```
### setWakeupHapInfo
setWakeupHapInfo(info: WakeupHapInfo): Promise\<void\>
设置唤醒应用的hap信息,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise&lt;void&gt; | 无返回结果的Promise对象。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
let info = {
bundleName: "com.wakeup",
abilityName: "WakeUpExtAbility",
}
enrollIntelligentVoiceEngine.setWakeupHapInfo(info).then(() => {
console.info('Succeeded in setting wakeup hap info.');
}).catch((err) => {
console.error('Failed to set wakeup hap info, Code:${err.code},
});
```
### setSensibility
setSensibility(sensibility: SensibilityType, callback: AsyncCallback\<void\>): void
设置唤醒灵敏度,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| sensibility | [SensibilityType](#sensibilitytype) | 是 | 灵敏度类型。 |
| callback | AsyncCallback\<void\> | 是 | 返回设置灵敏度的结果。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
enrollIntelligentVoiceEngine.setSensibility(intelligentVoice.SensibilityType.LOW_SENSIBILITY, (err) => {
if (err) {
console.error(`Failed to set sensibility, Code:${err.code}, message:${err.message}`);
} else {
console.info('Succeeded in setting sensibility.');
}
});
```
### setSensibility
setSensibility(sensibility: SensibilityType): Promise\<void\>
设置唤醒灵敏度,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| sensibility | [SensibilityType](#sensibilitytype) | 是 | 灵敏度类型。 |
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise&lt;void&gt; | 无返回结果的Promise对象。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
enrollIntelligentVoiceEngine.setSensibility(intelligentVoice.SensibilityType.LOW_SENSIBILITY).then(() => {
console.info('Succeeded in setting sensibility.');
}).catch((err) => {
console.error(`Failed to set sensibility, Code:${err.code}, message:${err.message}`);
});
```
### setParameter
setParameter(key: string, value: string, callback: AsyncCallback\<void\>): void
设置指定的智能语音参数,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| key | string | 是 | 键。 |
| value | string | 是 | 值。 |
| callback | AsyncCallback\<void\> | 是 | 返回设置智能语音参数的结果。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
enrollIntelligentVoiceEngine.setParameter('scene', '0', (err) => {
if (err) {
console.error(`Failed to set parameter, Code:${err.code}, message:${err.message}`);
} else {
console.info('Succeeded in setting parameter');
}
});
```
### setParameter
setParameter(key: string, value: string): Promise\<void\>
设置指定的智能语音参数,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| key | string | 是 | 键。 |
| value | string | 是 | 值。 |
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise&lt;void&gt; | 无返回结果的Promise对象。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
enrollIntelligentVoiceEngine.setParameter('scene', '0').then(() => {
console.info('Succeeded in setting parameter');
}).catch((err) => {
console.error(`Failed to set parameter, Code:${err.code}, message:${err.message}`);
});
```
### getParameter
getParameter(key: string, callback: AsyncCallback\<string\>): void
获取指定的智能语音参数,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| key | string | 是 | 键。 |
| callback | AsyncCallback\<string\> | 是 | 返回智能语音参数。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
enrollIntelligentVoiceEngine.getParameter('key', (err,data) => {
if (err) {
console.error(`Failed to get parameter, Code:${err.code}, message:${err.message}`);
} else {
let param = data;
console.info('Succeeded in getting parameter, param:${param}');
}
});
```
### getParameter
getParameter(key: string): Promise\<string\>
获取指定的智能语音参数,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| key | string | 是 | 键。 |
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise\<string\> | 返回智能语音参数。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
let param = null;
enrollIntelligentVoiceEngine.getParameter('key').then((data) => {
param = data;
console.info('Succeeded in getting parameter, param:${param}');
}).catch((err) => {
console.error(`Failed to get parameter, Code:${err.code}, message:${err.message}`);
});
```
### release
release(callback: AsyncCallback&lt;void&gt;): void
释放注册智能语音引擎,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| callback | AsyncCallback\<void\> | 是 | 返回释放注册引擎的结果。 |
**示例:**
```js
enrollIntelligentVoiceEngine.release((err) => {
if (err) {
console.error('Failed to release enrollIntelligentVoice engine, Code:${err.code}, message:${err.message}');
} else {
console.info('Succeeded in releasing enrollIntelligentVoice engine.');
}
});
```
### release
release(): Promise&lt;void&gt;
释放注册智能语音引擎,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise&lt;void&gt; | 无返回结果的Promise对象。 |
**示例:**
```js
enrollIntelligentVoiceEngine.release().then(() => {
console.info('Succeeded in releasing enrollIntelligentVoice engine.');
}).catch((err) => {
console.error('Failed to release enrollIntelligentVoice engine, Code:${err.code}, message:${err.message}');
});
```
## WakeupIntelligentVoiceEngine
实现唤醒智能语音引擎,通过[createWakeupIntelligentVoiceEngine()](#intelligentvoicecreatewakeupintelligentvoiceengine)获取唤醒智能语音引擎。
### getSupportedRegions
getSupportedRegions(callback: AsyncCallback&lt;Array&lt;string&gt;&gt;): void
获取支持的区域,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| callback | AsyncCallback&lt;Array&lt;string&gt;&gt; | 是 | 返回支持区域的数组,当前只支持中国,对应取值为'CN'。 |
**示例:**
```js
let regions = null;
wakeupIntelligentVoiceEngine.getSupportedRegions((err, data) => {
if (err) {
console.error(`Failed to get supported regions, Code:${err.code}, message:${err.message}`);
} else {
regions = data;
console.info('Succeeded in getting supported regions, regions:${regions}.');
}
});
```
### getSupportedRegions
getSupportedRegions(): Promise&lt;Array&lt;string&gt;&gt;
获取支持的区域,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise&lt;Array&lt;string&gt;&gt; | 返回支持区域的数组,当前只支持中国,对应取值为'CN'。 |
**示例:**
```js
let regions = null;
wakeupIntelligentVoiceEngine.getSupportedRegions().then((data) => {
regions = data;
console.info('Succeeded in getting supported regions, regions:${regions}.');
}).catch((err) => {
console.error(`Failed to get supported regions, Code:${err.code}, message:${err.message}`);
});
```
### setWakeupHapInfo
setWakeupHapInfo(info: WakeupHapInfo, callback: AsyncCallback\<void\>): void
设置唤醒应用的hap信息,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| info | [WakeupHapInfo](#wakeuphapinfo) | 是 | 唤醒hap信息。 |
| callback | AsyncCallback\<void\> | 是 | 返回设置唤醒hap信息的结果。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
let info = {
bundleName: "com.wakeup",
abilityName: "WakeUpExtAbility",
}
wakeupIntelligentVoiceEngine.setWakeupHapInfo(info, (err) => {
if (err) {
console.error('Failed to set wakeup hap info, Code:${err.code}, message:${err.message}');
} else {
console.info('Succeeded in setting wakeup hap info.');
}
});
```
### setWakeupHapInfo
setWakeupHapInfo(info: WakeupHapInfo): Promise\<void\>
设置唤醒应用的hap信息,使用promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| info | [WakeupHapInfo](#wakeuphapinfo) | 是 | 唤醒hap信息。 |
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise&lt;void&gt; | 无返回结果的Promise对象。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
let info = {
bundleName: "com.wakeup",
abilityName: "WakeUpExtAbility",
}
wakeupIntelligentVoiceEngine.setWakeupHapInfo(info).then(() => {
console.info('Succeeded in setting wakeup hap info.');
}).catch((err) => {
console.error('Failed to set wakeup hap info, Code:${err.code}, message:${err.message}');
});
```
### setSensibility
setSensibility(sensibility: SensibilityType, callback: AsyncCallback\<void\>): void
设置唤醒灵敏度,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| sensibility | [SensibilityType](#sensibilitytype) | 是 | 灵敏度类型。 |
| callback | AsyncCallback\<void\> | 是 | 返回设置灵敏度的结果。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
wakeupIntelligentVoiceEngine.setSensibility(intelligentVoice.SensibilityType.LOW_SENSIBILITY, (err) => {
if (err) {
console.error(`Failed to set sensibility, Code:${err.code}, message:${err.message}`);
} else {
console.info('Succeeded in setting sensibility.');
}
});
```
### setSensibility
setSensibility(sensibility: SensibilityType): Promise\<void\>
设置唤醒灵敏度,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| sensibility | [SensibilityType](#sensibilitytype) | 是 | 灵敏度类型。 |
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise&lt;void&gt; | 无返回结果的Promise对象。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
wakeupIntelligentVoiceEngine.setSensibility(intelligentVoice.SensibilityType.LOW_SENSIBILITY).then(() => {
console.info('Succeeded in setting sensibility.');
}).catch((err) => {
console.error(`Failed to set sensibility, Code:${err.code}, message:${err.message}`);
});
```
### setParameter
setParameter(key: string, value: string, callback: AsyncCallback\<void\>): void
设置指定的智能语音参数,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| key | string | 是 | 键。 |
| value | string | 是 | 值。 |
| callback | AsyncCallback\<void\> | 是 | 返回设置智能语音参数的结果。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
wakeupIntelligentVoiceEngine.setParameter('scene', '0', (err) => {
if (err) {
console.error(`Failed to set parameter, Code:${err.code}, message:${err.message}`);
} else {
console.info('Succeeded in setting parameter');
}
});
```
### setParameter
setParameter(key: string, value: string): Promise\<void\>
设置指定的智能语音参数,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| key | string | 是 | 键。 |
| value | string | 是 | 值。 |
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise&lt;void&gt; | 无返回结果的Promise对象。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
wakeupIntelligentVoiceEngine.setParameter('scene', '0').then(() => {
console.info('Succeeded in setting parameter');
}).catch((err) => {
console.error(`Failed to set parameter, Code:${err.code}, message:${err.message}`);
});
```
### getParameter
getParameter(key: string, callback: AsyncCallback\<string\>): void
获取指定的智能语音参数,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| key | string | 是 | 键。 |
| callback | AsyncCallback\<string\> | 是 | 返回智能语音参数。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
wakeupIntelligentVoiceEngine.getParameter('key', (err, data) => {
if (err) {
console.error(`Failed to get parameter, Code:${err.code}, message:${err.message}`);
} else {
let param = data;
console.info('Succeeded in getting parameter, param:${param}');
}
});
```
### getParameter
getParameter(key: string): Promise\<string\>
获取指定的智能语音参数,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| key | string | 是 | 键。 |
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise\<string\> | 返回智能语音参数。 |
**错误码:**
以下错误码的详细介绍请参见[智能语音错误码](../errorcodes/errorcode-intelligentVoice.md)
| 错误码ID | 错误信息 |
| ------- | --------------------------------------------|
| 22700102 | Input parameter value error. |
**示例:**
```js
let param;
wakeupIntelligentVoiceEngine.getParameter('key').then((data) => {
param = data;
console.info('Succeeded in getting parameter, param:${param}');
}).catch((err) => {
console.error(`Failed to get parameter, Code:${err.code}, message:${err.message}`);
});
```
### release
release(callback: AsyncCallback\<void\>): void
释放唤醒智能语音引擎,使用callback异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| callback | AsyncCallback\<void\> | 是 | 返回释放唤醒引擎的结果。 |
**示例:**
```js
wakeupIntelligentVoiceEngine.release((err) => {
if (err) {
console.error('Failed to release wakeupIntelligentVoice engine, Code:${err.code}, message:${err.message}');
} else {
console.info('Succeeded in releasing wakeupIntelligentVoice engine.');
}
});
```
### release
release(): Promise\<void\>
释放唤醒智能语音引擎,使用Promise异步回调。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**返回值:**
| 类型 | 说明 |
| ----------------------------------------------- | ---------------------------- |
| Promise&lt;void&gt; | 无返回结果的Promise对象。 |
**示例:**
```js
wakeupIntelligentVoiceEngine.release().then(() => {
console.info('Succeeded in releasing wakeupIntelligentVoice engine.');
}).catch((err) => {
console.error('Failed to release wakeupIntelligentVoice engine, Code:${err.code}, message:${err.message}');
});
```
### on
on(type: 'wakeupIntelligentVoiceEvent', callback: Callback\<WakeupIntelligentVoiceEngineCallbackInfo\>): void
订阅唤醒事件。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| type | string | 是 | 唤醒智能语音事件,固定取为'wakeupIntelligentVoiceEvent',表示智能语音唤醒事件。 |
| callback | Callback\<[WakeupIntelligentVoiceEngineCallbackInfo](#wakeupintelligentvoiceenginecallbackinfo)\> | 是 | 收到唤醒事件的对应处理。 |
**示例:**
```js
wakeupIntelligentVoiceEngine.on('wakeupIntelligentVoiceEvent', (callback) => {
console.info(`wakeup intelligentvoice event`);
for (let prop in callback) {
console.info(`intelligentvoice prop: ${prop}`);
}
});
```
### off
off(type: 'wakeupIntelligentVoiceEvent', callback?: Callback\<WakeupIntelligentVoiceEngineCallbackInfo\>): void;
取消订阅唤醒事件。
**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE
**系统能力:** SystemCapability.AI.IntelligentVoice.Core
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
| -------- | -------------------------------- | --- | ------------------------------------------- |
| type |string | 是 | 唤醒智能语音事件,固定取为'wakeupIntelligentVoiceEvent'。 |
| callback | Callback\<[WakeupIntelligentVoiceEngineCallbackInfo](#wakeupintelligentvoiceenginecallbackinfo)\> | 否 | 收到唤醒事件的对应处理。无参数,则取消所有的订阅,否则,取消对应的订阅 |
**示例:**
```js
wakeupIntelligentVoiceEngine.off('wakeupIntelligentVoiceEvent');
```
...@@ -443,6 +443,90 @@ notificationSubscribe.remove(hashCode, reason).then(() => { ...@@ -443,6 +443,90 @@ notificationSubscribe.remove(hashCode, reason).then(() => {
console.info("remove success"); console.info("remove success");
}); });
``` ```
## NotificationSubscribe.remove
remove(hashCodes: Array\<string\>, reason: RemoveReason, callback: AsyncCallback\<void\>): void
批量删除指定通知(Callback形式)。
**系统能力**:SystemCapability.Notification.Notification
**需要权限**: ohos.permission.NOTIFICATION_CONTROLLER
**系统API**: 此接口为系统接口,三方应用不支持调用。
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
|-----------|-------------------------------| ---- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| hashCodes | Array\<string\> | 是 | 通知唯一ID数组集合。可以通过[onConsume](js-apis-inner-notification-notificationSubscriber.md#onConsume)回调的入参[SubscribeCallbackData](js-apis-notification.md#subscribecallbackdata)获取其内部[NotificationRequest](js-apis-inner-notification-notificationRequest.md#notificationrequest)对象中的hashCode。 |
| reason | [RemoveReason](#removereason) | 是 | 通知删除原因。 |
| callback | AsyncCallback\<void\> | 是 | 删除指定通知回调函数。 |
**错误码:**
错误码详细介绍请参考[errcode-notification](../errorcodes/errorcode-notification.md)
| 错误码ID | 错误信息 |
| -------- | ----------------------------------- |
| 1600001 | Internal error. |
| 1600002 | Marshalling or unmarshalling error. |
| 1600003 | Failed to connect service. |
**示例:**
```js
let hashCodes = ['hashCode1', 'hashCode2'];
function removeCallback(err) {
if (err) {
console.error(`remove failed, code is ${err.code}, message is ${err.message}`);
} else {
console.info("remove success");
}
}
let reason = notificationSubscribe.RemoveReason.CANCEL_REASON_REMOVE;
notificationSubscribe.remove(hashCodes, reason, removeCallback);
```
## NotificationSubscribe.remove
remove(hashCodes: Array\<string\>, reason: RemoveReason): Promise\<void\>
批量删除指定通知(Promise形式)。
**系统能力**:SystemCapability.Notification.Notification
**需要权限**: ohos.permission.NOTIFICATION_CONTROLLER
**系统API**: 此接口为系统接口,三方应用不支持调用。
**参数:**
| 参数名 | 类型 | 必填 | 说明 |
|-----------|-------------------------------| ---- |-------------|
| hashCodes | Array\<string\> | 是 | 通知唯一ID数组集合。 |
| reason | [RemoveReason](#removereason) | 是 | 通知删除原因。 |
**错误码:**
错误码详细介绍请参考[errcode-notification](../errorcodes/errorcode-notification.md)
| 错误码ID | 错误信息 |
| -------- | ----------------------------------- |
| 1600001 | Internal error. |
| 1600002 | Marshalling or unmarshalling error. |
| 1600003 | Failed to connect service. |
**示例:**
```js
let hashCodes = ['hashCode1','hashCode2'];
let reason = notificationSubscribe.RemoveReason.CLICK_REASON_REMOVE;
notificationSubscribe.remove(hashCodes, reason).then(() => {
console.info("remove success");
});
```
## NotificationSubscribe.removeAll ## NotificationSubscribe.removeAll
......
...@@ -282,6 +282,10 @@ on(type: 'progress', callback:(uploadedSize: number, totalSize: number) =&gt; vo ...@@ -282,6 +282,10 @@ on(type: 'progress', callback:(uploadedSize: number, totalSize: number) =&gt; vo
订阅上传任务进度监听,同步方法,使用callback形式返回结果。 订阅上传任务进度监听,同步方法,使用callback形式返回结果。
> **说明:**
>
> 当应用处于后台时,为满足功耗性能要求,不支持调用此接口进行回调。
**需要权限**:ohos.permission.INTERNET **需要权限**:ohos.permission.INTERNET
**系统能力**: SystemCapability.MiscServices.Upload **系统能力**: SystemCapability.MiscServices.Upload
...@@ -839,6 +843,10 @@ on(type: 'progress', callback:(receivedSize: number, totalSize: number) =&gt; vo ...@@ -839,6 +843,10 @@ on(type: 'progress', callback:(receivedSize: number, totalSize: number) =&gt; vo
订阅下载任务进度监听,同步方法,使用callback形式返回结果。 订阅下载任务进度监听,同步方法,使用callback形式返回结果。
> **说明:**
>
> 当应用处于后台时,为满足功耗性能要求,不支持调用此接口进行回调。
**需要权限**:ohos.permission.INTERNET **需要权限**:ohos.permission.INTERNET
**系统能力**: SystemCapability.MiscServices.Download **系统能力**: SystemCapability.MiscServices.Download
......
...@@ -40,16 +40,34 @@ setDarkMode(mode: DarkMode, callback: AsyncCallback\<void>): void ...@@ -40,16 +40,34 @@ setDarkMode(mode: DarkMode, callback: AsyncCallback\<void>): void
**系统能力:** SystemCapability.ArkUI.UiAppearance **系统能力:** SystemCapability.ArkUI.UiAppearance
**参数:** **参数:**
| 参数名 | 类型 | 必填 | 说明 | | 参数名 | 类型 | 必填 | 说明 |
| -- | -- | -- | -- | | -- | -- | -- | -- |
| mode | [DarkMode](#darkmode) | 是 | 指定系统的深色模式配置 | | mode | [DarkMode](#darkmode) | 是 | 指定系统的深色模式配置 |
| callback | AsyncCallback\<void>| 是 | 配置深色模式的异步回调 | | callback | AsyncCallback\<void>| 是 | 配置深色模式的异步回调 |
**错误码:**
错误码详细介绍请参考[errcode-uiappearance](../errorcodes/errorcode-uiappearance.md)
| 错误码ID | 错误码信息 |
| -- | -- |
| 500001 | Internal error. |
**示例:** **示例:**
```ts ```ts
uiAppearance.setDarkMode(uiAppearance.DarkMode.ALWAYS_DARK, (err) => { try {
console.info(`${err}`); uiAppearance.setDarkMode(uiAppearance.DarkMode.ALWAYS_DARK, (error) => {
}) if (error) {
console.error('Set dark-mode failed, ' + error.message);
} else {
console.info('Set dark-mode successfully.');
}
})
} catch (error) {
console.error('Set dark-mode failed, ' + error.message);
}
``` ```
...@@ -64,6 +82,7 @@ setDarkMode(mode: DarkMode): Promise\<void>; ...@@ -64,6 +82,7 @@ setDarkMode(mode: DarkMode): Promise\<void>;
**系统能力:** SystemCapability.ArkUI.UiAppearance **系统能力:** SystemCapability.ArkUI.UiAppearance
**参数:** **参数:**
| 参数名 | 类型 | 必填 | 说明 | | 参数名 | 类型 | 必填 | 说明 |
| -- | -- | -- | -- | | -- | -- | -- | -- |
| mode | [DarkMode](#darkmode) | 是 | 指定系统深色模式配置 | | mode | [DarkMode](#darkmode) | 是 | 指定系统深色模式配置 |
...@@ -74,13 +93,26 @@ setDarkMode(mode: DarkMode): Promise\<void>; ...@@ -74,13 +93,26 @@ setDarkMode(mode: DarkMode): Promise\<void>;
| ------ | ------------------------------ | | ------ | ------------------------------ |
| Promise\<void> | Promise对象。无返回结果的Promise对象。| | Promise\<void> | Promise对象。无返回结果的Promise对象。|
**错误码:**
错误码详细介绍请参考[errcode-uiappearance](../errorcodes/errorcode-uiappearance.md)
| 错误码ID | 错误码信息 |
| -- | -- |
| 500001 | Internal error. |
**示例:** **示例:**
```ts ```ts
uiAppearance.setDarkMode(uiAppearance.DarkMode.ALWAYS_DARK).then(() => { try {
console.log('Set dark-mode successfully.'); uiAppearance.setDarkMode(uiAppearance.DarkMode.ALWAYS_DARK).then(() => {
}).catch((err) => { console.info('Set dark-mode successfully.');
console.log(`Set dark-mode failed, ${err}`); }).catch((error) => {
}); console.error('Set dark-mode failed, ' + error.message);
});
} catch (error) {
console.error('Set dark-mode failed, ' + error.message);
}
``` ```
...@@ -95,12 +127,26 @@ getDarkMode(): DarkMode; ...@@ -95,12 +127,26 @@ getDarkMode(): DarkMode;
**系统能力:** SystemCapability.ArkUI.UiAppearance **系统能力:** SystemCapability.ArkUI.UiAppearance
**返回值:** **返回值:**
| 类型 | 说明 | | 类型 | 说明 |
| -- | -- | | -- | -- |
|[DarkMode](#darkmode) | 系统当前的深色模式配置 | |[DarkMode](#darkmode) | 系统当前的深色模式配置 |
**错误码:**
错误码详细介绍请参考[errcode-uiappearance](../errorcodes/errorcode-uiappearance.md)
| 错误码ID | 错误码信息 |
| -- | -- |
| 500001 | Internal error. |
**示例:** **示例:**
```ts ```ts
let darkMode = uiAppearance.getDarkMode(); try {
console.log(`Get dark-mode ${darkMode}`); let darkMode = uiAppearance.getDarkMode();
console.info('Get dark-mode ' + mode);
} catch (error) {
console.error('Get dark-mode failed, ' + error.message);
}
``` ```
\ No newline at end of file
...@@ -330,7 +330,7 @@ constructor(name: string, param: unknown) ...@@ -330,7 +330,7 @@ constructor(name: string, param: unknown)
| 名称 | 描述 | | 名称 | 描述 |
| ----- | ---------------------------------------- | | ----- | ---------------------------------------- |
| Stack | 导航栏与内容区独立显示,相当于两个页面。 | | Stack | 导航栏与内容区独立显示,相当于两个页面。 |
| Split | 导航栏与内容区分两栏显示。 | | Split | 导航栏与内容区分两栏显示。<br/>以下navBarWidthRange的值用[minNavBarWidth,maxNavBarWidth]表示<br/>1.当navBarWidth属性的值,在navBarWidthRange属性的值范围以外时,navBarWidth按如下规则显示:<br/>navBarWidth < minNavBarWidth时navBarWidth修正为minNavBarWidth;<br/>navBarWidth > maxNavBarWidth,且组件宽度 - minContentWidth大于maxNavBarWidth时,navBarWidth修正为maxNavBarWidth;<br/>navBarWidth > maxNavBarWidth,且组件宽度 - minContentWidth小于minNavBarWidth时,navBarWidth修正为minNavBarWidth;<br/>navBarWidth > maxNavBarWidth,且组件宽度 - minContentWidth在navBarWidthRange范围内,navBarWidth修正为组件宽度 - minContentWidth。<br/>2.缩小组件尺寸时,先缩小内容区的尺寸至minContentWidth,然后再缩小导航栏的尺寸至minNavBarWidth。若继续缩小,先缩小内容区,内容区消失后再缩小导航栏。<br/>3.设置导航栏为固定尺寸时,若持续缩小组件尺寸,导航栏最后压缩显示。<br/>4.当navBarWidth值与minContentWidth的值相加大于组件尺寸时,会优先显示导航栏。 |
| Auto | API version 9之前:窗口宽度>=520vp时,采用Split模式显示;窗口宽度<520vp时采用Stack模式显示。<br/>API version 10及以上:窗口宽度>=600vp时,采用Split模式显示;窗口宽度<600vp时,采用Stack模式显示,600vp等于minNavBarWidth(240vp) + minContentWidth (360vp)。 | | Auto | API version 9之前:窗口宽度>=520vp时,采用Split模式显示;窗口宽度<520vp时采用Stack模式显示。<br/>API version 10及以上:窗口宽度>=600vp时,采用Split模式显示;窗口宽度<600vp时,采用Stack模式显示,600vp等于minNavBarWidth(240vp) + minContentWidth (360vp)。 |
## TitleHeight枚举说明 ## TitleHeight枚举说明
......
...@@ -97,6 +97,7 @@ Progress(options: {value: number, total?: number, type?: ProgressType}) ...@@ -97,6 +97,7 @@ Progress(options: {value: number, total?: number, type?: ProgressType})
| 名称 | 参数类型 | 必填 | 描述 | | 名称 | 参数类型 | 必填 | 描述 |
| ------------- | ---------------------------- | ---- | ------------------------------------------------------------------------------------------ | | ------------- | ---------------------------- | ---- | ------------------------------------------------------------------------------------------ |
| strokeWidth | [Length](ts-types.md#length) | 否 | 设置进度条宽度(不支持百分比设置)。<br/>默认值:4.0vp | | strokeWidth | [Length](ts-types.md#length) | 否 | 设置进度条宽度(不支持百分比设置)。<br/>默认值:4.0vp |
| strokeRadius | [PX](ts-types.md#px10) \| [VP](ts-types.md#vp10) \| [LPX](ts-types.md#lpx10) \| [Resource](ts-types.md#resource)| 否 | 设置线性进度条圆角半径。<br/>取值范围[0, strokeWidth / 2]。默认值:strokeWidth / 2。 |
| enableScanEffect | boolean | 否 | 进度条扫光效果的开关。<br/>默认值: false | | enableScanEffect | boolean | 否 | 进度条扫光效果的开关。<br/>默认值: false |
| enableSmoothEffect | boolean | 否 | 进度平滑动效的开关。开启平滑动效后设置进度,进度会从当前值渐变至设定值,否则进度从当前值突变至设定值。<br/>默认值:true | | enableSmoothEffect | boolean | 否 | 进度平滑动效的开关。开启平滑动效后设置进度,进度会从当前值渐变至设定值,否则进度从当前值突变至设定值。<br/>默认值:true |
......
...@@ -51,7 +51,7 @@ SideBarContainer( type?: SideBarContainerType ) ...@@ -51,7 +51,7 @@ SideBarContainer( type?: SideBarContainerType )
| autoHide<sup>9+</sup> | boolean | 设置当侧边栏拖拽到小于最小宽度后,是否自动隐藏。<br/>默认值:true<br>**说明:** <br>受minSideBarWidth属性方法影响,minSideBarWidth属性方法未设置值使用默认值。<br/>拖拽过程中判断是否要自动隐藏。小于最小宽度时需要阻尼效果触发隐藏(越界一段距离) | | autoHide<sup>9+</sup> | boolean | 设置当侧边栏拖拽到小于最小宽度后,是否自动隐藏。<br/>默认值:true<br>**说明:** <br>受minSideBarWidth属性方法影响,minSideBarWidth属性方法未设置值使用默认值。<br/>拖拽过程中判断是否要自动隐藏。小于最小宽度时需要阻尼效果触发隐藏(越界一段距离) |
| sideBarPosition<sup>9+</sup> | [SideBarPosition](#sidebarposition9枚举说明) | 设置侧边栏显示位置。<br/>默认值:SideBarPosition.Start | | sideBarPosition<sup>9+</sup> | [SideBarPosition](#sidebarposition9枚举说明) | 设置侧边栏显示位置。<br/>默认值:SideBarPosition.Start |
| divider<sup>10+</sup> | [DividerStyle](#dividerstyle10对象说明) \| null | 设置分割线的样式。<br/>- 默认为DividerStyle:显示分割线。<br/>- null:不显示分割线。 | | divider<sup>10+</sup> | [DividerStyle](#dividerstyle10对象说明) \| null | 设置分割线的样式。<br/>- 默认为DividerStyle:显示分割线。<br/>- null:不显示分割线。 |
| minContentWidth<sup>10+</sup> | [Dimension](ts-types.md#dimension10) | SideBarContainer组件内容区的最小宽度。<br/>默认值:360vp<br/>单位:vp<br/>**说明:** <br/>设置为小于0的值时按默认值显示,未设置时为0vp。<br/>Embed场景下,增大组件尺寸时仅增大内容区的尺寸,缩小组件尺寸时,先缩小内容区的尺寸至minContentWidth,然后再缩小侧边栏的尺寸,当缩小侧边栏的尺寸至minSideBarWidth后,继续缩小组件尺寸时,会保持侧边栏最小尺寸,继续缩小内容区尺寸,并采用截断方式显示内容区,内容区尺寸可以缩小至0vp<br/>minContentWidth优先于侧边栏的maxSideBarWidth与sideBarWidth属性,minContentWidth未设置时默认值优先级低于设置的minSideBarWidth与maxSideBarWidth属性。 | | minContentWidth<sup>10+</sup> | [Dimension](ts-types.md#dimension10) | SideBarContainer组件内容区的最小宽度。<br/>默认值:360vp<br/>单位:vp<br/>**说明:** <br/>设置为小于0的值时按默认值显示,未设置时为0vp。<br/>Embed场景下,增大组件尺寸时仅增大内容区的尺寸<br/>缩小组件尺寸时,先缩小内容区的尺寸至minContentWidth。继续缩小组件尺寸时,保持内容区宽度minContentWidth不变,优先缩小侧边栏的尺寸。<br/>当缩小侧边栏的尺寸至minSideBarWidth后,继续缩小组件尺寸时,<br/>- 如果autoHide属性为false,则会保持侧边栏宽度minSideBarWidth和内容区宽度minContentWidth不变,但内容区会被截断显示;<br/>- 如果autoHide属性为true,则会优先隐藏侧边栏,然后继续缩小至内容区宽度minContentWidth后,内容区宽度保持不变,但内容区会被截断显示<br/>minContentWidth优先于侧边栏的maxSideBarWidth与sideBarWidth属性,minContentWidth未设置时默认值优先级低于设置的minSideBarWidth与maxSideBarWidth属性。 |
## ButtonStyle对象说明 ## ButtonStyle对象说明
......
...@@ -5,7 +5,10 @@ ...@@ -5,7 +5,10 @@
> **说明:** > **说明:**
> >
> 从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 > 从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
>
> 不支持横竖屏切换。 > 不支持横竖屏切换。
>
> 不支持路由跳转。
## 属性 ## 属性
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
> 从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 > 从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
> >
> 不支持横竖屏切换。 > 不支持横竖屏切换。
>
> 不支持路由跳转。
## 属性 ## 属性
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
- [元能力子系统错误码](errorcode-ability.md) - [元能力子系统错误码](errorcode-ability.md)
- [DistributedSchedule错误码](errorcode-DistributedSchedule.md) - [DistributedSchedule错误码](errorcode-DistributedSchedule.md)
- [卡片错误码](errorcode-form.md) - [卡片错误码](errorcode-form.md)
- AI业务
- [智能语音错误码](errorcode-intelligentVoice.md)
- 包管理 - 包管理
- [包管理子系统通用错误码](errorcode-bundle.md) - [包管理子系统通用错误码](errorcode-bundle.md)
- [zlib子系统错误码](errorcode-zlib.md) - [zlib子系统错误码](errorcode-zlib.md)
......
...@@ -644,4 +644,44 @@ Failed to install the HAP because the code signature verification is failed. ...@@ -644,4 +644,44 @@ Failed to install the HAP because the code signature verification is failed.
**处理步骤**<br/> **处理步骤**<br/>
1. 检查代码签名文件对应的module是否包含在安装包路径之中。 1. 检查代码签名文件对应的module是否包含在安装包路径之中。
2. 检查提供的代码签名文件的路径是否合法。 2. 检查提供的代码签名文件的路径是否合法。
3. 使用和安装包匹配的代码签名文件。 3. 使用和安装包匹配的代码签名文件。
\ No newline at end of file
## 17700049 应用自升级时安装的应用与调用方包名不同
**错误信息**<br/>
Failed to install the HAP because the bundleName is different from the bundleName of the caller application.
**错误描述**<br/>
企业mdm应用自升级时,安装的应用与调用方包名不同。
**可能原因**<br/>
1. 要安装的hap或hsp不属于当前应用。
**处理步骤**<br/>
1. 检查要安装的hap或hsp是否属于当前应用。
## 17700050 企业设备校验失败
**错误信息**<br/>
Failed to install the HAP because enterprise normal/MDM bundle cannot be installed on non-enterprise device.
**错误描述**<br/>
安装应用时,企业normal应用或企业mdm应用无法在非企业设备上安装。
**可能原因**<br/>
1. 安装设备不是企业设备。
**处理步骤**<br/>
1. 检查安装设备是否为企业设备。
2. 检查设备参数const.bms.allowenterprisebundle是否为true
## 17700051 应用自升级时安装的应用与调用方包名不同
**错误信息**<br/>
Failed to install the HAP because the distribution type of caller application is not enterprise_mdm.
**错误描述**<br/>
企业mdm应用自升级时,调用方的分发类型不是企业mdm。
**可能原因**<br/>
1. 调用方的分发类型不是企业mdm。
**处理步骤**<br/>
1. 检查应用的签名文件是否正确配置。
# IntelligentVoice错误码
> **说明:**
>
> 以下仅介绍本模块特有错误码,通用错误码请参考[通用错误码说明文档](errorcode-universal.md)。
## 22700101 内存不足
**错误信息**
No memory.
**错误描述**
调用接口时,分配内存失败或者出现空指针。
**可能原因**
1. 系统内存压力大,没有足够的内存用来映射。
2. 对于失效的实例,没有及时销毁释放内存。
**处理步骤**
1. 停止当前操作,或者暂停其他的应用,以保证当前业务有可用内存。
2. 主动清空失效的实例,释放内存后再重新创建实例,仍然失败,则停止相关操作。
## 22700102 无效入参
**错误信息**
Input parameter value error.
**错误描述**
调用接口时,传入的参数无效。
**可能原因**
参数无效,比如值不在边界范围内,没有使用指定的枚举范围等。
**处理步骤**
根据接口文档,传入正确的入参。
## 22700103 初始化失败
**错误信息**
Init failed.
**错误描述**
调用引擎的初始化接口时,返回初始化失败。
**可能原因**
1. 重复初始化。
2. 没有注册初始化所需要的资源。
**处理步骤**
1. 不要重复初始化。
2. 确认注册初始化需要的资源(声学模型文件等)已经完备。
## 22700104 确认注册结果失败
**错误信息**
Commit enroll failed.
**错误描述**
调用注册引擎的确认注册结果接口[commit()](../apis/js-apis-intelligentVoice.md#commit)时,返回失败。
**可能原因**
没有完成指定次数的注册流程。
**处理步骤**
根据界面上要求的注册次数注册完成后再确认注册结果。
# 用户界面外观服务错误码
> **说明:**
>
> 以下仅介绍本模块特有错误码,通用错误码请参考[通用错误码说明文档](errorcode-universal.md)。
## 500001 内部错误
**错误信息**
Internal error.
**错误描述**
当出现了开发者解决不了的内部异常错误,如参数持久化错误,获取服务失败,配置深浅色模式失败等,系统会产生此错误码。
**可能原因**
参数持久化错误,获取服务失败,配置深浅色模式失败等。
**处理步骤**
NA
...@@ -367,6 +367,6 @@ user_grant权限可以通过预授权方式请求权限。预授权方式需要 ...@@ -367,6 +367,6 @@ user_grant权限可以通过预授权方式请求权限。预授权方式需要
针对访问控制,有以下相关实例可供参考: 针对访问控制,有以下相关实例可供参考:
- [AbilityAccessCtrl:访问权限控制(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Security/AbilityAccessCtrl) - [访问权限控制(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Security/AbilityAccessCtrl)
- [为应用添加运行时权限(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Security/AccessPermission) - [为应用添加运行时权限(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Security/AccessPermission)
...@@ -573,3 +573,9 @@ function crlEntrySample() { ...@@ -573,3 +573,9 @@ function crlEntrySample() {
}); });
} }
``` ```
## 相关实例
针对证书开发,有以下相关实例可供参考:
- [证书算法库框架(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Security/CertificateFramework)
\ No newline at end of file
...@@ -2571,4 +2571,10 @@ function doRandBySync() { ...@@ -2571,4 +2571,10 @@ function doRandBySync() {
针对加解密算法开发,有以下相关实例可供参考: 针对加解密算法开发,有以下相关实例可供参考:
- [支付(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Security/PaySecurely)
- [通用密钥库系统(cryptoFramework)(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Security/CryptoFramework)
- [加解密(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Security/Cipher)
- [字符串加解密(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Security/StringCipherArkTS) - [字符串加解密(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Security/StringCipherArkTS)
...@@ -86,3 +86,7 @@ ...@@ -86,3 +86,7 @@
## 读取已安装应用列表 ## 读取已安装应用列表
- ohos.permission.GET_INSTALLED_BUNDLE_LIST - ohos.permission.GET_INSTALLED_BUNDLE_LIST
## 蓝牙
- ohos.permission.ACCESS_BLUETOOTH
...@@ -194,4 +194,8 @@ ...@@ -194,4 +194,8 @@
基于代理提醒,有以下相关实例可供参考: 基于代理提醒,有以下相关实例可供参考:
- [后台代理提醒(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/ReminderAgentManager)
- [翻页闹钟(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Tools/FlipClock)
- [闹钟(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/CommonEventAndNotification/AlarmClock) - [闹钟(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/CommonEventAndNotification/AlarmClock)
\ No newline at end of file
...@@ -475,4 +475,4 @@ ...@@ -475,4 +475,4 @@
针对长时任务开发,有以下相关实例可供参考: 针对长时任务开发,有以下相关实例可供参考:
- [ContinuousTask:长时任务(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/ContinuousTask) - [长时任务(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/ContinuousTask)
\ No newline at end of file \ No newline at end of file
...@@ -97,4 +97,4 @@ ...@@ -97,4 +97,4 @@
针对短时任务开发,有以下相关实例可供参考: 针对短时任务开发,有以下相关实例可供参考:
- [短时任务(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/TransientTask) - [短时任务(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/TransientTask)
\ No newline at end of file \ No newline at end of file
...@@ -210,4 +210,4 @@ WorkInfo参数用于设置应用条件,参数设置时需遵循以下规则: ...@@ -210,4 +210,4 @@ WorkInfo参数用于设置应用条件,参数设置时需遵循以下规则:
针对延迟任务调度的开发,有以下相关示例可供参考: 针对延迟任务调度的开发,有以下相关示例可供参考:
- [WorkScheduler的创建与使用(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/WorkScheduler) - [延迟任务调度(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/WorkScheduler)
\ No newline at end of file \ No newline at end of file
...@@ -111,6 +111,6 @@ observer模块为开发者提供订阅和取消订阅通话业务状态的功能 ...@@ -111,6 +111,6 @@ observer模块为开发者提供订阅和取消订阅通话业务状态的功能
## 相关实例 ## 相关实例
拨打电话有以下相关实例可供参考: 针对拨打电话,有以下相关实例可供参考:
- [拨打电话](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Telephony/Call) - [拨打电话(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Telephony/Call)
...@@ -115,4 +115,5 @@ ...@@ -115,4 +115,5 @@
## 相关实例 ## 相关实例
针对短信的使用,有以下相关实例可供参考: 针对短信的使用,有以下相关实例可供参考:
- [短信服务](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Telephony/Message)
- [短信服务(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Telephony/Message)
...@@ -326,3 +326,243 @@ bm dump-shared -n com.ohos.lib ...@@ -326,3 +326,243 @@ bm dump-shared -n com.ohos.lib
# 显示指定应用指定模块依赖的共享库信息 # 显示指定应用指定模块依赖的共享库信息
bm dump-dependencies -n com.ohos.app -m entry bm dump-dependencies -n com.ohos.app -m entry
``` ```
## 常见问题
### 安装HAP时提示“code:9568320 error: no signature file”
**问题现象**
对HAP包签名后,在设备中运行HAP时提示“failed to install bundle. error: install no signature info”或“failed to install bundle. error: no signature file”。
![示例图](figures/zh-cn_image_0000001389116960.png)
**解决措施**
该问题是由于签名工具与设备运行的镜像版本不匹配导致,需要开发者手动更新设备的镜像,可参考如下步骤进行更新。
1. 获取[OpenHarmony 最新镜像文件](https://gitee.com/openharmony/docs/blob/master/zh-cn/release-notes/Readme.md),下载对应开发板的镜像文件。
2. 将下载的镜像文件烧录到开发板中,关于各开发板的烧录,可以使用DevEco Device Tool工具进行烧录,具体请参考[DevEco Device Tool使用指南](../../device-dev/quick-start/quickstart-ide-env-win.md)
3. 重新运行应用/服务。
### 安装HAP时提示“code:9568347 error: install parse native so failed”错误
**问题现象**
在启动调试或运行C++应用/服务时,安装HAP出现错误,提示“error: install parse native so failed”错误信息。
**解决措施**
该问题可能是由于设备支持的Abi类型与C++工程中配置的Abi类型不匹配,请通过如下步骤进行解决。
1. 将设备与DevEco Studio进行连接。
2. 打开命令行工具,并进入SDK安装目录下的toolchains\{版本号}目录下。
```
若不清楚OpenHarmony SDK安装目录,可单击File > Settings > SDK界面查看安装路径。
```
3. 执行如下命令,查询设备支持的Abi列表,返回结果为default/armeabi-v7a/armeabi/arm64-v8a/x86/x86_64中的一个或多个Abi类型。
```
hdc shell
param get const.product.cpu.abilist
```
4. 根据查询返回结果,检查[模块级build-profile.json5](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/build_config-0000001052902431-V3#section6887184182020)文件中的“abiFilters”参数中的配置,规则如下:
* 若返回结果为default,请执行如下命令,查询是否存在lib64文件夹。
```
cd /system/
ls
```
![示例图](figures/zh-cn_image_0000001609001262.png)
* 存在lib64文件夹:则“abiFilters”参数中需要包含arm64-v8a类型。
* 不存在lib64文件夹:则“abiFilters”参数中需要至少包含armeabi/armeabi-v7a中的一个类型。
* 若返回结果为armeabi-v7a/armeabi/arm64-v8a/x86/x86_64中的一个或多个,需要在“abiFilters”参数中至少包含返回结果中的一个Abi类型。
### 安装HAP时提示“code:9568344 error: install parse profile prop check error”错误
**问题现象**
在启动调试或运行应用/服务时,安装HAP出现错误,提示“error: install parse profile prop check error”错误信息。
![示例图](figures/zh-cn_image_0000001585361412.png)
**解决措施**
该问题可能是由于应用使用了应用特权,但应用的签名文件发生变化后未将新的签名指纹重新配置到设备的特权管控白名单文件install_list_capability.json中,请通过如下步骤进行解决。
1. 获取新的签名指纹。
a. 在项目级build-profile.json5文件中,signingConfigs字段内的profile的值即为签名文件的存储路径。
b. 打开该签名文件(后缀为.p7b),打开后在文件内搜索“development-certificate”,将“-----BEGIN CERTIFICATE-----”和“-----END CERTIFICATE-----”以及中间的信息拷贝到新的文本中,注意换行并去掉换行符,保存为一个新的.cer文件,如命名为xxx.cer。
新的.cer文件格式如下图(仅作为格式示意,内容以实际为准):
![示例图](figures/zh-cn_image_0000001585521364.png)
c. 使用keytool工具(在DevEco Studio安装目录下的jbr/bin文件夹内),执行如下命令通过.cer文件获取证书指纹的SHA256值。
```
keytool -printcert -file xxx.cer
```
d. 将证书指纹中SHA256的内容去掉冒号,即为最终要获得的签名指纹。
如SHA256值为下图(仅作为格式示意,内容以实际为准):
![示例图](figures/zh-cn_image_0000001635921233.png)
去掉冒号后的签名指纹为:5753DDBC1A8EF88A62058A9FC4B6AFAFC1C5D8D1A1B86FB3532739B625F8F3DB
2. 获取设备的特权管控白名单文件install_list_capability.json。
a. 连接设备。
b. 执行如下命令查看设备的特权管控白名单文件install_list_capability.json。
```
find /system -name install_list_capability.json
```
HarmonyOS设备上install_list_capability.json的位置通常为以下几种,选取其中一个即可:
```
/system/variant/phone/base/etc/app/install_list_capability.json
/system/etc/app/install_list_capability.json
```
OpenHarmony设备上install_list_capability.json的位置通常为:
```
/system/etc/app/install_list_capability.json
```
c. 执行如下命令拉取install_list_capability.json。
```
hdc shell mount -o rw,remount /
hdc file recv /system/variant/phone/base/etc/app/install_list_capability.json
```
3. 将步骤1获取到的签名指纹配置到install_list_capability.json文件的app_signature中,注意要配置到对应的bundleName下。
![示例图](figures/zh-cn_image_0000001635641893.png)
4. 将修改后的install_list_capability.json文件重新推到设备上,并重启设备。
```
hdc shell mount -o rw,remount /
hdc file send install_list_capability.json /system/variant/phone/base/etc/app/install_list_capability.json
hdc shell chmod 777 /system/variant/phone/base/etc/app/install_list_capability.json
hdc shell reboot
```
5. 设备重启后,重新安装新的应用即可。
### 安装HAP时提示“code:9568305 error: dependent module does not exist”错误
**问题现象**
在启动调试或运行应用/服务时,安装HAP出现错误,提示“error: dependent module does not exist”错误信息。
![示例图](figures/zh-cn_image_0000001560338986.png)
**解决措施**
该问题是由于运行/调试的应用依赖的动态共享包(SharedLibrary)模块未安装导致安装报错,您可以通过如下方式进行解决:
* 先安装依赖的动态共享包(SharedLibrary)模块,再在应用运行配置页勾选Keep Application Data,点击OK保存配置,再运行/调试。
![示例图](figures/zh-cn_image_0000001560201786.png)
* 在运行配置页,选择Deploy Multi Hap标签页,勾选Deploy Multi Hap Packages,选择依赖的模块,点击OK保存配置,再进行运行/调试。
![示例图](figures/zh-cn_image_0000001610761941.png)
### 安装HAP时提示“code:9568259 error: install parse profile missing prop”
**问题现象**
在启动调试或运行应用/服务时,安装HAP出现错误,提示“error: install parse profile missing prop”错误信息。
![示例图](figures/zh-cn_image_0000001559130596.png)
**解决措施**
出现该问题的原因是配置文件app.json5和module.json5中必填字段缺失。
* 方法1:请参考[app.json5配置文件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/app-configuration-file-0000001558277229-V3)[module.json5配置文件](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/module-configuration-file-0000001506957668-V3)查看并补充必填字段。
* 方法2:通过hilog日志判断缺失字段。
开启落盘命令:
```
hilog -w start
```
落盘位置:/data/log/hilog
打开日志查看“profile prop %{public}s is mission”。如“profile prop icon is mission”表示“icon”字段缺失。
### 安装HAP时提示“code:9568258 error: install releaseType target not same”
**问题现象**
在启动调试或运行应用/服务时,安装HAP出现错误,提示“error: install releaseType target not same”错误信息。
![示例图](figures/zh-cn_image_0000001609976041.png)
**解决措施**
出现该问题的原因是设备上已安装的旧HAP和现在要安装的新HAP所使用的SDK中的releaseType值不一样。请先卸载设备上已安装的HAP,再安装新的HAP。
### 安装HAP时提示“code:9568322 error: signature verification failed due to not trusted app source”
**问题现象**
在启动调试或运行应用/服务时,安装HAP出现错误,提示“error: signature verification failed due to not trusted app source”错误信息。
![示例图](figures/zh-cn_image_0000001585042216.png)
**解决措施**
该问题是由于签名中未包含该调试设备的UDID,请通过如下步骤进行解决。
* 使用[自动签名](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/signing-0000001587684945-V3#section18815157237)。在连接设备后,重新为应用进行签名。
* 如果使用的是手动签名,对于HarmonyOS应用,请在AppGallery Connect中先将该调试设备[注册调试设备](https://developer.huawei.com/consumer/cn/doc/distribution/app/agc-help-harmonyos-debugapp-manual-0000001177608893#section7732152932911)并在[申请Profile文件](https://developer.huawei.com/consumer/cn/doc/distribution/app/agc-help-harmonyos-debugapp-manual-0000001177608893?ha_linker=eyJ0cyI6MTY4NzkzNDEzOTk1OSwiaWQiOiJhZjdhYzI0MDlkMGQ5MzQ1MzFlNDE3NDQ5MmY4MjJkMyJ9#section1774717395304)选择设备时添加该调试设备,重新申请Profile证书;对于OpenHarmony应用,请参考[OpenHarmony应用手动签名](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/hapsigntool-guidelines.md),在UnsgnedDebugProfileTemplate.json文件中添加该调试设备的[UDID](https://developer.huawei.com/consumer/cn/doc/distribution/app/agc-help-harmonyos-debugapp-manual-0000001177608893#section1835412326017)
### 安装HAP时提示“code:9568289 error: install failed due to grant request permissions failed”
**问题现象**
在启动调试或运行应用/服务时,安装HAP出现错误,提示“error: install failed due to grant request permissions failed”错误信息。
![示例图](figures/zh-cn_image_0000001585201996.png)
**解决措施**
该问题是由于默认应用等级为normal,只能使用normal等级的权限,如果使用了system_basic或system_core等级的权限,将导致报错。
对于HarmonyOS应用,请参考[使用ACL签名配置指导](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/signing-0000001587684945-V3?catalogVersion=V3#section157591551175916)完成ACL提权;对于OpenHarmony应用,请参考[修改应用权限等级](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ohos-auto-configuring-signature-information-0000001271659465#section42735161005)修改签名模板。
### 安装HAP时提示“code:9568297 error: install failed due to older sdk version in the device”
**问题现象**
在启动调试或运行应用/服务时,安装HAP出现错误,提示“error: install failed due to older sdk version in the device”错误信息。
![示例图](figures/zh-cn_image_0000001635521909.png)
**解决措施**
该问题是由于编译打包所使用的SDK版本与设备镜像版本不匹配。不匹配的场景包括:
* 场景一:设备上的镜像版本低于编译打包的SDK版本,请更新设备镜像版本。查询设备镜像版本命令:
```
hdc shell param get const.ohos.apiversion
```
如果镜像提供的api版本为10,且应用编译所使用的SDK版本也为10,仍出现该报错,可能是由于镜像版本较低,未兼容新版本SDK校验规则,请将镜像版本更新为最新版本。
* 场景二:对于需要运行在OpenHarmony设备上的应用,请确认runtimeOS已改为OpenHarmony。
### 安装HAP时提示“code:9568332 error: install sign info inconsistent”
**问题现象**
在启动调试或运行应用/服务时,安装HAP出现错误,提示“error: install sign info inconsistent”错误信息。
![示例图](figures/zh-cn_image_0000001635761329.png)
**解决措施**
该问题是由于设备上已安装的应用与新安装的应用中签名不一致。如果在**Edit Configurations**中勾选了“Keep Application Data”(不卸载应用,覆盖安装),并且重新进行了签名,将导致该报错。
请卸载设备上已安装的应用,或取消勾选“Keep Application Data”后,重新安装新的应用。
### 安装HAP时提示“code:9568257 error: fail to verify pkcs7 file”
**问题现象**
在启动调试或者运行应用/服务时,安装HAP出现错误,提示”error: fail to verify pkcs7 file“错误信息。
![示例图](figures/zh-cn_image_00000016359212344.png)
**解决措施**
出现该问题的原因是应用当前使用的签名不符合HarmonyOS应用签名的要求。通常是由于当前使用的是OpenHarmony应用的签名,需替换为HarmonyOS应用的签名。
请在[为应用/服务签名](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/signing-0000001587684945-V3)时勾选”Support HarmonyOS“,完成HarmonyOS应用签名后再次启动调试或者运行应用。
![示例图](figures/zh-cn_image_00000016359212311.png)
\ No newline at end of file
...@@ -271,4 +271,6 @@ Video组件已经封装好了视频播放的基础能力,开发者无需进行 ...@@ -271,4 +271,6 @@ Video组件已经封装好了视频播放的基础能力,开发者无需进行
针对Video组件开发,有以下相关实例可供参考: 针对Video组件开发,有以下相关实例可供参考:
- [视频播放(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/VideoShow)
- [简易视频播放器(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/SimpleVideo) - [简易视频播放器(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/SimpleVideo)
\ No newline at end of file
...@@ -306,3 +306,9 @@ struct TouchExample { ...@@ -306,3 +306,9 @@ struct TouchExample {
![zh-cn_image_0000001511900468](figures/zh-cn_image_0000001511900468.gif) ![zh-cn_image_0000001511900468](figures/zh-cn_image_0000001511900468.gif)
## 相关实例
针对触屏事件开发,有以下相关实例可供参考:
- [拖拽事件(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/Drag)
\ No newline at end of file
...@@ -346,6 +346,12 @@ OffscreenCanvasRenderingContext2D对象和CanvasRenderingContext2D对象提供 ...@@ -346,6 +346,12 @@ OffscreenCanvasRenderingContext2D对象和CanvasRenderingContext2D对象提供
使用画布绘制自定义图形,有以下相关实例可供参考: 使用画布绘制自定义图形,有以下相关实例可供参考:
- [画布组件(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/Canvas)
- [分布式五子棋(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Game/DistributedDataGobang)
- [ArkTS时钟(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Tools/ArkTSClock)
- [Lottie动画](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Game/Lottie) - [Lottie动画](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Game/Lottie)
- [自定义抽奖转盘(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/CanvasComponent) - [自定义抽奖转盘(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/CanvasComponent)
\ No newline at end of file
...@@ -334,6 +334,8 @@ Grid() { ...@@ -334,6 +334,8 @@ Grid() {
## 相关实例 ## 相关实例
如需详细了解网格布局的实现,请参考以下示例: 针对网格开发,有以下相关实例可供参考:
- [游戏2048(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Game/Game2048)
- [分布式计算器](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/ArkTSDistributedCalc) - [分布式计算器](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/ArkTSDistributedCalc)
...@@ -258,6 +258,6 @@ struct MediaQueryExample { ...@@ -258,6 +258,6 @@ struct MediaQueryExample {
## 相关实例 ## 相关实例
基于媒体查询,可参考以下实例 针对媒体查询开发,有以下相关实例可供参考
[媒体查询](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/MediaQuery):使用媒体查询,完成在不同设备上显示不同的界面效果。 - [横竖屏切换(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/MediaQuery)
...@@ -82,6 +82,8 @@ position、offset等属性影响了布局容器相对于自身或其他组件的 ...@@ -82,6 +82,8 @@ position、offset等属性影响了布局容器相对于自身或其他组件的
针对布局开发,有以下相关实例可供参考: 针对布局开发,有以下相关实例可供参考:
- [页面布局和连接(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/DefiningPageLayoutAndConnection)
- [ArkUI常用布局容器对齐方式(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/OHLayoutAlign) - [ArkUI常用布局容器对齐方式(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/OHLayoutAlign)
- [常用组件与布局(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/ArkTSComponents) - [常用组件与布局(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/ArkTSComponents)
\ No newline at end of file
...@@ -387,3 +387,8 @@ struct Index { ...@@ -387,3 +387,8 @@ struct Index {
} }
``` ```
## 相关实例
针对页面路由开发,有以下相关实例可供参考:
- [页面布局和连接(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/DefiningPageLayoutAndConnection)
\ No newline at end of file
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
基于ArkTS的声明式开发范式,可参考以下实例: 基于ArkTS的声明式开发范式,可参考以下实例:
- [ArkTS组件集](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/ComponentCollection):组件、通用方法、动画、全局方法的集合。 - [ArkTS组件集(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/ComponentCollection)
- [像素转换(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/PixelConversion) - [像素转换(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/PixelConversion)
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
针对组件开发,有以下相关实例可供参考: 针对组件开发,有以下相关实例可供参考:
- [`JsComponentCollection`:组件集合(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection) - [JS组件集(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection)
- [rating组件的使用(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/RatingApplication) - [rating组件的使用(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/RatingApplication)
......
...@@ -146,7 +146,7 @@ export default { ...@@ -146,7 +146,7 @@ export default {
针对Canvas开发,有以下相关实例可供参考: 针对Canvas开发,有以下相关实例可供参考:
- [`JsComponentCollection`:JS组件集合(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection) - [JS组件集(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection)
- [自定义抽奖转盘(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/JSCanvasComponent) - [自定义抽奖转盘(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/JSCanvasComponent)
......
...@@ -217,7 +217,7 @@ export default{ ...@@ -217,7 +217,7 @@ export default{
针对slider开发,有以下相关实例可供参考: 针对slider开发,有以下相关实例可供参考:
- [`JsComponentCollection`:JS组件集合(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection) - [JS组件集(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection)
- [slider组件的使用(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/SliderApplication) - [slider组件的使用(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/SliderApplication)
......
...@@ -370,6 +370,6 @@ export default { ...@@ -370,6 +370,6 @@ export default {
针对swiper开发,有以下相关实例可供参考: 针对swiper开发,有以下相关实例可供参考:
- [`JsComponentCollection`:JS组件集合(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection) - [JS组件集(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection)
- [简易视频播放器(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/VideoOpenHarmony) - [简易视频播放器(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/VideoOpenHarmony)
...@@ -28,11 +28,3 @@ ...@@ -28,11 +28,3 @@
- **Porting Layer** - **Porting Layer**
适配层主要完成对平台层进行抽象,提供抽象接口,可以对接到系统平台。比如:事件对接、渲染管线对接和系统生命周期对接等。 适配层主要完成对平台层进行抽象,提供抽象接口,可以对接到系统平台。比如:事件对接、渲染管线对接和系统生命周期对接等。
## 相关实例
兼容JS的类Web开发范式的方舟开发框架,有以下相关实例可供参考:
- [`JsComponentCollection`:JS组件集合(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection)
...@@ -46,3 +46,9 @@ ...@@ -46,3 +46,9 @@
} }
} }
``` ```
## 相关实例
针对Web组件开发,有以下相关实例可供参考:
- [JS注入与执行(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Web/RunJsInWeb)
\ No newline at end of file
...@@ -138,3 +138,9 @@ struct WebComponent { ...@@ -138,3 +138,9 @@ struct WebComponent {
} }
} }
``` ```
## 相关实例
针对Web组件开发,有以下相关实例可供参考:
- [浏览器(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Web/Browser)
\ No newline at end of file
...@@ -372,4 +372,6 @@ export default class EntryAbility extends UIAbility { ...@@ -372,4 +372,6 @@ export default class EntryAbility extends UIAbility {
- [`Window`:一多设置典型页面(Settings)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/Settings) - [`Window`:一多设置典型页面(Settings)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/Settings)
- [`WindowManage`:窗口管理(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/WindowManagement/WindowManage) - [窗口管理(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/WindowManagement/WindowManage)
\ No newline at end of file
- [窗口(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/WindowManagement/WindowRatio)
\ No newline at end of file
...@@ -8,9 +8,10 @@ ...@@ -8,9 +8,10 @@
移植LCD驱动的主要工作是编写一个驱动,在驱动中生成模型的实例,并完成注册。 移植LCD驱动的主要工作是编写一个驱动,在驱动中生成模型的实例,并完成注册。
这些LCD的驱动被放置在源码目录//drivers/hdf_core/framework/model/display/driver/panel中。 这些LCD的驱动被放置在源码目录`//drivers/hdf_core/framework/model/display/driver/panel`中。
1. 创建Panel驱动 1. 创建Panel驱动
创建HDF驱动,在驱动初始化中调用RegisterPanel接口注册模型实例。如: 创建HDF驱动,在驱动初始化中调用RegisterPanel接口注册模型实例。如:
...@@ -36,7 +37,8 @@ ...@@ -36,7 +37,8 @@
``` ```
2. 配置加载panel驱动 2. 配置加载panel驱动
产品的所有设备信息被定义在源码文件//vendor/vendor_name/product_name/config/device_info/device_info.hcs中。修改该文件,在display的host中,名为device_lcd的device中增加配置。
产品的所有设备信息被定义在源码文件`//vendor/vendor_name/product_name/config/device_info/device_info.hcs`中。修改该文件,在display的host中,名为device_lcd的device中增加配置。
> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:** > ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:**
> moduleName 要与panel驱动中的moduleName相同。 > moduleName 要与panel驱动中的moduleName相同。
...@@ -61,12 +63,13 @@ ...@@ -61,12 +63,13 @@
## TP驱动移植 ## TP驱动移植
本节描述如何移植触摸屏驱动。触摸屏的器件驱动被放置在源码目录//drivers/hdf_core/framework/model/input/driver/touchscreen中。 移植触摸屏驱动主要工作是向系统注册ChipDevice模型实例。 本节描述如何移植触摸屏驱动。触摸屏的器件驱动被放置在源码目录`//drivers/hdf_core/framework/model/input/driver/touchscreen`中。 移植触摸屏驱动主要工作是向系统注册ChipDevice模型实例。
详细的驱动开发指导,请参考 [TOUCHSCREEN开发指导](../driver/driver-peripherals-touch-des.md) 详细的驱动开发指导,请参考 [TOUCHSCREEN开发指导](../driver/driver-peripherals-touch-des.md)
1. 创建触摸屏器件驱动 1. 创建触摸屏器件驱动
在上述touchscreen目录中创建名为touch_ic_name.c的文件。编写如下内容
在上述touchscreen目录中创建名为`touch_ic_name.c`的文件。编写如下内容
``` ```
...@@ -103,21 +106,22 @@ ...@@ -103,21 +106,22 @@
| int32_t&nbsp;(\*UpdateFirmware)(ChipDevice&nbsp;\*device) | 实现固件升级 | | int32_t&nbsp;(\*UpdateFirmware)(ChipDevice&nbsp;\*device) | 实现固件升级 |
2. 配置产品,加载器件驱动 2. 配置产品,加载器件驱动
产品的所有设备信息被定义在源码文件//vendor/vendor_name/product_name/config/device_info/device_info.hcs中。修改该文件,在名为input的host中,名为device_touch_chip的device中增加配置。
产品的所有设备信息被定义在源码文件`//vendor/vendor_name/product_name/config/device_info/device_info.hcs`中。修改该文件,在名为input的host中,名为device_touch_chip的device中增加配置。
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> moduleName 要与触摸屏驱动中的moduleName相同。 > moduleName 要与触摸屏驱动中的moduleName相同。
``` ```
deviceN :: deviceNode { deviceN :: deviceNode {
policy = 0; policy = 0;
priority = 130; priority = 130;
preload = 0; preload = 0;
permission = 0660; permission = 0660;
moduleName = "HDF_TOUCH_XXXX"; moduleName = "HDF_TOUCH_XXXX";
deviceMatchAttr = "touch_XXXX_configs"; deviceMatchAttr = "touch_XXXX_configs";
} }
``` ```
...@@ -126,6 +130,7 @@ ...@@ -126,6 +130,7 @@
WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负责处理WLAN流量。 WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负责处理WLAN流量。
**图1** OpenHarmony WLAN结构示意图 **图1** OpenHarmony WLAN结构示意图
![zh-cn_image_0000001207756867](figures/zh-cn_image_0000001207756867.png) ![zh-cn_image_0000001207756867](figures/zh-cn_image_0000001207756867.png)
如图1,左半部分负责管理WLAN设备,右半部分负责WLAN流量。HDF WLAN分别为这两部分做了抽象,驱动的移植过程可以看做分别实现这两部分所需接口。这些接口有: 如图1,左半部分负责管理WLAN设备,右半部分负责WLAN流量。HDF WLAN分别为这两部分做了抽象,驱动的移植过程可以看做分别实现这两部分所需接口。这些接口有:
...@@ -141,8 +146,9 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负 ...@@ -141,8 +146,9 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负
具体的移植步骤如下: 具体的移植步骤如下:
1. 创建HDF WLAN 芯片驱动 1. 创建HDF WLAN芯片驱动
在目录/device/vendor_name/peripheral/wifi/chip_name/ 创建文件 hdf_wlan_chip_name.c。内容模板如下:
在目录`/device/vendor_name/peripheral/wifi/chip_name/`创建文件`hdf_wlan_chip_name.c`。内容模板如下:
``` ```
...@@ -166,7 +172,7 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负 ...@@ -166,7 +172,7 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负
HDF_INIT(g_hdfXXXChipEntry); HDF_INIT(g_hdfXXXChipEntry);
``` ```
在上述代码的CreateChipDriverFactory方法中,需要创建一个HdfChipDriverFactory类型的对象。该对象提供如下方法 在上述代码的CreateChipDriverFactory方法中,需要创建一个HdfChipDriverFactory类型的对象。该对象提供如下方法
| 接口 | 说明 | | 接口 | 说明 |
| -------- | -------- | | -------- | -------- |
...@@ -178,7 +184,7 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负 ...@@ -178,7 +184,7 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负
| void&nbsp;(\*Release)(struct&nbsp;HdfChipDriver&nbsp;\*chipDriver) | 释放chipDriver | | void&nbsp;(\*Release)(struct&nbsp;HdfChipDriver&nbsp;\*chipDriver) | 释放chipDriver |
| uint8_t&nbsp;(\*GetMaxIFCount)(struct&nbsp;HdfChipDriverFactory&nbsp;\*factory) | 获取当前芯片支持的最大接口数 | | uint8_t&nbsp;(\*GetMaxIFCount)(struct&nbsp;HdfChipDriverFactory&nbsp;\*factory) | 获取当前芯片支持的最大接口数 |
其中Build方法负责创建一个管理指定网络接口的对象HdfChipDriver 。该对象需要提供方法: 其中Build方法负责创建一个管理指定网络接口的对象HdfChipDriver。该对象需要提供方法:
| 接口 | 说明 | | 接口 | 说明 |
| -------- | -------- | | -------- | -------- |
...@@ -189,7 +195,8 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负 ...@@ -189,7 +195,8 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负
| struct&nbsp;HdfMac80211APOps&nbsp;\*apOps | 支持AP模式所需要的接口集 | | struct&nbsp;HdfMac80211APOps&nbsp;\*apOps | 支持AP模式所需要的接口集 |
2. 编写配置文件描述驱动支持的芯片 2. 编写配置文件描述驱动支持的芯片
在产品配置目录下创建芯片的配置文件,保存至源码路径//vendor/vendor_name/product_name/config/wifi/wlan_chip_chip_name.hcs
在产品配置目录下创建芯片的配置文件,保存至源码路径`//vendor/vendor_name/product_name/config/wifi/wlan_chip_chip_name.hcs`
该文件模板如下: 该文件模板如下:
...@@ -212,29 +219,32 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负 ...@@ -212,29 +219,32 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负
``` ```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 路径和文件中的vendor_name、product_name、chip_name请替换成实际名称 >
> 路径和文件中的vendor_name、product_name、chip_name请替换成实际名称。
> >
> vendorId 和 deviceId需要根据实际芯片的识别码进行填写。 > vendorId 和 deviceId需要根据实际芯片的识别码进行填写。
3. 编写配置文件,加载驱动 3. 编写配置文件,加载驱动
产品的所有设备信息被定义在源码文件//vendor/vendor_name/product_name/config/device_info/device_info.hcs中。修改该文件,在名为network的host中,名为device_wlan_chips的device中增加配置。模板如下:
产品的所有设备信息被定义在源码文件`//vendor/vendor_name/product_name/config/device_info/device_info.hcs`中。修改该文件,在名为network的host中,名为device_wlan_chips的device中增加配置。模板如下:
``` ```
deviceN :: deviceNode { deviceN :: deviceNode {
policy = 0; policy = 0;
preload = 2; preload = 2;
moduleName = "HDF_WLAN_CHIPS"; moduleName = "HDF_WLAN_CHIPS";
deviceMatchAttr = "hdf_wlan_chips_chip_name"; deviceMatchAttr = "hdf_wlan_chips_chip_name";
serviceName = "driverName"; serviceName = "driverName";
} }
``` ```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> moduleName 要与HDF WLAN 芯片驱动中的moduleName相同。 > moduleName 要与HDF WLAN 芯片驱动中的moduleName相同。
4. 修改Kconfig文件,让移植的WLAN模组出现再内核配置中 4. 修改Kconfig文件,让移植的WLAN模组出现再内核配置中
在device/vendor_name/drivers/Kconfig中增加配置菜单,模板如下
`device/vendor_name/drivers/Kconfig`中增加配置菜单,模板如下
``` ```
...@@ -246,10 +256,11 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负 ...@@ -246,10 +256,11 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负
``` ```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 请替换模板中的chip_name为实际的芯片名称 > 请替换模板中的chip_name为实际的芯片名称
5. 修改构建脚本,让驱动参与内核构建 5. 修改构建脚本,让驱动参与内核构建
在源码文件//device/vendor_name/drivers/lite.mk末尾追加如下内容
在源码文件`//device/vendor_name/drivers/lite.mk`末尾追加如下内容。
``` ```
...@@ -262,4 +273,4 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负 ...@@ -262,4 +273,4 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负
``` ```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:**
> 请替换模板中的chip_name为实际的芯片名称 > 请替换模板中的chip_name为实际的芯片名称
...@@ -8,7 +8,7 @@ Linux内核移植主要涉及基于linux内核基线合入三方芯片补丁后 ...@@ -8,7 +8,7 @@ Linux内核移植主要涉及基于linux内核基线合入三方芯片补丁后
### 基本信息 ### 基本信息
当前Linux内核基线是基于Linux社区 4.19 LTS版本演进,合入CVE及bugfix补丁。具体信息参考[代码库](https://gitee.com/openharmony/kernel_linux),对应repo工程代码路径为kernel/linux-4.19 当前Linux内核基线是基于Linux社区 4.19 LTS版本演进,合入CVE及bugfix补丁。具体信息参考[代码库](https://gitee.com/openharmony/kernel_linux),对应repo工程代码路径为`kernel/linux-4.19`
### Bootloader ### Bootloader
...@@ -19,17 +19,20 @@ Linux内核移植主要涉及基于linux内核基线合入三方芯片补丁后 ...@@ -19,17 +19,20 @@ Linux内核移植主要涉及基于linux内核基线合入三方芯片补丁后
## 适配编译和烧录启动 ## 适配编译和烧录启动
1. 准备内核config(特别是芯片相关的config)。 1. 准备内核config(特别是芯片相关的config)。
config文件所在源码目录:kernel/linux/config/
以hi3516dv300芯片为例,可在对应的linux-4.19/arch/arm/configs/目录下新建&lt;YOUR_CHIP&gt;_small_defconfig,如hi3516dv300_small_defconfig表示针对hi3516dv300小型系统的defconfig。该config文件可以由基础defconfig文件small_common_defconfig与该芯片相关的config组合生成。 config文件所在源码目录:`kernel/linux/config/`
以hi3516dv300芯片为例,可在对应的`linux-4.19/arch/arm/configs/`目录下新建&lt;YOUR_CHIP&gt;_small_defconfig,如`hi3516dv300_small_defconfig`表示针对hi3516dv300小型系统的defconfig。该config文件可以由基础defconfig文件`small_common_defconfig`与该芯片相关的config组合生成。
2. 准备芯片补丁。 2. 准备芯片补丁。
补丁文件所在源码目录:kernel/linux/patches/linux-4.19
补丁文件所在源码目录:`kernel/linux/patches/linux-4.19`
以hi3516dv300芯片为例,参考已有的patch目录hi3516dv300_small_patch目录,新建&lt;YOUR_CHIP&gt;_patch目录,放置相关芯片补丁,注意hdf.patch等驱动补丁。 以hi3516dv300芯片为例,参考已有的patch目录hi3516dv300_small_patch目录,新建&lt;YOUR_CHIP&gt;_patch目录,放置相关芯片补丁,注意hdf.patch等驱动补丁。
3. 编译。 3. 编译。
具体内核编译入口脚本位于工程目录kernel/linux/patches/下面,版本级整编命令会通过BUILD.gn进入kernel_module_build.sh和kernel.mk,需要在这2个文件中针对性进行patch及defconfig文件路径、编译器、芯片架构、内核Image格式等的适配。
具体内核编译入口脚本位于工程目录`kernel/linux/patches/`下面,版本级整编命令会通过BUILD.gn进入`kernel_module_build.sh``kernel.mk`,需要在这2个文件中针对性进行patch及defconfig文件路径、编译器、芯片架构、内核Image格式等的适配。
通过编译错误日志调整补丁,典型错误场景: 通过编译错误日志调整补丁,典型错误场景:
...@@ -38,11 +41,12 @@ Linux内核移植主要涉及基于linux内核基线合入三方芯片补丁后 ...@@ -38,11 +41,12 @@ Linux内核移植主要涉及基于linux内核基线合入三方芯片补丁后
(2)编译失败,内核版本差异(函数实现调整等)需要针对性进行内核适配。 (2)编译失败,内核版本差异(函数实现调整等)需要针对性进行内核适配。
> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:** > ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:**
> - 参考kernel.mk,在OpenHarmony工程的编译构建流程中会拷贝kernel/linux-4.19的代码环境后进行打补丁动作,在使用版本级编译命令前,需要kernel/linux-4.19保持原代码环境。 > - 参考`kernel.mk`,在OpenHarmony工程的编译构建流程中会拷贝kernel/linux-4.19的代码环境后进行打补丁动作,在使用版本级编译命令前,需要kernel/linux-4.19保持原代码环境。
> >
> - 对应拷贝后的目录位于: out/&lt;\*\*\*&gt;/kernel/linux-4.19,可以在该目录下进行补丁的修改适配。 > - 对应拷贝后的目录位于:`out/<***>/kernel/linux-4.19`,可以在该目录下进行补丁的修改适配。
4. 烧录启动。 4. 烧录启动。
由于不同芯片的开发板的烧录方式不一样,此处不表述具体的烧录方式。需要注意烧录的各镜像的大小及启动参数的配置,参考hi3516dv300采用uboot启动参数: 由于不同芯片的开发板的烧录方式不一样,此处不表述具体的烧录方式。需要注意烧录的各镜像的大小及启动参数的配置,参考hi3516dv300采用uboot启动参数:
...@@ -56,43 +60,56 @@ Linux内核移植主要涉及基于linux内核基线合入三方芯片补丁后 ...@@ -56,43 +60,56 @@ Linux内核移植主要涉及基于linux内核基线合入三方芯片补丁后
调试init进程、启动shell和运行简单的用户态程序,验证内核移植是否成功。OpenHarmony小型系统的OS镜像结构以及linux用户态的启动流程如下图1所示: 调试init进程、启动shell和运行简单的用户态程序,验证内核移植是否成功。OpenHarmony小型系统的OS镜像结构以及linux用户态的启动流程如下图1所示:
**图1** 基于linux内核的OS镜像结构和用户态程序启动流程 **图1** 基于linux内核的OS镜像结构和用户态程序启动流程
![zh-cn_image_0000001154372318](figures/zh-cn_image_0000001154372318.png) ![zh-cn_image_0000001154372318](figures/zh-cn_image_0000001154372318.png)
基于上述流程,推荐按以下步骤完成验证: 基于上述流程,推荐按以下步骤完成验证:
1. 制作根文件系统镜像。 1. 制作根文件系统镜像。
请参考[新建芯片解决方案和产品解决方案](../subsystems/subsys-build-all.md)生成根文件系统镜像rootfs.img。从上图可以看到启动过程与产品配置强相关,在制作rootfs.img过程中请完成如下四种配置:
请参考[新建芯片解决方案和产品解决方案](../subsystems/subsys-build-all.md)生成根文件系统镜像`rootfs.img`。从上图可以看到启动过程与产品配置强相关,在制作rootfs.img过程中请完成如下四种配置:
- 组件配置 - 组件配置
产品组件配置文件vendor/{company}/{product}/config.json需配置启动恢复子系统(startup)的init_lite组件和内核子系统的linux_4_1_9组件。
产品组件配置文件`vendor/{company}/{product}/config.json`需配置启动恢复子系统(startup)的init_lite组件和内核子系统的linux_4_1_9组件。
- 系统服务配置 - 系统服务配置
系统服务配置文件vendor/{company}/{product}/init_configs/init_xxx.cfg需要启动shell服务。
系统服务配置文件`vendor/{company}/{product}/init_configs/init_xxx.cfg`需要启动shell服务。
- 文件系统配置 - 文件系统配置
文件系统配置vendor/{company}/{product}/fs.yml中需要创建“/bin/sh -&gt; mksh“和“/lib/ld-musl-arm.so.1 -&gt; libc.so“软连接,这两个文件分别是shell可执行程序和可执行程序依赖的c库。
文件系统配置`vendor/{company}/{product}/fs.yml`中需要创建`/bin/sh -> mksh`和`/lib/ld-musl-arm.so.1 -> libc.so`软连接,这两个文件分别是shell可执行程序和可执行程序依赖的c库。
- 启动配置 - 启动配置
启动配置在vendor/{company}/{product}/init_configs/etc目录下,包括fstab、rsS和Sxxx文件,请按开发板实际情况配置。
启动配置在`vendor/{company}/{product}/init_configs/etc`目录下,包括fstab、rsS和Sxxx文件,请按开发板实际情况配置。
编译完成后,可通过检查产品编译输出目录下的rootfs内容,确认rootfs.img文件生成是否符合预期。 编译完成后,可通过检查产品编译输出目录下的rootfs内容,确认rootfs.img文件生成是否符合预期。
2. 调试init进程和shell。 2. 调试init进程和shell。
烧录rootfs.img并调试init进程和shell,不同厂商的开发板的烧录工具和流程可能不同,请按芯片解决方案提供的流程进行烧录。烧录rootfs.img前请确认bootloader和linux内核启动正常。如果rootfs.img被内核正常挂载,接着将运行/bin/init程序,init进程为用户态的第一个应用程序,它的运行意味着用户态的开始。
init程序首先会调用/etc/init.d/rcS脚本,rcS脚本执行第一条命令为"/bin/mount -a”,该命令会加载fstab文件,在fstab中的命令执行完后rcS将顺序调用Sxxx脚本完成设备节点创建和扫描、文件权限配置等操作 烧录`rootfs.img`并调试init进程和shell,不同厂商的开发板的烧录工具和流程可能不同,请按芯片解决方案提供的流程进行烧录。烧录`rootfs.img`前请确认bootloader和linux内核启动正常。如果`rootfs.img`被内核正常挂载,接着将运行`/bin/init`程序,init进程为用户态的第一个应用程序,它的运行意味着用户态的开始
最后,init程序会读取init.cfg系统服务配置文件。根据步骤1中的设置,init程序将会启动shell。如果上述流程运行正常,系统则会进入shell。 init程序首先会调用`/etc/init.d/rcS`脚本,rcS脚本执行第一条命令为`/bin/mount -a`,该命令会加载fstab文件,在fstab中的命令执行完后rcS将顺序调用Sxxx脚本完成设备节点创建和扫描、文件权限配置等操作。
最后,init程序会读取`init.cfg`系统服务配置文件。根据步骤1中的设置,init程序将会启动shell。如果上述流程运行正常,系统则会进入shell。
若串口有如下版本号日志打印,则表示init程序启动正常: 若串口有如下版本号日志打印,则表示init程序启动正常:
**图2** init启动正常日志 **图2** init启动正常日志
![zh-cn_image_0000001154212516](figures/zh-cn_image_0000001154212516.png) ![zh-cn_image_0000001154212516](figures/zh-cn_image_0000001154212516.png)
正常进入shell后执行ls命令,串口打印信息如下图: 正常进入shell后执行ls命令,串口打印信息如下图:
**图3** 正常进入shell后输入ls命令串口打印 **图3** 正常进入shell后输入ls命令串口打印
![zh-cn_image_0000001200171991](figures/zh-cn_image_0000001200171991.png) ![zh-cn_image_0000001200171991](figures/zh-cn_image_0000001200171991.png)
3. 配置NFS。 3. 配置NFS。
init进程和shell正常启动后,以服务端IP为192.168.1.22、客户端IP为192.168.1.4为例,可在根目录执行如下命令开启NFS:
init进程和shell正常启动后,以服务端IP为192.168.1.22、客户端IP为192.168.1.4为例,可在根目录执行如下命令开启NFS:
``` ```
ifconfig eth0 192.168.1.4 netmask 255.255.255.0 ifconfig eth0 192.168.1.4 netmask 255.255.255.0
......
...@@ -20,7 +20,8 @@ sudo apt-get install gcc-arm-linux-gnueabi ...@@ -20,7 +20,8 @@ sudo apt-get install gcc-arm-linux-gnueabi
了解编译框架和搭建完编译环境后,请参考如下步骤新建芯片解决方案: 了解编译框架和搭建完编译环境后,请参考如下步骤新建芯片解决方案:
1. 新建目录 1. 新建目录
芯片解决方案的目录规则为:device/{芯片解决方案厂商}/{开发板}。以海思的hispark_taurus开发板为例,在代码根目录执行如下命令建立目录:
芯片解决方案的目录规则为:`device/{芯片解决方案厂商}/{开发板}`。以海思的hispark_taurus开发板为例,在代码根目录执行如下命令建立目录:
``` ```
...@@ -59,7 +60,8 @@ sudo apt-get install gcc-arm-linux-gnueabi ...@@ -59,7 +60,8 @@ sudo apt-get install gcc-arm-linux-gnueabi
目录树建立后开发板相关的源码放到hispark_taurus目录下。 目录树建立后开发板相关的源码放到hispark_taurus目录下。
2. 配置开发板编译选项 2. 配置开发板编译选项
步骤1中的config.gni可配置开发板相关的编译选项,编译构建框架将会遵照该配置文件中的参数编译所有用户态OS组件。其中关键的字段说明如下:
步骤1中的`config.gni`可配置开发板相关的编译选项,编译构建框架将会遵照该配置文件中的参数编译所有用户态OS组件。其中关键的字段说明如下:
``` ```
...@@ -75,7 +77,7 @@ sudo apt-get install gcc-arm-linux-gnueabi ...@@ -75,7 +77,7 @@ sudo apt-get install gcc-arm-linux-gnueabi
board_ld_flags: 开发板配置的链接选项。 board_ld_flags: 开发板配置的链接选项。
``` ```
还以海思的hispark_taurus开发板为例,对应的device/hisilicon/hispark_taurus/config.gni内容如下: 还以海思的hispark_taurus开发板为例,对应的`device/hisilicon/hispark_taurus/config.gni`内容如下:
``` ```
# Board CPU type, e.g. "cortex-a7", "riscv32". # Board CPU type, e.g. "cortex-a7", "riscv32".
...@@ -121,9 +123,10 @@ sudo apt-get install gcc-arm-linux-gnueabi ...@@ -121,9 +123,10 @@ sudo apt-get install gcc-arm-linux-gnueabi
``` ```
3. 编写开发板编译脚本 3. 编写开发板编译脚本
步骤1中的BUILD.gn为新增的开发板的编译入口,主要用于编译开发板相关的代码,主要为设备侧驱动、设备侧接口适配(媒体,图形等)和开发板的SDK等等。
海思的hispark_taurus开发板的device/hisilicon/hispark_taurus/BUILD.gn可写成: 步骤1中的`BUILD.gn`为新增的开发板的编译入口,主要用于编译开发板相关的代码,主要为设备侧驱动、设备侧接口适配(媒体,图形等)和开发板的SDK等等。
海思的hispark_taurus开发板的`device/hisilicon/hispark_taurus/BUILD.gn`可写成:
``` ```
...@@ -137,4 +140,5 @@ sudo apt-get install gcc-arm-linux-gnueabi ...@@ -137,4 +140,5 @@ sudo apt-get install gcc-arm-linux-gnueabi
``` ```
4. 编译调试 4. 编译调试
在开发板目录下执行hb set和hb build即可启动芯片解决方案的编译,编译框架会以开发板下的BUILD.gn为入口启动编译。
在开发板目录下执行`hb set``hb build`即可启动芯片解决方案的编译,编译框架会以开发板下的`BUILD.gn`为入口启动编译。
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
### 定义产品 ### 定义产品
“//vendor/MyProductVendor/{product_name}名称的目录下创建一个config.json文件,该文件用于描述产品所使用的SOC 以及所需的子系统。配置如下: `//vendor/MyProductVendor/{product_name}`名称的目录下创建一个config.json文件,该文件用于描述产品所使用的SOC 以及所需的子系统。配置如下:
//vendor/MyProductVendor/MyProduct/config.json //vendor/MyProductVendor/MyProduct/config.json
...@@ -41,29 +41,20 @@ ...@@ -41,29 +41,20 @@
``` ```
主要的配置内容 主要的配置内容
product_name:产品名称 必填 | 配置项 | 说明 |
|-------|----------|
version:版本 必填 |product_name |(必填)产品名称|
|version|(必填)版本 |
type:配置的系统级别,包含(small,standard …) 必填 |type|(必填)配置的系统级别,包含(small、standard等) |
|target_cpu |(必填)设备的CPU类型(根据实际情况,这里的target_cpu也可能是arm64 、riscv、 x86等)|
target_cpu :设备的CPU类型(根据实际情况,这里的target_cpu也可能是arm64 、riscv、 x86等。) 必填 |ohos_version|(选填)操作系统版本|
|device_company|(必填)device厂商名|
ohos_version:操作系统版本 选填 |board|(必填)开发板名称|
|enable_ramdisk|(必填)是否启动ramdisk|
device_company:device厂商名 必填 |kernel_type|(选填)内核类型|
|kernel_version|(选填)kernel_type与kernel_version在standard是固定的不需要写|
board:开发板名称 必填 |subsystems|(必填)系统需要启用的子系统。子系统可以简单理解为一块独立构建的功能块。|
|product_company|不体现在配置中,而是目录名,vendor下一级目录就是product_company,BUILD.gn脚本依然可以访问。|
enable_ramdisk:是否启动ramdisk 必填
kernel_type 选填
kernel_version 选填 kernel_type与 kernel_version在 standard 是固定的不需要写。
subsystems:系统需要启用的子系统。子系统可以简单理解为一块独立构建的功能块。必填
product_company:不体现在配置中,而是目录名,vendor下一级目录就是product_company,BUILD.gn脚本依然可以访问。
已定义的子系统可以在“//build/subsystem_config.json”中找到。当然你也可以定制子系统。 已定义的子系统可以在“//build/subsystem_config.json”中找到。当然你也可以定制子系统。
...@@ -79,7 +70,7 @@ product_company:不体现在配置中,而是目录名,vendor下一级目 ...@@ -79,7 +70,7 @@ product_company:不体现在配置中,而是目录名,vendor下一级目
./build.sh --product-name MyProduct ./build.sh --product-name MyProduct
``` ```
构建完成后,可以在“//out/{device_name}/packages/phone/images”目录下看到构建出来的OpenHarmony镜像文件。 构建完成后,可以在`//out/{device_name}/packages/phone/images`目录下看到构建出来的OpenHarmony镜像文件。
## 内核移植 ## 内核移植
...@@ -89,7 +80,7 @@ product_company:不体现在配置中,而是目录名,vendor下一级目 ...@@ -89,7 +80,7 @@ product_company:不体现在配置中,而是目录名,vendor下一级目
### 为SOC添加内核构建的子系统 ### 为SOC添加内核构建的子系统
修改文件 //build/subsystem_config.json增加一个子系统. 配置如下: 修改文件`//build/subsystem_config.json`增加一个子系统。配置如下:
``` ```
...@@ -101,16 +92,16 @@ product_company:不体现在配置中,而是目录名,vendor下一级目 ...@@ -101,16 +92,16 @@ product_company:不体现在配置中,而是目录名,vendor下一级目
}, },
``` ```
接着需要修改定义产品的配置文件//vendor/MyProductVendor/MyProduct/config.json,将刚刚定义的子系统加入到产品中。 接着需要修改定义产品的配置文件`//vendor/MyProductVendor/MyProduct/config.json`,将刚刚定义的子系统加入到产品中。
### 编译内核 ### 编译内核
源码中提供了Linux 4.19的内核,归档在//kernel/linux-4.19。本节以该内核版本为例,讲解如何编译内核。 源码中提供了Linux 4.19的内核,归档在`//kernel/linux-4.19`。本节以该内核版本为例,讲解如何编译内核。
在子系统的定义中,描述了子系统构建的路径path,即`//device/MySOCVendor/MySOC/build`。这一节会在这个目录创建构建脚本,告诉构建系统如何构建内核。 在子系统的定义中,描述了子系统构建的路径path,即`//device/MySOCVendor/MySOC/build`。这一节会在这个目录创建构建脚本,告诉构建系统如何构建内核。
建议的目录结构 建议的目录结构
``` ```
...@@ -126,9 +117,8 @@ BUILD.gn是subsystem构建的唯一入口。 ...@@ -126,9 +117,8 @@ BUILD.gn是subsystem构建的唯一入口。
期望的构建结果 期望的构建结果
| | |
| -------- | -------- |
| 文件 | 文件说明 | | 文件 | 文件说明 |
| -------- | -------- |
| $root_build_dir/packages/phone/images/uImage | 内核镜像 | | $root_build_dir/packages/phone/images/uImage | 内核镜像 |
| $root_build_dir/packages/phone/images/uboot | bootloader镜像 | | $root_build_dir/packages/phone/images/uboot | bootloader镜像 |
...@@ -156,11 +146,11 @@ BUILD.gn是subsystem构建的唯一入口。 ...@@ -156,11 +146,11 @@ BUILD.gn是subsystem构建的唯一入口。
2. init。 2. init。
init启动引导组件配置文件包含了所有需要由init进程启动的系统关键服务的服务名、可执行文件路径、权限和其他信息。每个系统服务各自安装其启动脚本到/system/etc/init目录下。 init启动引导组件配置文件包含了所有需要由init进程启动的系统关键服务的服务名、可执行文件路径、权限和其他信息。每个系统服务各自安装其启动脚本到`/system/etc/init`目录下。
新芯片平台移植时,平台相关的初始化配置需要增加平台相关的初始化配置文件/vendor/etc/init/init.{hardware}.cfg;该文件完成平台相关的初始化设置,如安装ko驱动,设置平台相关的/proc节点信息。 新芯片平台移植时,平台相关的初始化配置需要增加平台相关的初始化配置文件`/vendor/etc/init/init.{hardware}.cfg`;该文件完成平台相关的初始化设置,如安装ko驱动,设置平台相关的`/proc`节点信息。
init相关进程代码在//base/startup/init_lite目录下,该进程是系统第一个进程,无其它依赖。 init相关进程代码在`//base/startup/init_lite`目录下,该进程是系统第一个进程,无其它依赖。
初始化配置文件具体的开发指导请参考 [init启动子系统概述](../subsystems/subsys-boot-overview.md) 初始化配置文件具体的开发指导请参考 [init启动子系统概述](../subsystems/subsys-boot-overview.md)
...@@ -172,115 +162,117 @@ BUILD.gn是subsystem构建的唯一入口。 ...@@ -172,115 +162,117 @@ BUILD.gn是subsystem构建的唯一入口。
HDF为LCD设计了驱动模型。支持一块新的LCD,需要编写一个驱动,在驱动中生成模型的实例,并完成注册。 HDF为LCD设计了驱动模型。支持一块新的LCD,需要编写一个驱动,在驱动中生成模型的实例,并完成注册。
这些LCD的驱动被放置在//drivers/hdf_core/framework/model/display/driver/panel目录中。 这些LCD的驱动被放置在`//drivers/hdf_core/framework/model/display/driver/panel`目录中。
- 创建Panel驱动 1. 创建Panel驱动
在驱动的Init方法中,需要调用RegisterPanel接口注册模型实例。如: 在驱动的Init方法中,需要调用RegisterPanel接口注册模型实例。如:
``` ```
int32_t XXXInit(struct HdfDeviceObject *object) int32_t XXXInit(struct HdfDeviceObject *object)
{ {
struct PanelData *panel = CreateYourPanel(); struct PanelData *panel = CreateYourPanel();
// 注册
if (RegisterPanel(panel) != HDF_SUCCESS) {
HDF_LOGE("%s: RegisterPanel failed", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
struct HdfDriverEntry g_xxxxDevEntry = { // 注册
.moduleVersion = 1, if (RegisterPanel(panel) != HDF_SUCCESS) {
.moduleName = "LCD_XXXX", HDF_LOGE("%s: RegisterPanel failed", __func__);
.Init = XXXInit, return HDF_FAILURE;
}; }
return HDF_SUCCESS;
}
HDF_INIT(g_xxxxDevEntry); struct HdfDriverEntry g_xxxxDevEntry = {
``` .moduleVersion = 1,
.moduleName = "LCD_XXXX",
.Init = XXXInit,
};
- 配置加载panel驱动产品的所有设备信息被定义在文件//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs中。修改该文件,在display的host中,名为device_lcd的device中增加配置。注意:moduleName 要与panel驱动中的moduleName相同。 HDF_INIT(g_xxxxDevEntry);
```
``` 2. 配置加载panel驱动产品的所有设备信息被定义在文件`//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs`中。修改该文件,在display的host中,名为device_lcd的device中增加配置。
root {
... 注意:moduleName要与panel驱动中的moduleName相同。
display :: host {
device_lcd :: device { ```
deviceN :: deviceNode { root {
policy = 0; ...
priority = 100; display :: host {
preload = 2; device_lcd :: device {
moduleName = "LCD_XXXX"; deviceN :: deviceNode {
} policy = 0;
} priority = 100;
} preload = 2;
} moduleName = "LCD_XXXX";
``` }
}
}
}
```
更详细的驱动开发指导,请参考 [LCD](../driver/driver-peripherals-lcd-des.md) 更详细的驱动开发指导,请参考[LCD](../driver/driver-peripherals-lcd-des.md)
### 触摸屏 ### 触摸屏
本节描述如何移植触摸屏驱动。触摸屏的驱动被放置在//drivers/hdf_core/framework/model/input/driver/touchscreen目录中。移植触摸屏驱动主要工作是向系统注册ChipDevice模型实例。 本节描述如何移植触摸屏驱动。触摸屏的驱动被放置在`//drivers/hdf_core/framework/model/input/driver/touchscreen`目录中。移植触摸屏驱动主要工作是向系统注册ChipDevice模型实例。
- 创建触摸屏器件驱动 1. 创建触摸屏器件驱动
在目录中创建名为touch_ic_name.c的文件。代码模板如下:注意:请替换ic_name为你所适配芯片的名称。 在目录中创建名为touch_ic_name.c的文件。代码模板如下:注意:请替换ic_name为你所适配芯片的名称。
``` ```
#include "hdf_touch.h" #include "hdf_touch.h"
static int32_t HdfXXXXChipInit(struct HdfDeviceObject *device) static int32_t HdfXXXXChipInit(struct HdfDeviceObject *device)
{ {
ChipDevice *tpImpl = CreateXXXXTpImpl(); ChipDevice *tpImpl = CreateXXXXTpImpl();
if(RegisterChipDevice(tpImpl) != HDF_SUCCESS) { if(RegisterChipDevice(tpImpl) != HDF_SUCCESS) {
ReleaseXXXXTpImpl(tpImpl); ReleaseXXXXTpImpl(tpImpl);
return HDF_FAILURE; return HDF_FAILURE;
} }
return HDF_SUCCESS; return HDF_SUCCESS;
} }
struct HdfDriverEntry g_touchXXXXChipEntry = { struct HdfDriverEntry g_touchXXXXChipEntry = {
.moduleVersion = 1, .moduleVersion = 1,
.moduleName = "HDF_TOUCH_XXXX", .moduleName = "HDF_TOUCH_XXXX",
.Init = HdfXXXXChipInit, .Init = HdfXXXXChipInit,
}; };
HDF_INIT(g_touchXXXXChipEntry); HDF_INIT(g_touchXXXXChipEntry);
``` ```
其中ChipDevice中要提供若干方法。 其中ChipDevice中要提供若干方法。
| | | | 方法 | 实现说明 |
| -------- | -------- | | -------- | -------- |
| 方法 | 实现说明 | | int32_t&nbsp;(\*Init)(ChipDevice&nbsp;\*device) | 器件初始化 |
| int32_t&nbsp;(\*Init)(ChipDevice&nbsp;\*device) | 器件初始化 | | int32_t&nbsp;(\*Detect)(ChipDevice&nbsp;\*device) | 器件探测 |
| int32_t&nbsp;(\*Detect)(ChipDevice&nbsp;\*device) | 器件探测 | | int32_t&nbsp;(\*Suspend)(ChipDevice&nbsp;\*device) | 器件休眠 |
| int32_t&nbsp;(\*Suspend)(ChipDevice&nbsp;\*device) | 器件休眠 | | int32_t&nbsp;(\*Resume)(ChipDevice&nbsp;\*device) | 器件唤醒 |
| int32_t&nbsp;(\*Resume)(ChipDevice&nbsp;\*device) | 器件唤醒 | | int32_t&nbsp;(\*DataHandle)(ChipDevice&nbsp;\*device) | 从器件读取数据,将触摸点数据填写入device-&gt;driver-&gt;frameData中 |
| int32_t&nbsp;(\*DataHandle)(ChipDevice&nbsp;\*device) | 从器件读取数据,将触摸点数据填写入device-&gt;driver-&gt;frameData中 | | int32_t&nbsp;(\*UpdateFirmware)(ChipDevice&nbsp;\*device) | 固件升级 |
| int32_t&nbsp;(\*UpdateFirmware)(ChipDevice&nbsp;\*device) | 固件升级 |
- 配置产品,加载器件驱动 2. 配置产品,加载器件驱动
产品的所有设备信息被定义在文件//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs中。修改该文件,在名为input的host中,名为device_touch_chip的device中增加配置。注意:moduleName 要与触摸屏驱动中的moduleName相同。
产品的所有设备信息被定义在文件`//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs`中。修改该文件,在名为input的host中,名为device_touch_chip的device中增加配置。注意:moduleName 要与触摸屏驱动中的moduleName相同。
``` ```
deviceN :: deviceNode { deviceN :: deviceNode {
policy = 0; policy = 0;
priority = 130; priority = 130;
preload = 0; preload = 0;
permission = 0660; permission = 0660;
moduleName = "HDF_TOUCH_XXXX"; moduleName = "HDF_TOUCH_XXXX";
deviceMatchAttr = "touch_XXXX_configs"; deviceMatchAttr = "touch_XXXX_configs";
} }
``` ```
更详细的驱动开发指导,请参考 [TOUCHSCREEN](../driver/driver-peripherals-touch-des.md) 更详细的驱动开发指导,请参考[TOUCHSCREEN](../driver/driver-peripherals-touch-des.md)
### WLAN ### WLAN
...@@ -293,135 +285,134 @@ Wi-Fi驱动分为两部分,一部分负责管理WLAN设备,另一个部分 ...@@ -293,135 +285,134 @@ Wi-Fi驱动分为两部分,一部分负责管理WLAN设备,另一个部分
支持一款芯片的主要工作是实现一个ChipDriver驱动。实现HDF_WLAN_CORE和NetDevice提供的接口。主要需要实现的接口有: 支持一款芯片的主要工作是实现一个ChipDriver驱动。实现HDF_WLAN_CORE和NetDevice提供的接口。主要需要实现的接口有:
| | | |
| -------- | -------- | -------- |
| 接口 | 定义头文件 | 说明 | | 接口 | 定义头文件 | 说明 |
| -------- | -------- | -------- |
| HdfChipDriverFactory | //drivers/hdf_core/framework/include/wifi/hdf_wlan_chipdriver_manager.h | ChipDriver的Factory,用于支持一个芯片多个Wi-Fi端口 | | HdfChipDriverFactory | //drivers/hdf_core/framework/include/wifi/hdf_wlan_chipdriver_manager.h | ChipDriver的Factory,用于支持一个芯片多个Wi-Fi端口 |
| HdfChipDriver | //drivers/hdf_core/framework/include/wifi/wifi_module.h | 每个WLAN端口对应一个HdfChipDriver,用来管理一个特定的WLAN端口 | | HdfChipDriver | //drivers/hdf_core/framework/include/wifi/wifi_module.h | 每个WLAN端口对应一个HdfChipDriver,用来管理一个特定的WLAN端口 |
| NetDeviceInterFace | //drivers/hdf_core/framework/include/net/net_device.h | 与协议栈之间的接口,如发送数据、设置网络接口状态等 | | NetDeviceInterFace | //drivers/hdf_core/framework/include/net/net_device.h | 与协议栈之间的接口,如发送数据、设置网络接口状态等 |
建议适配按如下步骤操作: 建议适配按如下步骤操作:
1.创建HDF驱动建议将代码放置在//device/MySoCVendor/peripheral/wifi/chip_name/,文件模板如下: 1. 创建HDF驱动建议将代码放置在`//device/MySoCVendor/peripheral/wifi/chip_name/`,文件模板如下:
``` ```
static int32_t HdfWlanXXXChipDriverInit(struct HdfDeviceObject *device) { static int32_t HdfWlanXXXChipDriverInit(struct HdfDeviceObject *device) {
static struct HdfChipDriverFactory factory = CreateChipDriverFactory(); static struct HdfChipDriverFactory factory = CreateChipDriverFactory();
struct HdfChipDriverManager *driverMgr = HdfWlanGetChipDriverMgr(); struct HdfChipDriverManager *driverMgr = HdfWlanGetChipDriverMgr();
if (driverMgr->RegChipDriver(&factory) != HDF_SUCCESS) { if (driverMgr->RegChipDriver(&factory) != HDF_SUCCESS) {
HDF_LOGE("%s fail: driverMgr is NULL!", __func__); HDF_LOGE("%s fail: driverMgr is NULL!", __func__);
return HDF_FAILURE; return HDF_FAILURE;
} }
return HDF_SUCCESS; return HDF_SUCCESS;
} }
struct HdfDriverEntry g_hdfXXXChipEntry = { struct HdfDriverEntry g_hdfXXXChipEntry = {
.moduleVersion = 1, .moduleVersion = 1,
.Init = HdfWlanXXXChipDriverInit, .Init = HdfWlanXXXChipDriverInit,
.Release = HdfWlanXXXChipRelease, .Release = HdfWlanXXXChipRelease,
.moduleName = "HDF_WIFI_CHIP_XXX" .moduleName = "HDF_WIFI_CHIP_XXX"
}; };
HDF_INIT(g_hdfXXXChipEntry); HDF_INIT(g_hdfXXXChipEntry);
``` ```
在CreateChipDriverFactory中,需要创建一个HdfChipDriverFactory,接口如下: 在CreateChipDriverFactory中,需要创建一个HdfChipDriverFactory,接口如下:
| | |
| -------- | -------- |
| 接口 | 说明 | | 接口 | 说明 |
| const&nbsp;char&nbsp;\*driverName | 当前driverName | | -------- | -------- |
| int32_t&nbsp;(\*InitChip)(struct&nbsp;HdfWlanDevice&nbsp;\*device) | 初始化芯片 | | const&nbsp;char&nbsp;\*driverName | 当前driverName |
| int32_t&nbsp;(\*DeinitChip)(struct&nbsp;HdfWlanDevice&nbsp;\*device) | 去初始化芯片 | | int32_t&nbsp;(\*InitChip)(struct&nbsp;HdfWlanDevice&nbsp;\*device) | 初始化芯片 |
| void&nbsp;(_ReleaseFactory)(struct&nbsp;HdfChipDriverFactory&nbsp;_factory) | 释放HdfChipDriverFactory对象 | | int32_t&nbsp;(\*DeinitChip)(struct&nbsp;HdfWlanDevice&nbsp;\*device) | 去初始化芯片 |
| struct&nbsp;HdfChipDriver&nbsp;_(_Build)(struct&nbsp;HdfWlanDevice&nbsp;\*device,&nbsp;uint8_t&nbsp;ifIndex) | 创建一个HdfChipDriver;输入参数中,device是设备信息,ifIndex是当前创建的接口在这个芯片中的序号 | | void&nbsp;(_ReleaseFactory)(struct&nbsp;HdfChipDriverFactory&nbsp;_factory) | 释放HdfChipDriverFactory对象 |
| void&nbsp;(_Release)(struct&nbsp;HdfChipDriver&nbsp;_chipDriver) | 释放chipDriver | | struct&nbsp;HdfChipDriver&nbsp;_(_Build)(struct&nbsp;HdfWlanDevice&nbsp;\*device,&nbsp;uint8_t&nbsp;ifIndex) | 创建一个HdfChipDriver;输入参数中,device是设备信息,ifIndex是当前创建的接口在这个芯片中的序号 |
| uint8_t&nbsp;(\*GetMaxIFCount)(struct&nbsp;HdfChipDriverFactory&nbsp;\*factory) | 获取当前芯片支持的最大接口数 | | void&nbsp;(_Release)(struct&nbsp;HdfChipDriver&nbsp;_chipDriver) | 释放chipDriver |
| uint8_t&nbsp;(\*GetMaxIFCount)(struct&nbsp;HdfChipDriverFactory&nbsp;\*factory) | 获取当前芯片支持的最大接口数 |
HdfChipDriver需要实现的接口有
HdfChipDriver需要实现的接口有:
| | |
| -------- | -------- | | 接口 | 说明 |
| 接口 | 说明 | | -------- | -------- |
| int32_t&nbsp;(\*init)(struct&nbsp;HdfChipDriver&nbsp;\*chipDriver,&nbsp;NetDevice&nbsp;\*netDev) | 初始化当前网络接口,这里需要向netDev提供接口NetDeviceInterFace | | int32_t&nbsp;(\*init)(struct&nbsp;HdfChipDriver&nbsp;\*chipDriver,&nbsp;NetDevice&nbsp;\*netDev) | 初始化当前网络接口,这里需要向netDev提供接口NetDeviceInterFace |
| int32_t&nbsp;(\*deinit)(struct&nbsp;HdfChipDriver&nbsp;\*chipDriver,&nbsp;NetDevice&nbsp;\*netDev) | 去初始化当前网络接口 | | int32_t&nbsp;(\*deinit)(struct&nbsp;HdfChipDriver&nbsp;\*chipDriver,&nbsp;NetDevice&nbsp;\*netDev) | 去初始化当前网络接口 |
| struct&nbsp;HdfMac80211BaseOps&nbsp;\*ops | WLAN基础能力接口集 | | struct&nbsp;HdfMac80211BaseOps&nbsp;\*ops | WLAN基础能力接口集 |
| struct&nbsp;HdfMac80211STAOps&nbsp;\*staOps | 支持STA模式所需的接口集 | | struct&nbsp;HdfMac80211STAOps&nbsp;\*staOps | 支持STA模式所需的接口集 |
| struct&nbsp;HdfMac80211APOps&nbsp;\*apOps | 支持AP模式所需要的接口集 | | struct&nbsp;HdfMac80211APOps&nbsp;\*apOps | 支持AP模式所需要的接口集 |
2.编写配置文件,描述驱动支持的设备 2. 编写配置文件,描述驱动支持的设备。
在产品配置目录下创建芯片的配置文件//vendor/MyProductVendor/MyProduct/config/wifi/wlan_chip_chip_name.hcs。 在产品配置目录下创建芯片的配置文件`//vendor/MyProductVendor/MyProduct/config/wifi/wlan_chip_chip_name.hcs`
注意: 路径中的vendor_name、product_name、chip_name请替换成实际名称。 注意: 路径中的vendor_name、product_name、chip_name请替换成实际名称。
模板如下: 模板如下:
```
``` root {
root { wlan_config {
wlan_config { chip_name :& chipList {
chip_name :& chipList { chip_name :: chipInst {
chip_name :: chipInst { match_attr = "hdf_wlan_chips_chip_name"; /* 这是配置匹配属性,用于提供驱动的配置根 */
match_attr = "hdf_wlan_chips_chip_name"; /* 这是配置匹配属性,用于提供驱动的配置根 */ driverName = "driverName"; /* 需要与HdfChipDriverFactory中的driverName相同*/
driverName = "driverName"; /* 需要与HdfChipDriverFactory中的driverName相同*/ sdio {
sdio { vendorId = 0x0296;
vendorId = 0x0296; deviceId = [0x5347];
deviceId = [0x5347]; }
} }
} }
} }
} }
} ```
```
3. 编写配置文件,加载驱动。
3.编写配置文件,加载驱动
产品的所有设备信息被定义在文件`//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs`中。修改该文件,在名为network的host中,名为device_wlan_chips的device中增加配置。
产品的所有设备信息被定义在文件//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs中。修改该文件,在名为network的host中,名为device_wlan_chips的device中增加配置。注意:moduleName 要与触摸屏驱动中的moduleName相同。
注意:moduleName 要与触摸屏驱动中的moduleName相同。
``` ```
deviceN :: deviceNode { deviceN :: deviceNode {
policy = 0; policy = 0;
preload = 2; preload = 2;
moduleName = "HDF_WLAN_CHIPS"; moduleName = "HDF_WLAN_CHIPS";
deviceMatchAttr = "hdf_wlan_chips_chip_name"; deviceMatchAttr = "hdf_wlan_chips_chip_name";
serviceName = "driverName"; serviceName = "driverName";
} }
``` ```
4.构建驱动 4. 构建驱动
- 创建内核菜单在//device/MySoCVendor/peripheral目录中创建Kconfig文件,内容模板如下: - 创建内核菜单在`//device/MySoCVendor/peripheral`目录中创建Kconfig文件,内容模板如下:
``` ```
config DRIVERS_WLAN_XXX config DRIVERS_WLAN_XXX
bool "Enable XXX WLAN Host driver" bool "Enable XXX WLAN Host driver"
default n default n
depends on DRIVERS_HDF_WIFI depends on DRIVERS_HDF_WIFI
help help
Answer Y to enable XXX Host driver. Support chip xxx Answer Y to enable XXX Host driver. Support chip xxx
``` ```
接着修改文件//drivers/hdf_core/adapter/khdf/linux/model/network/wifi/Kconfig,在文件末尾加入如下代码将配置菜单加入内核中,如: 接着修改文件`//drivers/hdf_core/adapter/khdf/linux/model/network/wifi/Kconfig`,在文件末尾加入如下代码将配置菜单加入内核中,如:
``` ```
source "../../../../../device/MySoCVendor/peripheral/Kconfig" source "../../../../../device/MySoCVendor/peripheral/Kconfig"
``` ```
- 创建构建脚本 - 创建构建脚本
在//drivers/hdf_core/adapter/khdf/linux/model/network/wifi/Makefile文件末尾增加配置,模板如下:
`//drivers/hdf_core/adapter/khdf/linux/model/network/wifi/Makefile`文件末尾增加配置,模板如下:
``` ```
HDF_DEVICE_ROOT := $(HDF_DIR_PREFIX)/../device HDF_DEVICE_ROOT := $(HDF_DIR_PREFIX)/../device
obj-$(CONFIG_DRIVERS_WLAN_XXX) += $(HDF_DEVICE_ROOT)/MySoCVendor/peripheral/build/standard/ obj-$(CONFIG_DRIVERS_WLAN_XXX) += $(HDF_DEVICE_ROOT)/MySoCVendor/peripheral/build/standard/
``` ```
当在内核中开启DRIVERS_WLAN_XXX开关时,会调用//device/MySoCVendor/peripheral/build/standard/中的makefile。更多详细的开发手册,请参考[WLAN开发](../guide/device-wlan-led-control.md) 当在内核中开启DRIVERS_WLAN_XXX开关时,会调用`//device/MySoCVendor/peripheral/build/standard/`中的makefile。更多详细的开发手册,请参考[WLAN开发](../guide/device-wlan-led-control.md)。
### 开发移植示例 ### 开发移植示例
......
# ArkUI子系统changelog
## cl.arkui.1 状态变量支持undefined和null
**变更影响**
API version 9:状态变量不支持undefined和null,当开发者给状态变量设置undefined或者null时,设置失败,即状态变量还是上一次的值。
API version 10:状态变量支持undefined和null,当开发者给状态变量设置undefined和null时,ArkUI框架会接受该值,即下一次读状态变量的是undefined和null,开发者要注意做判空保护。
**适配指导**
API version 9,当开发者给状态变量设置undefined时,设置无效,会导致开发者忽略对undefined的校验。
```ts
@Entry
@Component
struct Page3 {
@State messages: string[] = ['Hello World']
aboutToAppear() {
// AppStorage里没有对应的key,返回undefined
// API version 9:赋值不生效,ArkUI框架会拒绝undefined,this.messages还为其初始值['Hello World']
// API version 10: 赋值生效,ArkUI框架会接受undefined,this.messages为undefined
this.messages = AppStorage.Get("aProp")
}
build() {
Row() {
Column() {
// API version 9: 应用没有crash,length为1
// API version 10:应用crash, Error message: Cannot read property length of undefined
Text(`the messages length: ${this.messages.length}`)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
}
}
```
对于上述情况,当每一次给状态变量赋值undefined和null时,需要对状态变量是否为undefined做校验。
```ts
Text(`the messages length: ${this.messages?.length}`)
```
API version 10,ArkUI框架增强对状态变量类型和初始化的校验,ArkUI框架会抛出运行时报错。具体有以下两种情况:
1. @Link必须被父组件初始化。
对于以下示例,当前会抛出运行时报错,提示开发者需要初始化@Link。
```ts
@Entry
@Component
struct Page3 {
@State aProp: boolean = true
build() {
Row() {
Column() {
// crash: SynchedPropertyObjectTwoWayPU[9, 'linkProp']: constructor @Link/@Consume source variable in
// parent/ancestor @Component must be defined. Application error!
LinkChild()
// 错误的用常规变量初始化linkProp,ArkUI框架无认为没有初始化,和上述一样的报错
LinkChild({ aProp: false })
// 正确,用状态变量this.aProp初始化@Link
LinkChild({ aProp: this.aProp })
}
.width('100%')
}
.height('100%')
}
}
@Component
struct LinkChild {
@Link aProp: boolean
build() {
Text(`linkProp: ${this.aProp}`)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
}
```
2. 校验状态变量不支持的类型。
状态变量对于不支持的类型,比如function,抛出运行时报错来提示开发者。
```ts
@Entry
@Component
struct Page3 {
// API version 10:运行时报错:@Component 'Page3': Illegal variable value error with decorated variable @State/@Provide 'functionProp': failed
// validation: 'undefined, null, number, boolean, string, or Object but not function, attempt to assign value type: 'function',
@State functionProp: () => void = () => {
console.info("123")
}
aboutToAppear() {
this.functionProp()
}
build() {
Row() {
Column() {
Text("hello")
}
.width('100%')
}
.height('100%')
}
}
```
## cl.arkui.2 @StorageLink在页面跳转和页签场景行为优化
**变更影响**
AppStorage是应用全局的UI状态存储,@StorageLink是对AppStorage中对应key的双向同步,即@StorageLink修饰的变量的改变会同步回AppStorage,AppStorage的修改也会同步给@StorageLink。
当AppStorage某一个key发生改变时,会通知所有绑定该key的@StorageLink,@StorageLink装饰的变量的改变,会触发组件的重新渲染,包括不可见页面或者TabContent组件,这就造成了不必要的更新和性能浪费。
本次优化针对两个场景做出了优化:
1. 不可见页面的@StorageLink不会被通知刷新。
2. 不可见TabContent的@StorageLink不会被通知刷新。
AppStorage的属性改变,将不立即通知这两个场景下的@StorageLink更新和其@Watch回调,而是当页面或TabContent重新回到激活状态时,即可见状态,再去触发UI更新和其@Watch回调。
可见切换不可见状态或不可见切换可见状态流程如下:
1. 页面或TabContent内的自定义组件从可见到不可见,即标记组件为inActive。
2. 当AppStorage的属性变化时,标记不可见节点的@StorageLink装饰的变量已经变化,但不通知UI刷新。
3. 当页面或TabContent重新可见,即从inActive回到Active状态,将@StorageLink的dependentElementIds添加到其所属自定义组件的脏节点,调用其@Watch方法,刷新UI。
这次优化带来的最重要的应用行为变更是:不可见的页面和TabContent的@StorageLink的watch方法将不被回调。当其回到可见状态时,才会触发@Watch方法回调和UI更新。
**适配指导**
不建议开发者通过借助@StorageLink和@Watch作为事件通知机制,因为@StorageLink是和UI强相关的装饰器,更新成本相较于一般的事件通知机制emit较高。
TapImage中的点击事件,会触发AppStorage中tapIndex对应属性的改变。因为@StorageLink是双向同步,修改会同步会AppStorage中,所以,所有绑定AppStorage的tapIndex可见自定义组件都会被通知UI刷新。UI刷新带来的成本是巨大的,因此不建议开发者使用此方式来实现基本的事件通知功能。
```ts
// xxx.ets
class ViewData {
title: string;
uri: Resource;
color: Color = Color.Black;
constructor(title: string, uri: Resource) {
this.title = title;
this.uri = uri
}
}
@Entry
@Component
struct Gallery2 {
dataList: Array<ViewData> = [new ViewData('flower', $r('app.media.icon')), new ViewData('OMG', $r('app.media.icon')), new ViewData('OMG', $r('app.media.icon'))]
scroller: Scroller = new Scroller()
build() {
Column() {
Grid(this.scroller) {
ForEach(this.dataList, (item: ViewData, index?: number) => {
GridItem() {
TapImage({
uri: item.uri,
index: index
})
}.aspectRatio(1)
}, (item: ViewData, index?: number) => {
return JSON.stringify(item) + index;
})
}.columnsTemplate('1fr 1fr')
}
}
}
@Component
export struct TapImage {
@StorageLink('tapIndex') @Watch('onTapIndexChange') tapIndex: number = -1;
@State tapColor: Color = Color.Black;
private index: number;
private uri: Resource;
// 判断是否被选中
onTapIndexChange() {
if (this.tapIndex >= 0 && this.index === this.tapIndex) {
console.info(`tapindex: ${this.tapIndex}, index: ${this.index}, red`)
this.tapColor = Color.Red;
} else {
console.info(`tapindex: ${this.tapIndex}, index: ${this.index}, black`)
this.tapColor = Color.Black;
}
}
build() {
Column() {
Image(this.uri)
.objectFit(ImageFit.Cover)
.onClick(() => {
this.tapIndex = this.index;
})
.border({ width: 5, style: BorderStyle.Dotted, color: this.tapColor })
}
}
}
```
开发者可以使用emit订阅某个事件并接收事件回调,可以减少开销,增强代码的可读性。
```ts
// xxx.ets
import emitter from '@ohos.events.emitter';
let NextID: number = 0;
class ViewData {
title: string;
uri: Resource;
color: Color = Color.Black;
id: number;
constructor(title: string, uri: Resource) {
this.title = title;
this.uri = uri
this.id = NextID++;
}
}
@Entry
@Component
struct Gallery2 {
dataList: Array<ViewData> = [new ViewData('flower', $r('app.media.icon')), new ViewData('OMG', $r('app.media.icon')), new ViewData('OMG', $r('app.media.icon'))]
scroller: Scroller = new Scroller()
private preIndex: number = -1
build() {
Column() {
Grid(this.scroller) {
ForEach(this.dataList, (item: ViewData) => {
GridItem() {
TapImage({
uri: item.uri,
index: item.id
})
}.aspectRatio(1)
.onClick(() => {
if (this.preIndex === item.id) {
return
}
var innerEvent = { eventId: item.id }
// 选中态:黑变红
var eventData = {
data: {
"colorTag": 1
}
}
emitter.emit(innerEvent, eventData)
if (this.preIndex != -1) {
console.info(`preIndex: ${this.preIndex}, index: ${item.id}, black`)
var innerEvent = { eventId: this.preIndex }
// 取消选中态:红变黑
var eventData = {
data: {
"colorTag": 0
}
}
emitter.emit(innerEvent, eventData)
}
this.preIndex = item.id
})
}, (item: ViewData) => JSON.stringify(item))
}.columnsTemplate('1fr 1fr')
}
}
}
@Component
export struct TapImage {
@State tapColor: Color = Color.Black;
private index: number;
private uri: Resource;
onTapIndexChange(colorTag: emitter.EventData) {
this.tapColor = colorTag.data.colorTag ? Color.Red : Color.Black
}
aboutToAppear() {
//定义事件ID
var innerEvent = { eventId: this.index }
emitter.on(innerEvent, this.onTapIndexChange.bind(this))
}
build() {
Column() {
Image(this.uri)
.objectFit(ImageFit.Cover)
.border({ width: 5, style: BorderStyle.Dotted, color: this.tapColor })
}
}
}
```
以上通知事件逻辑简单,也可以简化成三元表达式。
```
// xxx.ets
class ViewData {
title: string;
uri: Resource;
color: Color = Color.Black;
constructor(title: string, uri: Resource) {
this.title = title;
this.uri = uri
}
}
@Entry
@Component
struct Gallery2 {
dataList: Array<ViewData> = [new ViewData('flower', $r('app.media.icon')), new ViewData('OMG', $r('app.media.icon')), new ViewData('OMG', $r('app.media.icon'))]
scroller: Scroller = new Scroller()
build() {
Column() {
Grid(this.scroller) {
ForEach(this.dataList, (item: ViewData, index?: number) => {
GridItem() {
TapImage({
uri: item.uri,
index: index
})
}.aspectRatio(1)
}, (item: ViewData, index?: number) => {
return JSON.stringify(item) + index;
})
}.columnsTemplate('1fr 1fr')
}
}
}
@Component
export struct TapImage {
@StorageLink('tapIndex') tapIndex: number = -1;
@State tapColor: Color = Color.Black;
private index: number;
private uri: Resource;
build() {
Column() {
Image(this.uri)
.objectFit(ImageFit.Cover)
.onClick(() => {
this.tapIndex = this.index;
})
.border({
width: 5,
style: BorderStyle.Dotted,
color: (this.tapIndex >= 0 && this.index === this.tapIndex) ? Color.Red : Color.Black
})
}
}
}
```
# arkui子系统ChangeLog
## cl.arkui.1 用户界面外观服务接口行为变更。
4.0.10.3版本开始,系统接口setDarkMode和getDarkMode返回信息的方式和内容发生变更,需要根据适配指导进行适配。
**变更影响**
基于此前版本开发的系统应用,对返回值的处理需适配新的方式,否则会影响原有业务逻辑。
**关键的接口/组件变更**
涉及接口如下:
- setDarkMode接口在Callback调用方式下,异常情况的处理由只抛出错误码ID变更为抛出错误码ID和错误码信息;
- setDarkMode接口在Promise调用方式下,异常情况的处理由只抛出错误信息变更为抛出错误码ID和错误码信息;
- setDarkMode接口在Callback调用方式下,正常情况的第一个参数由返回0变更为返回null;
- getDarkMode接口在异常情况下由直接返回2变更为抛出异常,需要通过错误码ID和错误码信息判断报错类型。
**说明**:异常情况指参数错误、未配置权限及内部执行出错等未预期的行为,正常情况指未产生错误的预期行为。
**适配指导**
请参考[ @ohos.uiAppearance(用户界面外观)](../../../application-dev/reference/apis/js-apis-uiappearance.md)接口的API参考。
...@@ -70,4 +70,59 @@ API Version 9: Free模式显示位置 ...@@ -70,4 +70,59 @@ API Version 9: Free模式显示位置
API Version 10: Free模式显示位置与Full模式显示位置相同 API Version 10: Free模式显示位置与Full模式显示位置相同
![Navigation](figures/navigation_title_mode_free_sdk10.png) ![Navigation](figures/navigation_title_mode_free_sdk10.png)
\ No newline at end of file
## cl.arkui.3 字符串异常值默认变更
**变更影响**
包含数字的非法字符串不会解析为数字部分,而是视为非法值,按照规则设定为默认值
**示例:**
```ts
@Entry
@Component
struct GridRowExample {
@State bgColors: Color[] = [Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Pink, Color.Grey, Color.Blue, Color.Brown]
@State currentBp: string = 'unknown'
build() {
Column() {
GridRow({
columns: 5,
gutter: { x: 5, y: 10 },
breakpoints: { value: ["400vp", "600vp", "800vp"],
reference: BreakpointsReference.WindowSize },
direction: GridRowDirection.Row
}) {
ForEach(this.bgColors, (color) => {
GridCol({ span: { xs: 1, sm: 2, md: 3, lg: 4 } }) {
Row().width("100%").height("20vp")
}.borderColor(color).borderWidth(2)
})
}.width("100%").height("100%")
}.width("80pv").margin({ left: 10, top: 5, bottom: 5 }).height(200)
.border({ color: '#880606', width: 2 })
}
}
```
API Version 9:上方示例中的GridRow设定width中的"80pv"会等同于width设定字符串"80"
API Version 10: 上方示例中的GridRow的width中的"80pv"会被视为异常值,所以GridRow的width设定为默认值,相当于未设定
## cl.arkui.4 Swiper的loop属性设置非法值时使用默认值true
**变更影响**
Swiper的loop属性设置非法值时原先使用false,现更改为true
API Version 9: loop属性设置非法值时使用false
API Version 10: loop属性设置非法值时使用true
## cl.arkui.5 Swiper的翻页速度阈值由180px/s调整为1200px/s
**变更影响**
需要更快的速度才能满足翻页的条件
\ No newline at end of file
...@@ -76,3 +76,10 @@ API Version 10: Free模式显示位置与Full模式显示位置相同 ...@@ -76,3 +76,10 @@ API Version 10: Free模式显示位置与Full模式显示位置相同
**变更影响** **变更影响**
1. 将sphericalEffect、lightUpEffect与pixelStretchEffect三个高阶动效接口由public接口修改为systemapi接口,不对外部开发者暴露 1. 将sphericalEffect、lightUpEffect与pixelStretchEffect三个高阶动效接口由public接口修改为systemapi接口,不对外部开发者暴露
## cl.arkui.4 onClick事件规格变更
**变更影响**
1. 若组件同时绑定onClick/TapGesture和PanGesture,当手指滑动超出距离时,响应PanGesture不响应onClick/TapGesture
2. 若组件绑定onClick/TapGesture未绑定PanGesture,当手指在组件范围内滑动时,手指抬起响应onClick/TapGesture
3. 若组件绑定onClick/TapGesture未绑定PanGesture,当手指滑动超出组件范围时,手指抬起不响应onClick/TapGesture
\ No newline at end of file
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
- [列表上拉加载更多内容](list-pullup-loading-data.md) - [列表上拉加载更多内容](list-pullup-loading-data.md)
- [如何删除多选框选项](delete-checkboxgroup-items.md) - [如何删除多选框选项](delete-checkboxgroup-items.md)
- [像素单位转换](pixel-format-transfer.md) - [像素单位转换](pixel-format-transfer.md)
- [如何在UIAbility间进行跳转](jump-between-UIAbilities.md)
- [转场动画](transition-animation.md)
### 装饰器 ### 装饰器
- [控制页面刷新范围](overall-and-part-refresh.md) - [控制页面刷新范围](overall-and-part-refresh.md)
...@@ -40,6 +42,7 @@ ...@@ -40,6 +42,7 @@
- [如何实现沉浸模式](immersion-mode.md) - [如何实现沉浸模式](immersion-mode.md)
- [如何创建悬浮窗](float-window.md) - [如何创建悬浮窗](float-window.md)
- [保持屏幕常亮](keep-screen-on.md) - [保持屏幕常亮](keep-screen-on.md)
- [如何创建子窗口并与主窗口通信](subwindow-mainwindow-communication.md)
### 数据管理 ### 数据管理
- [用户首选项的基本使用](preferences-data-process.md) - [用户首选项的基本使用](preferences-data-process.md)
......
# UIAbility内和UIAbility间页面的跳转
## 场景介绍
UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。例如,在支付应用中,可以将入口功能和收付款功能分别配置为独立的UIAbility。
对于开发者而言,可以根据具体场景选择单个还是多个UIAbility,划分建议如下:
* 如果希望在任务视图中看到一个任务,则建议使用一个UIAbility,多个页面的方式。
* 如果希望在任务视图中看到多个任务,或者需要同时开启多个窗口,则建议使用多个UIAbility开发不同的模块功能。
本例即为大家介绍如何基于Stage模型下的UIAbility开发,实现UIAbility内和UIAbility间页面的跳转与数据传递的功能。
## 效果呈现
本例最终效果如下:
![UIAbility](figures/UIAbility.gif)
## 运行环境
本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
- IDE: DevEco Studio 4.0 Beta1
- SDK: Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)
## 实现思路
本篇案例是基于Stage模型下的UIAbility开发,实现UIAbility内和UIAbility间页面的跳转。
* UIAbility内页面的跳转:
entry模块中,通过添加页面路由router来实现,页面路由router根据页面url找到目标页面,从而实现跳转。
* UIAbility间页面的跳转--跳转到指定UIAbility的首页:
实现UIAbility间页面的跳转,需要启动另外一个UIAbility,可以通过UIAbilityContext的startAbility的方法来完成。
* UIAbility间页面的跳转--跳转到指定UIAbility的指定页面(非首页):
实现跳转到指定UIAbility的指定页面(非首页),就需要在跳转到指定UIAbility的首页的基础上,新建一个Second页面,使用UIAbilityContext.startAbilityForResult来实现。
## 开发步骤
由于本例重点介绍UIAbility之间的跳转,所以开发步骤会着重讲解相关实现,不相关的内容不做介绍,全量代码可参考完整代码章节。
1. 从实现效果看,UIAbility之间的跳转,都是通过点击每个页面的button后实现的,因此我们可以先构建一个按钮点击后调用的方法类:ButtonClickMethod。
具体代码如下:
```ts
// entry/src/main/ets/model/ButtonClickMethod.ets
...
// 按钮点击后调用的方法类
Class ButtonClickMethod{
...
}
export default new ButtonClickMethod();
```
2. UIAbility内页面的跳转。
* 实现UIAbility内页面的跳转,首先构建Index页面,Index页面由一个Image组件、两个Text组件、三个Button组件组成。
具体代码如下:
```ts
// entry/src/main/ets/pages/Index.ets
@Entry
@Component
struct Index {
@State text: string = '';
build() {
Column() {
Image($r('app.media.right'))
...
Text($r('app.string.main_index_page_name'))
...
// 条件渲染:当text的值不为空时,显示该组件
if (this.text !== '') {
Text(this.text)
...
}
// 导航到EntryAbility的Second Page按钮
Button($r('app.string.to_main_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
// 导航到SecondAbility的Index Page按钮
Button($r('app.string.to_second_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
// 导航到SecondAbility的Index Page按钮
Button($r('app.string.to_second_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
}
...
}
}
```
* 构建Second页面,该页面由一个Image组件、两个Text组件、一个Button组件组成。
具体代码如下:
```ts
// entry/src/main/ets/pages/Second.ets
@Entry
@Component
struct Second {
...
build() {
Column() {
Image($r('app.media.left'))
...
Text($r('app.string.main_second_page_name'))
...
Text(`${this.src}${this.count}`)
...
// 返回到EntryAbility的Index Page按钮
Button($r('app.string.back_main_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
}
...
}
}
```
* entry模块的Index和Second页面之间的跳转以及数据的传递,需要通过router来实现。
* 从EntryAbility首页跳转到Second页面:
1. 导入router模块, 向按钮点击后调用的方法类ButtonClickMethod中添加toEntryAbilitySecond方法,使用router.pushUrl实现跳转,同时通过params来向新页面传入参数。
具体代码如下:
```ts
// entry/src/main/ets/model/ButtonClickMethod.ets
import router from '@ohos.router';
// 按钮点击后调用的方法类
Class ButtonClickMethod{
// 导航entry模块的Second页面
toEntryAbilitySecond() {
router.pushUrl({
url: 'pages/Second',
params: {
src: textMessage,
count: CommonConstants.NUM_VALUES[0]
}
});
}
...
}
export default new ButtonClickMethod();
```
2. 点击“导航到EntryAbility的Second Page”按钮后,调用ButtonClickMethod类中的toEntryAbilitySecond方法,跳转到EntryAbility的Second页面。
具体代码如下:
```ts
// entry/src/main/ets/pages/Index.ets
...
@Entry
@Component
struct Index {
@State text: string = '';
@State bottomMargin: string = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
build() {
Column() {
Image($r('app.media.right'))
...
Text($r('app.string.main_index_page_name'))
...
// 条件渲染:当text的值不为空时,显示该组件
if (this.text !== '') {
Text(this.text)
...
}
Button($r('app.string.to_main_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
.onClick(() => {
// 导航到EntryAbility的Second Page
ButtonClickMethod.toSecondAbilityIndex(context);
this.text = '';
this.bottomMargin = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
})
Button($r('app.string.to_second_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
Button($r('app.string.to_second_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
}
...
}
}
```
* 从entry模块的EntryAbility的Second页面返回至EntryAbility首页:
向EntryAbility的Second页面导入router模块,同时给button添加oncClick事件,使用router.back实现返回至EntryAbility的index页面。
具体代码如下:
```ts
// entry/src/main/ets/pages/Second.ets
import router from '@ohos.router';
@Entry
@Component
struct Second {
...
build() {
Column() {
Image($r('app.media.left'))
...
Text($r('app.string.main_second_page_name'))
...
Text(`${this.src}${this.count}`)
...
Button($r('app.string.back_main_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
.onClick(() => {
// 返回到EntryAbility的Index Page
router.back();
})
}
...
}
}
```
3. 跳转到指定的UIAbility的首页。
* 实现跳转到指定UIAbility的首页,先构建另外一个模块,方法如下:
在“Project”窗口,右键点击“entry 文件夹”,选择“New > Module > Empty Ability > Next”,在“Module name”中给新建的模块命名为“device”,点击“Next”,在“Ability name”中给新建模块的Ability命名为“SecondAbility”,点击“Finish”。可以看到文件目录结构如下:
![device-modules](figures/device-module.png)
* 构建device模块下SecondAbility的Index页面,该页面由一个Image组件、两个Text组件、一个Button组件组成。
具体代码如下:
```ts
// device/src/main/ets/pages/Index.ets
@Entry
@Component
struct Index {
...
build() {
Column() {
Image($r('app.media.left'))
...
Text($r('app.string.second_index_page_name'))
...
Text(`${this.src}${this.count}`)
...
// 停止SecondAbility自身按钮
Button($r('app.string.terminate_second_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
}
...
}
}
```
* 从entry模块的EntryAbility首页跳转至device模块的SecondAbility首页:需要通过UIAbilityContext的startAbility方法来实现。
1. 在EntryAbility的Index页面获取UIAbilityContext。
> 使用UIAbilityContext中的方法,需要在对应的页面获取相应的UIAbilityContext。
具体代码如下:
```ts
// entry/src/main/ets/pages/Index.ets
...
// 获取UIAbilityContext
let context = getContext(this);
...
```
2. 在EntryAbility的Index页面中,点击“导航到SecondAbility的Index Page”按钮后,调用ButtonClickMethod类中的toSecondAbilityIndex方法,拉起SecondAbility的Index页面,同时通过params来向新页面传入参数。
* 向ButtonClickMethod类中添加toSecondAbilityIndex方法。
具体代码如下:
```ts
// entry/src/main/ets/model/ButtonClickMethod.ets
import router from '@ohos.router';
import Logger from '../common/utils/Logger';
// 按钮点击后调用的方法类
Class ButtonClickMethod{
...
// 导航device模块的Index页面
toSecondAbilityIndex(context) {
let want = {
'deviceId': '',
'bundleName': 'com.example.uiability',
'abilityName': 'SecondAbility',
'moduleName':'device',
'parameters': {
src: textMessage,
count: 45
}
};
context.startAbility(want).then(() => {
Logger.info(CommonConstants.TAG, `start second ability index page succeed with ${JSON.stringify(want)}`);
}).catch((error) => {
Logger.error(CommonConstants.TAG, `start second ability index page failedwith ${error.code}`);
});
}
...
}
export default new ButtonClickMethod();
```
* 在EntryAbility的Index页面中,给“导航到SecondAbility的Index Page”按钮添加onClick事件,调用ButtonClickMethod类中的toSecondAbilityIndex方法,实现到SecondAbility首页的跳转。
具体代码如下:
```ts
// entry/src/main/ets/pages/Index.ets
...
// 获取UIAbilityContext
let context = getContext(this);
@Entry
@Component
struct Index {
@State text: string = '';
@State bottomMargin: string = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
build() {
Column() {
Image($r('app.media.right'))
...
Text($r('app.string.main_index_page_name'))
...
// 条件渲染:当text的值不为空时,显示该组件
if (this.text !== '') {
Text(this.text)
...
}
Button($r('app.string.to_main_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
Button($r('app.string.to_second_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
.onClick(() => {
// 导航到SecondAbility的Index页面
ButtonClickMethod.toSecondAbilityIndex(context);
this.text = '';
this.bottomMargin = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
})
Button($r('app.string.to_second_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
}
...
}
}
```
* 在SecondAbility的Index页面,获取从EntryAbility的Index页面传递过来的自定义参数,并用一个Text文本展示从Index页面传递过来的数据。
具体代码如下:
```ts
// device/src/main/ets/pages/Index.ets
...
@Entry
@Component
struct Index {
// 获取从EntryAbility的Index页面传递过来的自定义参数
@State src: string = globalThis?.secondAbilityWant?.parameters?.src ?? '-';
@State count: number = globalThis?.secondAbilityWant?.parameters?.count ?? 0;
build() {
Column() {
Image($r('app.media.left'))
...
Text($r('app.string.second_index_page_name'))
...
// 用一个Text文本展示从Index页面传递过来的数据
Text(`${this.src}:${this.count}`)
...
// 停止SecondAbility自身按钮
Button($r('app.string.terminate_second_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
}
...
}
}
```
* 从device模块的SecondAbility首页返回到entry模块的EntryAbility首页:通过点击device模块的Index页面的“停止SecondAbility自身”按钮,使用UIAbilityContext.terminateSelf方法手动销毁Ability。
1. 给ButtonClickMethod类中添加toSecondAbilityIndex方法。
具体代码如下:
```ts
// entry/src/main/ets/model/ButtonClickMethod.ets
import router from '@ohos.router';
import Logger from '../common/utils/Logger';
// 按钮点击后调用的方法类
Class ButtonClickMethod{
...
// 停止SecondAbility自身
terminateSecondAbility(context) {
context.terminateSelf().then(() => {
Logger.info(CommonConstants.TAG, 'terminate second ability self succeed');
}).catch((error) => {
Logger.error(CommonConstants.TAG, `terminate second ability self failed with ${error.code}`);
});
}
...
}
export default new ButtonClickMethod();
```
2. 在SecondAbility的Index页面中,给“停止SecondAbility自身”按钮添加onClick事件,调用ButtonClickMethod类中的terminateSecondAbility方法,使用UIAbilityContext.terminateSelf方法手动销毁Ability,从而实现从SecondAbility的Index页面返回至entry的Index页面。
具体代码如下:
```ts
// device/src/main/ets/model/Index.ets
let context = getContext(this);
...
@Entry
@Component
struct Index {
// 获取从EntryAbility的Index页面传递过来的自定义参数
@State src: string = globalThis?.secondAbilityWant?.parameters?.src ?? '-';
@State count: number = globalThis?.secondAbilityWant?.parameters?.count ?? 0;
build() {
Column() {
Image($r('app.media.left'))
...
Text($r('app.string.second_index_page_name'))
...
// 用一个Text文本展示从EntryAbility的Index页面传递过来的数据
Text(`${this.src}:${this.count}`)
...
Button($r('app.string.terminate_second_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
.onClick(() => {
// 停止SecondAbility自身
ButtonClickMethod.terminateSecondAbility(context);
})
}
...
}
}
```
4. 跳转到指定UIAbility的指定页面(非首页)。
* 构建device模块下SecondAbility的Second页面。该页面由一个Image组件、两个Text组件、一个Button组件组成。
具体代码如下:
```ts
// device/src/main/ets/pages/Second.ets
@Entry
@Component
struct Index {
...
build() {
Column() {
Image($r('app.media.left'))
...
Text($r('app.string.second_second_page_name'))
...
// 用一个Text文本展示从EntryAbility的Index页面传递过来的数据
Text(`${this.src}${this.count}`)
...
// 停止SecondAbility自身且返回结果按钮
Button($r('app.string.terminate_second_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
}
...
}
}
```
* 从entry模块的EntryAbility的首页跳转至device模块的SecondAbility的Second页面:通过点击“导航到SecondAbility的Second Page”按钮后,调用ButtonClickMethod类中的toSecondAbilitySecond方法,拉起SecondAbility的Second页面。
1. 给ButtonClickMethod类中添加toSecondAbilitySecond方法,该方法中使用UIAbilityContext.startAbilityForResult来实现,并获取被拉起侧销毁后的返回结果。可以通过parameters来向被拉起方传递参数。
具体代码如下:
```ts
// entry/src/main/ets/model/ButtonClickMethod.ets
import router from '@ohos.router';
import Logger from '../common/utils/Logger';
let currentContext = getContext(this);
// 按钮点击后调用的方法类
Class ButtonClickMethod{
...
// 导航到SecondAbility的Second页面
toSecondAbilitySecond(context, callback) {
let want = {
'deviceId': '',
'bundleName': 'com.example.uiability',
'abilityName': 'SecondAbility',
'moduleName':'device',
'parameters': {
url: 'pages/Second',
src: textMessage,
count: 78
}
};
// 被拉起侧销毁后,在startAbilityForResult回调中可以获取到被拉起侧销毁时传递过来的AbilityResult
context.startAbilityForResult(want).then((result) => {
callback(result);
Logger.info(CommonConstants.TAG, `start second ability second page succeed with ${JSON.stringify(want)}`);
}).catch((error) => {
Logger.error(CommonConstants.TAG, `start second ability second page failed with ${error.code}`);
});
}
...
}
export default new ButtonClickMethod();
```
2. 在EntryAbility的Index页面中,给“导航到SecondAbility的Second Page”按钮添加onClick事件,调用ButtonClickMethod类中的toSecondAbilityIndex方法,实现到SecondAbility首页的跳转。
具体代码如下:
```ts
// entry/src/main/ets/pages/Index.ets
...
// 获取UIAbilityContext
let context = getContext(this);
@Entry
@Component
struct Index {
@State text: string = '';
@State bottomMargin: string = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
build() {
Column() {
Image($r('app.media.right'))
...
Text($r('app.string.main_index_page_name'))
...
// 条件渲染:当text的值不为空时,显示该组件
if (this.text !== '') {
Text(this.text)
...
}
Button($r('app.string.to_main_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
Button($r('app.string.to_second_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
Button($r('app.string.to_second_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
.onClick(() => {
this.text = '';
this.bottomMargin = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
// 导航到SecondAbility的Second页面
ButtonClickMethod.toSecondAbilitySecond(context, (abilityResult) => {
// 获取SecondAbility被销毁时传递的abilityResult
if (abilityResult.resultCode === CommonConstants.RESULT_CODE) {
let src: string = abilityResult?.want?.parameters?.src ?? '-';
let count: number = abilityResult?.want?.parameters?.count ?? 0;
this.text = `${src}${count}`;
this.bottomMargin = StyleConstants.BUTTON_MARGIN_BOTTOM;
}
});
})
}
...
}
}
```
* 从device模块的SecondAbility的Second页面,返回至entry模块的EntryAbility首页:通过点击“停止SecondAbility自身并返回结果”按钮,调用ButtonClickMethod类中的terminateSecondAbilityForResult方法,使用UIAbilityContext.terminateSelfWithResult方法,同时传入不同的resultCode和want,手动销毁Ability,成功后拉起侧会收到abilityResult的值, 通过Text的方式显示在界面上,从而实现从SecondAbility的Second页面返回至entry的Index页面。
1. 给ButtonClickMethod类中添加terminateSecondAbilityForResult方法。
具体代码如下:
```ts
// entry/src/main/ets/model/ButtonClickMethod.ets
import router from '@ohos.router';
import Logger from '../common/utils/Logger';
// 按钮点击后调用的方法类
Class ButtonClickMethod{
...
// 停止SecondAbility自身
terminateSecondAbilityForResult(context) {
let abilityResult = {
resultCode: CommonConstants.RESULT_CODE,
want: {
'parameters': {
src: returnMessage,
count: 99
}
}
};
// 停止SecondAbility自身,并将abilityResult返回给startAbilityForResult接口调用方
context.terminateSelfWithResult(abilityResult).then(() => {
Logger.info(CommonConstants.TAG, `terminate second ability self succeed with ${JSON.stringify(abilityResult)}`);
}).catch((error) => {
Logger.error(CommonConstants.TAG, `terminate second ability self failed with ${error.code}`);
});
}
...
}
export default new ButtonClickMethod();
```
2. 在SecondAbility的Index页面中,给“停止SecondAbility自身并返回结果”按钮添加onClick事件,调用ButtonClickMethod类中的terminateSecondAbilityForResult方法,手动销毁自身Ability。
具体代码如下:
```ts
// device/src/main/ets/pages/Second.ets
let context = getContext(this);
@Entry
@Component
struct Second {
// 用来接收parameters参数传过来的值
@State src: string = globalThis?.secondAbilityWant?.parameters?.src ?? '-';
@State count: number = globalThis?.secondAbilityWant?.parameters?.count ?? 0;
build() {
Column() {
Image($r('app.media.left'))
...
Text($r('app.string.second_second_page_name'))
...
Text(`${this.src}${this.count}`)
..
// 停止SecondAbility自身且返回结果按钮
Button($r('app.string.terminate_second_for_result_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
.onClick(() => {
// 停止SecondAbility自身且返回结果.
ButtonClickMethod.terminateSecondAbilityForResult(context);
})
}
...
}
}
```
## 完整代码
本例完整代码如下:
1. entry模块的代码:
* 公共常量类:entry/src/main/ets/common/constants/CommonConstants.ets
具体代码如下:
```ts
class CommonConstants {
TAG = '[ButtonClickMethod.ts]';
RESULT_CODE = 100;
}
export default new CommonConstants();
```
* 样式常量类:entry/src/main/ets/common/constants/StyleConstants.ets
具体代码如下:
```ts
class StyleConstants {
IMAGE_WIDTH = '78%';
IMAGE_HEIGHT = '25%';
IMAGE_MARGIN_TOP = '140vp';
IMAGE_MARGIN_BOTTOM = '55vp';
MAIN_INDEX_TEXT_MARGIN_BOTTOM = '148vp';
BUTTON_WIDTH = '87%';
BUTTON_HEIGHT = '5%';
BUTTON_MARGIN_BOTTOM = '12vp';
MAIN_INDEX_BUTTON_MARGIN_BOTTOM = '179vp';
TEXT_MARGIN_BOTTOM = '250vp';
FULL_PERCENT = '100%';
FONT_SIZE_BIG = 20;
FONT_WEIGHT = 500;
FONT_SIZE_SMALL = 16;
OPACITY = 0.6;
}
export default new StyleConstants();
```
* 按钮点击后调用的方法类:entry/src/main/ets/model/ButtonClickMethod.ets
具体代码如下:
```ts
import router from '@ohos.router';
import Logger from '../common/utils/Logger';
import CommonConstants from '../common/constants/CommonConstants';
let currentContext = getContext(this);
let textMessage: string = currentContext.resourceManager.getStringSync($r('app.string.text_message'));
let returnMessage: string = currentContext.resourceManager.getStringSync($r('app.string.return_message'));
// 按钮点击后调用的方法类
class ButtonClickMethod {
// 导航entry模块的Second页面
toEntryAbilitySecond() {
router.pushUrl({
url: 'pages/Second',
params: {
src: textMessage,
count: 12
}
});
}
// 导航device模块的Index页面
toSecondAbilityIndex(context) {
let want = {
'deviceId': '',
'bundleName': 'com.example.uiability',
'abilityName': 'SecondAbility',
'moduleName':'device',
'parameters': {
src: textMessage,
count: 45
}
};
context.startAbility(want).then(() => {
Logger.info(CommonConstants.TAG, `start second ability index page succeed with ${JSON.stringify(want)}`);
}).catch((error) => {
Logger.error(CommonConstants.TAG, `start second ability index page failedwith ${error.code}`);
});
}
// 导航到SecondAbility的Second页面
toSecondAbilitySecond(context, callback) {
let want = {
'deviceId': '',
'bundleName': 'com.example.uiability',
'abilityName': 'SecondAbility',
'moduleName':'device',
'parameters': {
url: 'pages/Second',
src: textMessage,
count: 78
}
};
// 被拉起侧销毁后,在startAbilityForResult回调中可以获取到被拉起侧销毁时传递过来的AbilityResult
context.startAbilityForResult(want).then((result) => {
callback(result);
Logger.info(CommonConstants.TAG, `start second ability second page succeed with ${JSON.stringify(want)}`);
}).catch((error) => {
Logger.error(CommonConstants.TAG, `start second ability second page failed with ${error.code}`);
});
}
// 停止SecondAbility自身
terminateSecondAbility(context) {
context.terminateSelf().then(() => {
Logger.info(CommonConstants.TAG, 'terminate second ability self succeed');
}).catch((error) => {
Logger.error(CommonConstants.TAG, `terminate second ability self failed with ${error.code}`);
});
}
// 停止SecondAbility自身并返回结果
terminateSecondAbilityForResult(context) {
let abilityResult = {
resultCode: CommonConstants.RESULT_CODE,
want: {
'parameters': {
src: returnMessage,
count: 99
}
}
};
// 停止SecondAbility自身,并将abilityResult返回给startAbilityForResult接口调用方
context.terminateSelfWithResult(abilityResult).then(() => {
Logger.info(CommonConstants.TAG, `terminate second ability self succeed with ${JSON.stringify(abilityResult)}`);
}).catch((error) => {
Logger.error(CommonConstants.TAG, `terminate second ability self failed with ${error.code}`);
});
}
}
export default new ButtonClickMethod();
```
* EntryAbility的Index页面:entry/src/main/ets/pages/Index.ets
具体代码如下:
```ts
import ButtonClickMethod from '../model/ButtonClickMethod';
import StyleConstants from '../common/constants/StyleConstants';
import CommonConstants from '../common/constants/CommonConstants';
// 获取EntryAbility的UIAbilityContext
let context = getContext(this);
@Entry
@Component
struct Index {
@State text: string = '';
@State bottomMargin: string = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
build() {
Column() {
Image($r('app.media.right'))
.objectFit(ImageFit.Contain)
.width(StyleConstants.IMAGE_WIDTH)
.height(StyleConstants.IMAGE_HEIGHT)
.margin({
top: StyleConstants.IMAGE_MARGIN_TOP,
bottom: StyleConstants.IMAGE_MARGIN_BOTTOM
})
Text($r('app.string.main_index_page_name'))
.fontColor('#000')
.fontSize(StyleConstants.FONT_SIZE_BIG)
.fontWeight(StyleConstants.FONT_WEIGHT)
.margin({ bottom: this.bottomMargin })
// 条件渲染:当text的值不为空时,显示该组件
if (this.text !== '') {
Text(this.text)
.fontColor('#000')
.fontSize(StyleConstants.FONT_SIZE_SMALL)
.opacity(StyleConstants.OPACITY)
.margin({ bottom: StyleConstants.MAIN_INDEX_TEXT_MARGIN_BOTTOM })
}
// 导航到EntryAbility的Second Page按钮
Button($r('app.string.to_main_second_page_btn_text'),{ type: ButtonType.Capsule, stateEffect: true })
.backgroundColor($r('app.color.button_background_color'))
.width(StyleConstants.BUTTON_WIDTH)
.height(StyleConstants.BUTTON_HEIGHT)
.margin({ bottom: StyleConstants.BUTTON_MARGIN_BOTTOM })
.onClick(() => {
// 导航到EntryAbility的Second page
ButtonClickMethod.toEntryAbilitySecond();
this.text = '';
this.bottomMargin = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
})
// 导航到SecondAbility的Index Page按钮
Button($r('app.string.to_second_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
.backgroundColor($r('app.color.button_background_color'))
.width(StyleConstants.BUTTON_WIDTH)
.height(StyleConstants.BUTTON_HEIGHT)
.margin({ bottom: StyleConstants.BUTTON_MARGIN_BOTTOM })
.onClick(() => {
// 导航到SecondAbility的Index Page
ButtonClickMethod.toSecondAbilityIndex(context);
this.text = '';
this.bottomMargin = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
})
// 导航到SecondAbility的Index Page按钮
Button($r('app.string.to_second_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
.backgroundColor($r('app.color.button_background_color'))
.width(StyleConstants.BUTTON_WIDTH)
.height(StyleConstants.BUTTON_HEIGHT)
.onClick(() => {
this.text = '';
this.bottomMargin = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
// 导航到SecondAbility的Second Page
ButtonClickMethod.toSecondAbilitySecond(context, (abilityResult) => {
// 获取SecondAbility被销毁时传递的abilityResult
if (abilityResult.resultCode === CommonConstants.RESULT_CODE) {
let src: string = abilityResult?.want?.parameters?.src ?? '-';
let count: number = abilityResult?.want?.parameters?.count ?? 0;
this.text = `${src}${count}`;
this.bottomMargin = StyleConstants.BUTTON_MARGIN_BOTTOM;
}
});
})
}
.width(StyleConstants.FULL_PERCENT)
.height(StyleConstants.FULL_PERCENT)
.backgroundColor($r('app.color.background_color'))
}
}
```
* EntryAbility的Second页面:entry/src/main/ets/pages/Second.ets
具体代码如下:
```ts
import router from '@ohos.router';
import StyleConstants from '../common/constants/StyleConstants';
@Entry
@Component
struct Second {
@State src: string = router?.getParams()?.['src'] ?? '-';
@State count: number = router?.getParams()?.['count'] ?? 0;
build() {
Column() {
Image($r('app.media.left'))
.objectFit(ImageFit.Contain)
.width(StyleConstants.IMAGE_WIDTH)
.height(StyleConstants.IMAGE_HEIGHT)
.margin({
top: StyleConstants.IMAGE_MARGIN_TOP,
bottom: StyleConstants.IMAGE_MARGIN_BOTTOM
})
Text($r('app.string.main_second_page_name'))
.fontColor('#000')
.fontSize(StyleConstants.FONT_SIZE_BIG)
.fontWeight(StyleConstants.FONT_WEIGHT)
.margin({ bottom: StyleConstants.BUTTON_MARGIN_BOTTOM })
// 用一个Text文本展示从EntryAbility的Index页面传递过来的数据
Text(`${this.src}${this.count}`)
.fontColor('ccc')
.fontSize(StyleConstants.FONT_SIZE_SMALL)
.opacity(StyleConstants.OPACITY)
.margin({ bottom: StyleConstants.TEXT_MARGIN_BOTTOM })
// 返回到EntryAbility的Index Page按钮
Button($r('app.string.back_main_index_page_btn_text'),{ type: ButtonType.Capsule, stateEffect: true })
.backgroundColor($r('app.color.button_background_color'))
.width(StyleConstants.BUTTON_WIDTH)
.height(StyleConstants.BUTTON_HEIGHT)
.onClick(() => {
// 返回到EntryAbility的Index Page
router.back();
})
}
.width(StyleConstants.FULL_PERCENT)
.height(StyleConstants.FULL_PERCENT)
.backgroundColor($r('app.color.background_color'))
}
}
```
2. device模块的代码:
* SecondAbility的Index页面:device/src/main/ets/pages/Index.ets
具体代码如下:
```ts
import ButtonClickMethod from '../../../../../entry/src/main/ets/model/ButtonClickMethod';
import StyleConstants from '../../../../../entry/src/main/ets/common/constants/StyleConstants';
// 获取SecondAbility的UIAbilityContext
let context = getContext(this);
@Entry
@Component
struct Index {
// 获取从EntryAbility的Index页面传递过来的自定义参数
@State src: string = globalThis?.secondAbilityWant?.parameters?.src ?? '-';
@State count: number = globalThis?.secondAbilityWant?.parameters?.count ?? 0;
build() {
Column() {
Image($r('app.media.left'))
.objectFit(ImageFit.Contain)
.width(StyleConstants.IMAGE_WIDTH)
.height(StyleConstants.IMAGE_HEIGHT)
.margin({
top: StyleConstants.IMAGE_MARGIN_TOP,
bottom: StyleConstants.IMAGE_MARGIN_BOTTOM
})
// 用一个Text文本展示从EntryAbility的Index页面传递过来的数据
Text($r('app.string.second_index_page_name'))
.fontColor('#000')
.fontSize(StyleConstants.FONT_SIZE_BIG)
.fontWeight(StyleConstants.FONT_WEIGHT)
.margin({ bottom: StyleConstants.BUTTON_MARGIN_BOTTOM })
// 用一个Text文本展示从Index页面传递过来的数据
Text(`${this.src}${this.count}`)
.fontColor('#000')
.fontSize(StyleConstants.FONT_SIZE_SMALL)
.opacity(StyleConstants.OPACITY)
.margin({ bottom: StyleConstants.TEXT_MARGIN_BOTTOM })
// 停止SecondAbility自身按钮
Button($r('app.string.terminate_second_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
.backgroundColor($r('app.color.button_background_color'))
.width(StyleConstants.BUTTON_WIDTH)
.height(StyleConstants.BUTTON_HEIGHT)
.onClick(() => {
// 停止SecondAbility自身
ButtonClickMethod.terminateSecondAbility(context);
})
}
.width(StyleConstants.FULL_PERCENT)
.height(StyleConstants.FULL_PERCENT)
.backgroundColor($r('app.color.background_color'))
}
}
```
* SecondAbility的Second页面:device/src/main/ets/pages/Second.ets
具体代码如下:
```ts
import ButtonClickMethod from '../../../../../entry/src/main/ets/model/ButtonClickMethod';
import StyleConstants from '../../../../../entry/src/main/ets/common/constants/StyleConstants';
let context = getContext(this);
@Entry
@Component
struct Second {
// 用来接收parameters参数传过来的值
@State src: string = globalThis?.secondAbilityWant?.parameters?.src ?? '-';
@State count: number = globalThis?.secondAbilityWant?.parameters?.count ?? 0;
build() {
Column() {
Image($r('app.media.left'))
.objectFit(ImageFit.Contain)
.width(StyleConstants.IMAGE_WIDTH)
.height(StyleConstants.IMAGE_HEIGHT)
.margin({
top: StyleConstants.IMAGE_MARGIN_TOP,
bottom: StyleConstants.IMAGE_MARGIN_BOTTOM
})
Text($r('app.string.second_second_page_name'))
.fontColor('#000')
.fontSize(StyleConstants.FONT_SIZE_BIG)
.fontWeight(StyleConstants.FONT_WEIGHT)
.margin({ bottom: StyleConstants.BUTTON_MARGIN_BOTTOM })
// 用一个Text文本展示从EntryAbility的Index页面传递过来的数据
Text(`${this.src}${this.count}`)
.fontColor('#000')
.fontSize(StyleConstants.FONT_SIZE_SMALL)
.opacity(StyleConstants.OPACITY)
.margin({ bottom: StyleConstants.TEXT_MARGIN_BOTTOM })
// 停止SecondAbility自身且返回结果按钮
Button($r('app.string.terminate_second_for_result_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
.backgroundColor($r('app.color.button_background_color'))
.width(StyleConstants.BUTTON_WIDTH)
.height(StyleConstants.BUTTON_HEIGHT)
.onClick(() => {
// 停止SecondAbility自身且返回结果
ButtonClickMethod.terminateSecondAbilityForResult(context);
})
}
.width(StyleConstants.FULL_PERCENT)
.height(StyleConstants.FULL_PERCENT)
.backgroundColor($r('app.color.background_color'))
}
}
```
## 参考
- [UIAbility组件概述](../application-dev/application-models/uiability-overview.md)
- [UIAbility组件使用指导](../application-dev/reference/apis/js-apis-app-ability-uiAbility.md)
- [UIAbilityContext使用指导](../application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md)
- [router (页面路由)使用指导](../application-dev/reference/apis/js-apis-router.md)
- [Want使用指导](../application-dev/reference/apis/js-apis-application-want.md)
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
为便于理解,通过以下例子具体说明单层和多层状态变化: 为便于理解,通过以下例子具体说明单层和多层状态变化:
```ts ```ts
class ClassA { class ClassB {
public c: number; public c: number;
constructor(c: number) { constructor(c: number) {
...@@ -24,20 +24,20 @@ class ClassA { ...@@ -24,20 +24,20 @@ class ClassA {
} }
} }
class ClassB { class ClassA {
// ClassB成员变量的类型为ClassA,ClassA为被嵌套类 // ClassA成员变量的类型为ClassB,ClassB为被嵌套类
public a: ClassA; public b: ClassB;
constructor(a: ClassA) { constructor(b: ClassB) {
this.a = a; this.b = b;
} }
} }
b: ClassB a: ClassA
// 变量a为ClassB的成员变量,为第一层变量,所以变量a的状态变化即为第一层状态变化 // 变量b为ClassA的成员变量,为第一层变量,所以变量b的状态变化即为第一层状态变化
this.b.a = new ClassA(0) this.a.b = new ClassB(0)
// 变量c为被嵌套类ClassA的成员变量,变量c的状态变化即为第二层状态变化 // 变量c为被嵌套类ClassB的成员变量,变量c的状态变化即为第二层状态变化
this.b.a.c = 5 this.a.b.c = 5
``` ```
## 监听第一层状态变化 ## 监听第一层状态变化
......
...@@ -128,6 +128,7 @@ ...@@ -128,6 +128,7 @@
}); });
}; };
} }
export default new PreferenceModel();
``` ```
2. UI中主要包含两大部分:文本和输入框,按钮。将这两部分分别抽取为子组件,在主页中进行调用。具体代码如下: 2. UI中主要包含两大部分:文本和输入框,按钮。将这两部分分别抽取为子组件,在主页中进行调用。具体代码如下:
文本和输入框子组件: 文本和输入框子组件:
......
# 如何创建子窗口并与主窗口通信
## 场景介绍
应用开发过程中,经常需要创建弹窗(子窗口)用来承载跟当前内容相关的业务,比如电话应用的拨号弹窗;阅读应用中长按当前内容触发的编辑弹窗;购物应用经常出现的抽奖活动弹窗等。
本文为大家介绍如何创建子窗口并实现子窗口与主窗口的数据通信。
## 效果呈现
本例最终效果如下:
![subwindow-mainwindow-communication](figures/subwindow-mainwindow-communication.gif)
## 环境要求
本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
- IDE: DevEco Studio 4.0 Beta1
- SDK: Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)
## 实现思路
本例关键特性及实现方案如下:
- 点击“创建子窗口”按钮创建子窗口:使用window模块的createSubWindow方法创建子窗口,在创建时设置子窗口的大小、位置、内容等。
- 子窗口可以拖拽:通过gesture属性为子窗口绑定PanGesture拖拽事件,使用moveWindowTo方法将窗口移动到拖拽位置,呈现拖拽效果。
- 点击主窗口的“子窗口数据+1”按钮,子窗口中的数据加1,反之亦然,即实现主窗口和子窗口间的数据通信:将数据变量存储在AppStorage中,在主窗口和子窗口中引用该数据,并通过@StorageLink与AppStorage中的数据进行双向绑定,从而实现主窗口和子窗口之间的数据联动。
> ![icon-note.gif](../device-dev/public_sys-resources/icon-note.gif) **说明:**
> 本文使用AppStorage实现主窗口和子窗口之间的数据传递,除此之外,Emitter和EventHub等方式也可以实现,开发者可以根据实际业务需要进行选择。
## 开发步骤
由于本例重点讲解子窗口的创建以及主窗口和子窗口之间的通信,所以开发步骤会着重讲解相关内容的开发,其余内容不做赘述,全量代码可参考完整代码章节。
1. 创建子窗口。
使用createSubWindow方法创建名为“hiSubWindow”的子窗口,并设置窗口的位置、大小、显示内容。将创建子窗口的动作放在自定义成员方法showSubWindow()中,方便后续绑定到按钮上。具体代码如下:
```ts
showSubWindow() {
// 创建应用子窗口。
this.windowStage.createSubWindow("hiSubWindow", (err, data) => {
if (err.code) {
console.error('Failed to create the subwindow. Cause: ' + JSON.stringify(err));
return;
}
this.sub_windowClass = data;
console.info('Succeeded in creating the subwindow. Data: ' + JSON.stringify(data));
// 子窗口创建成功后,设置子窗口的位置
this.sub_windowClass.moveWindowTo(300, 300, (err) => {
if (err.code) {
console.error('Failed to move the window. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in moving the window.');
});
// 设置子窗口的大小
this.sub_windowClass.resize(350, 350, (err) => {
if (err.code) {
console.error('Failed to change the window size. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in changing the window size.');
});
// 为子窗口加载对应的目标页面。
this.sub_windowClass.setUIContent("pages/SubWindow",(err) => {
if (err.code) {
console.error('Failed to load the content. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in loading the content.');
// 显示子窗口。
this.sub_windowClass.showWindow((err) => {
if (err.code) {
console.error('Failed to show the window. Cause: ' + JSON.stringify(err));
return;
}
console.info('Succeeded in showing the window.');
});
this.sub_windowClass.setWindowBackgroundColor('#E8A027')
});
})
}
```
2. 实现子窗口可拖拽。
为页面内容绑定PanGesture拖拽事件,拖拽事件发生时获取到触摸点的位置信息,使用@Watch监听到位置变量的变化,然后调用窗口的moveWindowTo方法将窗口移动到对应位置,从而实现拖拽效果。
具体代码如下:
```ts
import window from '@ohos.window';
interface Position {
x: number,
y: number
}
@Entry
@Component
struct SubWindow{
...
// 创建位置变量,并使用@Watch监听,变量发生变化调用moveWindow方法移动窗口
@State @Watch("moveWindow") windowPosition: Position = { x: 0, y: 0 };
private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All });
private subWindow: window.Window
// 通过悬浮窗名称“hiSubWindow”获取到创建的悬浮窗
aboutToAppear() {
this.subWindow = window.findWindow("hiSubWindow")
}
// 将悬浮窗移动到指定位置
moveWindow() {
this.subWindow.moveWindowTo(this.windowPosition.x, this.windowPosition.y);
}
build(){
Column(){
Text(`AppStorage保存的数据:${this.storData}`)
.fontSize(12)
.margin({bottom:10})
Button('主窗口数据+1')
.fontSize(12)
.backgroundColor('#A4AE77')
.onClick(()=>{
this.storData += 1
})
}
.height('100%')
.width('100%')
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.gesture(
PanGesture(this.panOption)
.onActionStart((event: GestureEvent) => {
console.info('Pan start');
})
// 发生拖拽时,获取到触摸点的位置,并将位置信息传递给windowPosition
.onActionUpdate((event: GestureEvent) => {
this.windowPosition.x += event.offsetX;
this.windowPosition.y += event.offsetY;
})
.onActionEnd(() => {
console.info('Pan end');
})
)
}
}
```
3. 实现主窗口和子窗口间的数据通信。本例中即实现点击主窗口的“子窗口数据+1”按钮,子窗口中的数据加1,反之亦然。本例使用应用全局UI状态存储AppStorage来实现对应效果。
- 在创建窗口时触发的onWindowStageCreate回调中将自定义数据变量“data”存入AppStorage。
```ts
onWindowStageCreate(windowStage: window.WindowStage) {
// 将自定义数据变量“data”存入AppStorage
AppStorage.SetOrCreate('data', 1);
...
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
```
- 在主窗口中定义变量“storData”,并使用@StorageLink将其与AppStorage中的变量“data”进行双向绑定,这样一来,“mainData”的变化可以传导至“data”,并且该变化可以被UI框架监听到,从而完成UI状态刷新。
```ts
...
// 使用@StorageLink将"mainData"与AppStorage中的变量"data"进行双向绑定
@StorageLink('data') mainData: number = 1;
...
build() {
Row() {
Column() {
Text(`AppStorage保存的数据:${this.mainData}`)
.margin({bottom:30})
Button('子窗口数据+1')
.backgroundColor('#A4AE77')
.margin({bottom:30})
.onClick(()=>{
// 点击,storData的值加1
this.mainData += 1
})
...
}
.width('100%')
}
.height('100%')
}
```
- 在主窗口中定义变量“subData”,并使用@StorageLink将其与AppStorage中的变量“data”进行双向绑定。由于主窗口的“mainData”也与“data”进行了绑定,因此,“mainData”的值可以通过“data”传递给“subData”,反之亦然。这样就实现了主窗口和子窗口之间的数据同步。
```ts
...
// 使用@StorageLink将"subData"与AppStorage中的变量"data"进行双向绑定
@StorageLink('data') subData: number = 1;
...
build(){
Column(){
Text(`AppStorage保存的数据:${this.subData}`)
.fontSize(12)
.margin({bottom:10})
Button('主窗口数据+1')
.fontSize(12)
.backgroundColor('#A4AE77')
.onClick(()=>{
// 点击,subData的值加1
this.subData += 1
})
}
...
}
```
## 完整代码
本例完整代码如下:
EntryAbility文件代码:
```ts
// EntryAbility.ts
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import hilog from '@ohos.hilog';
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
let sub_windowClass = null;
export default class EntryAbility extends UIAbility {
destroySubWindow() {
// 销毁子窗口。当不再需要子窗口时,可根据具体实现逻辑,使用destroy对其进行销毁。
sub_windowClass.destroyWindow((err) => {
if (err.code) {
console.error('Failed to destroy the window. Cause: ' + JSON.stringify(err));
return;
}
console.info('Succeeded in destroying the window.');
});
}
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
}
onDestroy() {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage) {
// 将自定义数据变量“data”存入AppStorage
AppStorage.SetOrCreate('data', 1);
AppStorage.SetOrCreate('window', windowStage);
// 为主窗口添加加载页面
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
onWindowStageDestroy() {
this.destroySubWindow();
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground() {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground() {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
}
}
```
主窗口代码:
```ts
// Index.ets
import window from '@ohos.window';
@Entry
@Component
struct Index {
// 使用@StorageLink将"mainData"与AppStorage中的变量"data"进行双向绑定
@StorageLink('data') mainData: number = 1;
@StorageLink('window') storWindow:window.WindowStage = null
private windowStage = this.storWindow
private sub_windowClass = null
showSubWindow() {
// 创建应用子窗口。
this.windowStage.createSubWindow("hiSubWindow", (err, data) => {
if (err.code) {
console.error('Failed to create the subwindow. Cause: ' + JSON.stringify(err));
return;
}
this.sub_windowClass = data;
console.info('Succeeded in creating the subwindow. Data: ' + JSON.stringify(data));
// 子窗口创建成功后,设置子窗口的位置、大小及相关属性等。
this.sub_windowClass.moveWindowTo(300, 300, (err) => {
if (err.code) {
console.error('Failed to move the window. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in moving the window.');
});
this.sub_windowClass.resize(350, 350, (err) => {
if (err.code) {
console.error('Failed to change the window size. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in changing the window size.');
});
// 为子窗口加载对应的目标页面。
this.sub_windowClass.setUIContent("pages/SubWindow",(err) => {
if (err.code) {
console.error('Failed to load the content. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in loading the content.');
// 显示子窗口。
this.sub_windowClass.showWindow((err) => {
if (err.code) {
console.error('Failed to show the window. Cause: ' + JSON.stringify(err));
return;
}
console.info('Succeeded in showing the window.');
});
this.sub_windowClass.setWindowBackgroundColor('#E8A027')
});
})
}
build() {
Row() {
Column() {
Text(`AppStorage保存的数据:${this.mainData}`)
.margin({bottom:30})
Button('子窗口数据+1')
.backgroundColor('#A4AE77')
.margin({bottom:30})
.onClick(()=>{
// 点击,storData的值加1
this.mainData += 1
})
Button('创建子窗口')
.backgroundColor('#A4AE77')
.onClick(()=>{
// 点击弹出子窗口
this.showSubWindow()
})
}
.width('100%')
}
.height('100%')
}
}
```
子窗口代码:
```ts
// SubWindow.ets
import window from '@ohos.window';
interface Position {
x: number,
y: number
}
@Entry
@Component
struct SubWindow{
// 使用@StorageLink将"subData"与AppStorage中的变量"data"进行双向绑定
@StorageLink('data') subData: number = 1;
// 创建位置变量,并使用@Watch监听,变量发生变化调用moveWindow方法移动窗口
@State @Watch("moveWindow") windowPosition: Position = { x: 0, y: 0 };
private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All });
private subWindow: window.Window
// 通过悬浮窗名称“hiSubWindow”获取到创建的悬浮窗
aboutToAppear() {
this.subWindow = window.findWindow("hiSubWindow")
}
// 将悬浮窗移动到指定位置
moveWindow() {
this.subWindow.moveWindowTo(this.windowPosition.x, this.windowPosition.y);
}
build(){
Column(){
Text(`AppStorage保存的数据:${this.subData}`)
.fontSize(12)
.margin({bottom:10})
Button('主窗口数据+1')
.fontSize(12)
.backgroundColor('#A4AE77')
.onClick(()=>{
// 点击,subData的值加1
this.subData += 1
})
}
.height('100%')
.width('100%')
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.gesture(
PanGesture(this.panOption)
.onActionStart((event: GestureEvent) => {
console.info('Pan start');
})
// 发生拖拽时,获取到触摸点的位置,并将位置信息传递给windowPosition
.onActionUpdate((event: GestureEvent) => {
this.windowPosition.x += event.offsetX;
this.windowPosition.y += event.offsetY;
})
.onActionEnd(() => {
console.info('Pan end');
})
)
}
}
```
## 参考
- [窗口开发](../application-dev/windowmanager/application-window-stage.md)
- [AppStorage:应用全局的UI状态存储](../application-dev/quick-start/arkts-appstorage.md)
\ No newline at end of file
# 转场动画的使用(ArkTs)
## 场景介绍
日常在应用时,经常需要衔接两个场景,或者两个镜头画面之间进行切换,切换时需要呈现一种平滑过渡效果。
本例将为大家介绍下如何通过转场动画实现上述过渡效果。
## 效果呈现
本例最终效果如下:
| 场景 | 效果图 |
| ---------------------------------- | ----------------------------------------------------- |
| 页面间转场--底部滑入转场 | ![BottomTransition.gif](figures/BottomTransition.gif) |
| 页面间转场--自定义1:缩放动画转场 | ![](figures/CustomTransition.gif) |
| 页面间转场---自定义2:旋转动画转场 | ![](figures/FullCustomTransition.gif) |
| 组件内转场 | ![](figures/ComponentTransition.gif) |
| 共享元素转场 | ![](figures/SharePage.gif) |
## 运行环境
本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
- IDE: DevEco Studio 4.0 Beta1
- SDK: Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)
## 实现思路
* 构建应用首页,主要由5个相同样式的功能菜单组成,通过添加路由实现主页面与对应功能页面的链接跳转。
* 功能页面的实现
* 页面间转场
* 底部滑入转场
通过给pageTransition()方法定义入场效果PageTransitionEnter以及出场效果PageTransitionExit,同时通过设置slide属性为SlideEffect.Bottom来实现从底部滑入动效。
* 缩放动画转场
通过设置pageTransition方法,配置进行配置转场参数。
* 旋转动画转场
在FullCustomTransition.ets的Column组件中添加TransitionElement组件,并且定义pageTransition方法。给Clomn组件添加opacity、scale、rotate属性,定义变量animValue用来控制Clomn组件的动效,在PageTransitionEnter和PageTransitionExit组件中动态改变myProgress的值,从而控制动画效果。
* 组件间转场
* 通过Image、Column、Text、Button等组件构建ComponentTransition.ets页面。
* 新建一个Image组件,并且添加两个transition属性,分别用于定义组件的插入动效和移除动效,从而实现组件间的转场。
* 设置变量isShow,用来控制上述步骤中Image组件的添加和移除,同时向Button组件的onClick添加animateTo方法,来使ComponentItem子组件动效生效。
* isShow默认状态为false,删除隐藏Image组件,同时删除动效生效。
* 当isShow状态更新为true时,插入Image组件,同时插入动效生效。
* 共享转场
通过给两个页面“SharedItem”和“SharePage” 的Image组件设置sharedTransition属性来实现,两个页面的组件配置为同一个id,则转场过程中会执行共享元素转场效果。
## 开发步骤
1. 创建主界面。
添加媒体资源至resources > base > media目录下。
![Transition-animation-tree.png](figures/Transition-animation-tree.png)
首页Index.ets引入首页列表常量数据:INDEX_ANIMATION_MODE(imgRes:设置按钮的背景图片,url:设置页面路由的地址),通过ForEach方法循环渲染列表常量数据。
具体代码如下:
```ts
// entry/src/main/ets/pages/Index.ets
// 引入列表常量数据INDEX_ANIMATION_MODE
export const INDEX_ANIMATION_MODE = [
{ imgRes: $r('app.media.bg_bottom_anim_transition'), url: 'pages/BottomTransition' },
{ imgRes: $r('app.media.bg_custom1_anim_transition'), url: 'pages/CustomTransition' },
{ imgRes: $r('app.media.bg_custom2_anim_transition'), url: 'pages/FullCustomTransition' },
{ imgRes: $r('app.media.bg_element_anim_transition'), url: 'pages/ComponentTransition' },
{ imgRes: $r('app.media.bg_share_anim_transition'), url: 'pages/ShareItem' }
];
...
Column() {
// ForEach循环渲染
ForEach(INDEX_ANIMATION_MODE, ({ imgRes , url }) => {
Row()
.backgroundImage(imgRes)
.backgroundImageSize(ImageSize.Cover)
.backgroundColor('#00000000')
.height(130)
.margin({ bottom: 30 })
.width('100%')
.borderRadius(32)
.onClick(() => {
router.pushUrl({ url: url })
})
}, item => JSON.stringify(item))
}
```
添加其它组件,以及样式,完成UI构建。
具体代码如下:
```ts
// entry/src/main/ets/pages/Index.ets
import router from '@ohos.router';
import hilog from '@ohos.hilog';
@Entry
@Component
struct Index {
build() {
Column() {
Text($r('app.string.main_page_title'))
.fontSize(30)
.fontWeight(FontWeight.Regular)
.width('100%')
.margin({ top: 13, bottom: 27,left: 24})
Scroll() {
Column() {
ForEach(INDEX_ANIMATION_MODE, ({ imgRes , url }) => {
Row()
.backgroundImage(imgRes)
.backgroundImageSize(ImageSize.Cover)
.backgroundColor('#00000000')
.height(130)
.margin({ bottom: 30 })
.width('100%')
.borderRadius(32)
.onClick(() => {
router.pushUrl({ url: url })
.catch(err => {
hilog.error(0xff00, '[ReadingRecorder]', `%{public}s, %{public}s`, err);
});
})
}, item => JSON.stringify(item))
}
}
.align(Alignment.Top)
.layoutWeight(1)
.scrollBar(BarState.Off)
}
.height('100%')
.backgroundColor('#F1F3F5')
.padding({left:12 , right:12})
}
}
```
2. 实现页面间转场。
* 效果1:底部滑入。
该效果的实现,主要是通过在BottomTransition.ets中设置全局pageTransition()方法,该方法中自定义入场效果PageTransitionEnter以及出场效果PageTransitionExit,同时通过设置slide属性为SlideEffect.Bottom来实现从底部滑入动效。
具体代码如下:
```ts
// entry/src/main/ets/pages/BottomTransition.ets
@Entry
@Component
struct BottomTransition {
private imgRes: string | Resource = $r('app.media.bg_transition');
private imgFit: ImageFit = ImageFit.Fill;
build() {
Column() {
Image(this.imgRes)
.objectFit(this.imgFit)
.width('100%')
.height('100%')
}
}
// 页面转场通过全局pageTransition方法进行配置转场参数
pageTransition() {
// PageTransitionEnter自定义入场效果:设置slide属性为SlideEffect.Bottom 表示入场时从屏幕下方滑入。
PageTransitionEnter({ duration: 600, curve: Curve.Smooth }).slide(SlideEffect.Bottom);
// PageTransitionExit自定义出场效果:设置slide属性为SlideEffect.Bottom 退场时从屏幕下方滑出。
PageTransitionExit({ duration: 600, curve: Curve.Smooth }).slide(SlideEffect.Bottom);
}
}
```
* 效果2:页面入场时淡入和放大,退场时从右下角滑出。
* 在CustomTransition.ets中设置全局pageTransition()方法。
* pageTransition方法中自定义入场效果PageTransitionEnter:透明度设置从0.2到1;x、y轴缩放从0变化到1。
* pageTransition方法中自定义出场效果PageTransitionExit: x、y轴的偏移量为500。
具体代码如下:
```ts
// entry/src/main/ets/pages/CustomTransition.ets
@Entry
@Component
struct CustomTransition {
private imgRes: string | Resource = $r('app.media.bg_transition');
private imgFit: ImageFit = ImageFit.Fill;
build() {
Column() {
Image(this.imgRes)
.objectFit(this.imgFit)
.width('100%')
.height('100%')
}
}
// 页面转场通过全局pageTransition方法进行配置转场参数
pageTransition() {
// 进场时透明度设置从0.2到1;x、y轴缩放从0变化到1
PageTransitionEnter({ duration: 600, curve: Curve.Smooth }).opacity(0.2).scale({ x: 0, y: 0 })
// 退场时x、y轴的偏移量为500
PageTransitionExit({ duration: 600, curve: Curve.Smooth }).translate({ x: 500, y: 500 })
}
}
```
* 效果3:页面入场时淡入和放大,同时顺时针旋转;退场时淡出和缩小,同时逆时针旋转。
* 在FullCustomTransition.ets中添加Column组件。
* 向Column组件添加属性:opacity、scale、rotate,来控制动效的淡入淡出、缩放以及旋转效果。
* 定义变量animValue用来,通过animValue值得变化来控制Column组件的动效。
* 在FullCustomTransition.ets中定义全局pageTransition()方法。
* pageTransition方法中自定义入场效果PageTransitionEnter。
​ animValue值实时变化,0 --> 1,从而渲染 入场时淡入、放大以及顺时针旋转效果。
* pageTransition方法中自定义出场效果PageTransitionExit。
​ animValue值实时变化,1 --> 0,从而渲染 出场时淡出、缩小以及逆时针旋转效果。
具体代码如下:
```ts
// entry/src/main/ets/pages/FullCustomTransition.ets
@Entry
@Component
struct FullCustomTransition {
@State animValue: number = 1;
private imgRes: string | Resource = $r('app.media.bg_transition');
private imgFit: ImageFit = ImageFit.Fill;
build() {
Column() {
Image(this.imgRes)
.objectFit(this.imgFit)
.width('100%')
.height('100%')
}
// 设置淡入、淡出效果
.opacity(this.animValue)
// 设置缩放
.scale({ x: this.animValue, y: this.animValue })
// 设置旋转角度
.rotate({
z: 1,
angle: 360 * this.animValue
})
}
// 页面转场通过全局pageTransition方法进行配置转场参数
pageTransition() {
PageTransitionEnter({ duration: 600, curve: Curve.Smooth })
// 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0 - 1)
.onEnter((type: RouteType, progress: number) => {
// 入场动效过程中,实时更新this.animValue的值
this.animValue = progress
});
PageTransitionExit({ duration: 600, curve: Curve.Smooth })
// 出场过程中会逐帧触发onExit回调,入参为动效的归一化进度(0 - 1)
.onExit((type: RouteType, progress: number) => {
// 入场动效过程中,实时更新this.animValue的值
this.animValue = 1 - progress
});
}
}
```
3. 实现组件内转场。
* 通过Image、Column、Text、Button等组件构建ComponentTransition.ets页面。
具体代码如下:
```ts
// entry/src/main/ets/pages/ComponentTransition.ets
@Entry
@Component
struct ComponentTransition {
build() {
Column() {
Row() {
Image($r('app.media.ic_public_back'))
.width(20)
.height(20)
.responseRegion({width:'100%',height: '100%'})
.onClick(() => {
router.back();
})
Text($r('app.string.Component_transition_header'))
.fontColor(Color.Black)
.fontWeight(FontWeight.Regular)
.fontSize(25)
.margin({left:18,right:18})
}
.height(30)
.width('100%')
.margin({ top: 20, bottom: 27,left: 24})
Image($r('app.media.bg_element'))
.objectFit(ImageFit.Fill)
.borderRadius(20)
.margin({ bottom: 20 })
.width('100%')
.height(300)
Button($r('app.string.Component_transition_toggle'))
.height(40)
.width(120)
.fontColor(Color.White)
.backgroundColor($r('app.color.light_blue'))
}
.padding({left:20,right:20})
.height('100%')
.width('100%')
}
}
```
* 新建一个Image组件,并且添加两个transition属性,分别用于定义组件的插入动效和移除动效,来实现组件转场间。
具体代码如下:
```ts
// entry/src/main/ets/pages/ComponentTransition.ets
...
Image($r('app.media.bg_share'))
.objectFit(ImageFit.Fill)
.borderRadius(20)
.margin({ bottom: 20 })
.height(300)
.width('100%')
// 插入动效
.transition({
type: TransitionType.Insert,
scale: { x: 0.5, y: 0.5 },
opacity: 0
})
// 删除隐藏动效
.transition({
type: TransitionType.Delete,
rotate: { x: 0, y: 1, z: 0, angle: 360 },
opacity: 0
})
```
- 设置变量isShow,用来控制上述步骤中Image组件的添加和移除,同时向Button组件的onClick添加animateTo方法,来使ComponentItem子组件动效生效。
* isShow默认状态为false,删除隐藏Image组件,同时删除动效生效。
* 当isShow状态更新为true时,插入Image组件,同时插入动效生效。
具体代码如下:
```ts
// entry/src/main/ets/pages/ComponentTransition.ets
...
@State isShow: boolean = false;
...
// isShow为True,插入Image组件,同时插入动效生效;isShow为False,删除隐藏Image组件,同时删除动效生效
if (this.isShow) {
Image($r('app.media.bg_share'))
.objectFit(ImageFit.Fill)
.borderRadius(20)
.margin({ bottom: 20 })
.height(300)
.width('100%')
// 插入动效
.transition({
type: TransitionType.Insert,
scale: { x: 0.5, y: 0.5 },
opacity: 0
})
// 删除隐藏动效
.transition({
type: TransitionType.Delete,
rotate: { x: 0, y: 1, z: 0, angle: 360 },
opacity: 0
})
}
...
Button($r('app.string.Component_transition_toggle'))
...
.onClick(() => {
animateTo({ duration: 600 }, () => {
this.isShow = !this.isShow;
})
})
```
ComponentTransition.ets的完整代码如下:
```ts
// entry/src/main/ets/pages/ComponentTransition.ets
import router from '@ohos.router';
@Entry
@Component
struct ComponentTransition {
@State isShow: boolean = false;
build() {
Column() {
// 页面title区域,含返回功能以及title显示
Row() {
Image($r('app.media.ic_public_back'))
.width(20)
.height(20)
.responseRegion({
width:'100%',
height: '100%'
})
.onClick(() => {
router.back();
})
Text($r('app.string.Component_transition_header'))
.fontColor(Color.Black)
.fontWeight(FontWeight.Regular)
.fontSize(25)
.height(300)
.margin({ left:18, right:18 })
}
.height(30)
.width('100%')
.margin({ top: 20, bottom: 27,left: 24})
// 页面内容区域
// isShow为True,插入Image组件,同时插入动效生效;isShow为False,删除隐藏Image组件,同时删除动效生效
if (this.isShow) {
Image($r('app.media.bg_share'))
.objectFit(ImageFit.Fill)
.borderRadius(20)
.margin({ bottom: 20 })
.height(300)
.width('100%')
// 插入动效
.transition({
type: TransitionType.Insert,
scale: { x: 0.5, y: 0.5 },
opacity: 0
})
// 删除隐藏动效
.transition({
type: TransitionType.Delete,
rotate: { x: 0, y: 1, z: 0, angle: 360 },
opacity: 0
})
}
Image($r('app.media.bg_element'))
.objectFit(ImageFit.Fill)
.borderRadius(20)
.margin({ bottom: 20 })
.width('100%')
.height(300)
Button($r('app.string.Component_transition_toggle'))
.height(40)
.width(120)
.fontColor(Color.White)
.backgroundColor($r('app.color.light_blue'))
.onClick(() => {
animateTo({ duration: 600 }, () => {
console.log('console-- ' +this.isShow)
this.isShow = !this.isShow;
})
})
}
.padding({
left:(20),
right:(20)
})
.height('100%')
.width('100%')
}
}
```
4. 实现元素共享转场。
共享元素转场通过给组件设置sharedTransition属性来实现,两个页面的组件配置为同一个id,则转场过程中会执行共享元素转场效果。
* 通过Image、Column、Text等组件构建ShareItem.ets页面,给内容区域的Image组件设置sharedTransition属性标记该元素为共享元素,组件转场id设置为“shareID”, 同时设置共享元素转场效果。
具体代码如下:
```ts
// entry/src/main/ets/pages/ShareItem.ets
import hilog from '@ohos.hilog';
@Entry
@Component
struct ShareItem {
// 自定义页面内容区域
@Builder PreviewArea() {
Column() {
Image($r('app.media.bg_transition'))
.width('100%')
.height(300)
.borderRadius(24)
.margin({ bottom: 12 })
// 设置sharedTransition属性标记该元素为共享元素,转场id为“shareId”
.sharedTransition('shareId', {
duration: 600,
curve: Curve.Smooth,
delay: 100
})
.onClick(() => {
// 路由切换
router.pushUrl({ url: 'pages/SharePage' })
.catch(err => {
hilog.error(0xFF00, '[ReadingRecorder]', `%{public}s, %{public}s`, err);
});
})
Text($r('app.string.Share_Item_hint'))
.width('100%')
.textAlign(TextAlign.Center)
.fontSize(20)
.fontWeight(FontWeight.Regular)
.fontColor($r('app.color.share_item_content_font'))
}
.borderRadius(24)
.backgroundColor(Color.White)
.width('100%')
.padding({ top: 13, left: 12, right: 12,bottom:12})
}
build() {
Column() {
// 页面title区域,含返回功能以及title显示
Row() {
Image($r('app.media.ic_public_back'))
.width(20)
.height(20)
.responseRegion({
width:'100%',
height: '100%'
})
.onClick(() => {
router.back();
})
Text($r('app.string.Share_Item_header'))
.fontColor(Color.Black)
.fontWeight(FontWeight.Regular)
.fontSize(25)
.margin({ left:18, right:18 })
}
.height(30)
.width('100%')
.margin({ top: 20, bottom: 27,left: 24})
this.PreviewArea()
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.grey_light'))
.padding({left:12,right:12})
}
}
```
* pages/SharePage.ets页面中,给Image组件设置sharedTransition属性,同时组件转场id设置为“shareID”,从而可以共享上述步骤的转场动效。
具体代码如下:
```ts
// entry/src/main/ets/pages/SharePage.ets
@Entry
@Component
struct SharePage {
build() {
Column() {
Image($r('app.media.bg_transition'))
.objectFit(ImageFit.Fill)
.width('100%')
.height('100%')
.sharedTransition('shareId', {
duration: 600,
curve: Curve.Smooth,
delay: 100
})
}
}
}
```
## 完整代码
本例完整代码如下:
应用首页: /entry/src/main/ets/pages/Index.ets。
```ts
// entry/src/main/ets/pages/Index.ets
import router from '@ohos.router';
import hilog from '@ohos.hilog';
@Entry
@Component
struct Index {
build() {
Column() {
Text($r('app.string.main_page_title'))
.fontSize(30)
.fontWeight(FontWeight.Regular)
.width('100%')
.margin({ top: 13, bottom: 27,left: 24})
Scroll() {
Column() {
ForEach(INDEX_ANIMATION_MODE, ({ imgRes , url }) => {
Row()
.backgroundImage(imgRes)
.backgroundImageSize(ImageSize.Cover)
.backgroundColor('#00000000')
.height(130)
.margin({ bottom: 30 })
.width('100%')
.borderRadius(32)
.onClick(() => {
router.pushUrl({ url: url })
.catch(err => {
hilog.error(0xff00, '[ReadingRecorder]', `%{public}s, %{public}s`, err);
});
})
}, item => JSON.stringify(item))
}
}
.align(Alignment.Top)
.layoutWeight(1)
.scrollBar(BarState.Off)
}
.height('100%')
.backgroundColor('#F1F3F5')
.padding({left:12 , right:12})
}
}
```
底部滑出页面:/entry/src/main/ets/pages/BottomTransition.ets。
```ts
// entry/src/main/ets/pages/BottomTransition.ets
@Entry
@Component
struct BottomTransition {
private imgRes: string | Resource = $r('app.media.bg_transition');
private imgFit: ImageFit = ImageFit.Fill;
build() {
Column() {
Image(this.imgRes)
.objectFit(this.imgFit)
.width('100%')
.height('100%')
}
}
// 页面转场通过全局pageTransition方法进行配置转场参数
pageTransition() {
// PageTransitionEnter自定义入场效果:设置slide属性为SlideEffect.Bottom 表示入场时从屏幕下方滑入。
PageTransitionEnter({ duration: 600, curve: Curve.Smooth }).slide(SlideEffect.Bottom);
// PageTransitionExit自定义出场效果:设置slide属性为SlideEffect.Bottom 退场时从屏幕下方滑出。
PageTransitionExit({ duration: 600, curve: Curve.Smooth }).slide(SlideEffect.Bottom);
}
}
```
自定义1 缩放动画转场页面:/entry/src/main/ets/pages/CustomTransition.ets。
```ts
// entry/src/main/ets/pages/CustomTransition.ets
@Entry
@Component
struct CustomTransition {
private imgRes: string | Resource = $r('app.media.bg_transition');
private imgFit: ImageFit = ImageFit.Fill;
build() {
Column() {
Image(this.imgRes)
.objectFit(this.imgFit)
.width('100%')
.height('100%')
}
}
// 页面转场通过全局pageTransition方法进行配置转场参数
pageTransition() {
// 进场时透明度设置从0.2到1;x、y轴缩放从0变化到1
PageTransitionEnter({ duration: 600, curve: Curve.Smooth }).opacity(0.2).scale({ x: 0, y: 0 })
// 退场时x、y轴的偏移量为500
PageTransitionExit({ duration: 600, curve: Curve.Smooth }).translate({ x: 500, y: 500 })
}
}
```
自定义2 旋转动画转场: /entry/src/main/ets/pages/FullCustomTransition.ets。
```ts
@Entry
@Component
struct FullCustomTransition {
@State animValue: number = 1;
private imgRes: string | Resource = $r('app.media.bg_transition');
private imgFit: ImageFit = ImageFit.Fill;
build() {
Column() {
Image(this.imgRes)
.objectFit(this.imgFit)
.width('100%')
.height('100%')
}
// 设置淡入、淡出效果
.opacity(this.animValue)
// 设置缩放
.scale({ x: this.animValue, y: this.animValue })
// 设置旋转角度
.rotate({
z: 1,
angle: 360 * this.animValue
})
}
// 页面转场通过全局pageTransition方法进行配置转场参数
pageTransition() {
PageTransitionEnter({ duration: 600, curve: Curve.Smooth })
// 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0 - 1)
.onEnter((type: RouteType, progress: number) => {
// 入场动效过程中,实时更新this.animValue的值
this.animValue = progress
});
PageTransitionExit({ duration: 600, curve: Curve.Smooth })
// 出场过程中会逐帧触发onExit回调,入参为动效的归一化进度(0 - 1)
.onExit((type: RouteType, progress: number) => {
// 入场动效过程中,实时更新this.animValue的值
this.animValue = 1 - progress
});
}
}
```
组件内转场页面: /entry/src/main/ets/pages/ComponentTransition.ets。
```ts
import router from '@ohos.router';
@Entry
@Component
struct ComponentTransition {
@State isShow: boolean = false;
build() {
Column() {
// 页面title区域,含返回功能以及title显示
Row() {
Image($r('app.media.ic_public_back'))
.width(20)
.height(20)
.responseRegion({
width:'100%',
height: '100%'
})
.onClick(() => {
router.back();
})
Text($r('app.string.Component_transition_header'))
.fontColor(Color.Black)
.fontWeight(FontWeight.Regular)
.fontSize(25)
.margin({left:18, right:18})
}
.height(30)
.width('100%')
.margin({ top: 20, bottom: 27,left: 24})
// 页面内容区域
// isShow为True,插入Image组件,同时插入动效生效;isShow为False,删除隐藏Image组件,同时删除动效生效
if (this.isShow) {
Image($r('app.media.bg_share'))
.objectFit(ImageFit.Fill)
.borderRadius(20)
.margin({ bottom: 20 })
.height(300)
.width('100%')
// 插入动效
.transition({
type: TransitionType.Insert,
scale: { x: 0.5, y: 0.5 },
opacity: 0
})
// 删除隐藏动效
.transition({
type: TransitionType.Delete,
rotate: { x: 0, y: 1, z: 0, angle: 360 },
opacity: 0
})
}
Image($r('app.media.bg_element'))
.objectFit(ImageFit.Fill)
.borderRadius(20)
.margin({ bottom: 20 })
.width('100%')
.height(300)
Button($r('app.string.Component_transition_toggle'))
.height(40)
.width(120)
.fontColor(Color.White)
.backgroundColor($r('app.color.light_blue'))
.onClick(() => {
animateTo({ duration: 600 }, () => {
this.isShow = !this.isShow;
})
})
}
.padding({left:20,right:20})
.height('100%')
.width('100%')
}
}
```
共享元素转场部件:/entry/src/main/ets/pages/ShareItem.ets。
```ts
import hilog from '@ohos.hilog';
@Entry
@Component
struct ShareItem {
// 自定义页面内容区域
@Builder PreviewArea() {
Column() {
Image($r('app.media.bg_transition'))
.width('100%')
.height(300)
.borderRadius(24)
.margin({ bottom: 12 })
// 设置sharedTransition属性标记该元素为共享元素,转场id为“shareId”
.sharedTransition('shareId', {
duration: 600,
curve: Curve.Smooth,
delay: 100
})
.onClick(() => {
// 路由切换
router.pushUrl({ url: 'pages/SharePage' })
.catch(err => {
hilog.error(0xFF00, '[ReadingRecorder]', `%{public}s, %{public}s`, err);
});
})
Text($r('app.string.Share_Item_hint'))
.width('100%')
.textAlign(TextAlign.Center)
.fontSize(20)
.fontWeight(FontWeight.Regular)
.fontColor($r('app.color.share_item_content_font'))
}
.borderRadius(24)
.backgroundColor(Color.White)
.width('100%')
.padding({ top: 13, left: 12, right: 12,bottom:12})
}
build() {
Column() {
// 页面title区域,含返回功能以及title显示
Row() {
Image($r('app.media.ic_public_back'))
.width(20)
.height(20)
.responseRegion({
width:'100%',
height: '100%'
})
.onClick(() => {
router.back();
})
Text($r('app.string.Share_Item_header'))
.fontColor(Color.Black)
.fontWeight(FontWeight.Regular)
.fontSize(25)
.margin({ left:18, right:18 })
}
.height(30)
.width('100%')
.margin({ top: 20, bottom: 27,left: 24})
this.PreviewArea()
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.grey_light'))
.padding({left:12,right:12})
}
}
```
共享元素转场页面:/entry/src/main/ets/pages/SharePage.ets。
```ts
@Entry
@Component
struct SharePage {
build() {
Column() {
Image($r('app.media.bg_transition'))
.objectFit(ImageFit.Fill)
.width('100%')
.height('100%')
.sharedTransition('shareId', {
duration: 600,
curve: Curve.Smooth,
delay: 100
})
}
}
}
```
## 参考
- [图形变换](../application-dev/reference/arkui-ts/ts-universal-attributes-transformation.md)
- [页面间转场](../application-dev/reference/arkui-ts/ts-page-transition-animation.md)
- [组件内转场](../application-dev/ui/arkts-shared-element-transition.md)
- [共享元素转场](../application-dev/reference/arkui-ts/ts-transition-animation-shared-elements.md)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册