diff --git a/en/application-dev/file-management/app-file-backup-extension.md b/en/application-dev/file-management/app-file-backup-extension.md index 3ba491045e1dc665bbc13d9edb9431e79e7809a6..724f51db698895e006d83b6737889fa6956d7076 100644 --- a/en/application-dev/file-management/app-file-backup-extension.md +++ b/en/application-dev/file-management/app-file-backup-extension.md @@ -73,8 +73,8 @@ BackupExtensionAbility is a class derived from the [ExtensionAbility](../applica "data/storage/el2/base/files/", "data/storage/el2/base/preferences/", "data/storage/el2/base/haps/*/database/", - "data/storage/el2/base/haps/*/base/files/", - "data/storage/el2/base/haps/*/base/preferences/", + "data/storage/el2/base/haps/*/files/", + "data/storage/el2/base/haps/*/preferences/", ] } ``` diff --git a/en/application-dev/file-management/photoAccessHelper-resource-guidelines.md b/en/application-dev/file-management/photoAccessHelper-resource-guidelines.md index d145589c1ad96aa8c9e4cc11d3112e40f4772678..4934fca1c911c104c04f47f16505f989b5d1ba3a 100644 --- a/en/application-dev/file-management/photoAccessHelper-resource-guidelines.md +++ b/en/application-dev/file-management/photoAccessHelper-resource-guidelines.md @@ -42,7 +42,7 @@ let fetchOptions = { }; ``` -Call **PhotoAccessHelper.getAssets** to obtain the image asset. +Call **PhotoAccessHelper.getAssets** to obtain image assets. ```ts 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**. @@ -70,7 +70,7 @@ let fetchOptions = { }; ``` -Call **PhotoAccessHelper.getAssets** to obtain the image asset. +Call **PhotoAccessHelper.getAssets** to obtain image assets. ```ts try { @@ -103,7 +103,7 @@ let fetchOptions = { }; ``` -Call **PhotoAccessHelper.getAssets** to obtain the image assets. +Call **PhotoAccessHelper.getAssets** to obtain image assets. ```ts try { @@ -250,7 +250,7 @@ The files moved to the trash will be retained for 30 days, and deleted permanent **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. Example: Move the first file in the result set to the trash. diff --git a/en/application-dev/file-management/photoAccessHelper-systemAlbum-guidelines.md b/en/application-dev/file-management/photoAccessHelper-systemAlbum-guidelines.md index 7c98b2f674aba77a5359179e2a56b56819784eb1..c88fc6536d5119a1bb6e994c4abd41270bc2d78a 100644 --- a/en/application-dev/file-management/photoAccessHelper-systemAlbum-guidelines.md +++ b/en/application-dev/file-management/photoAccessHelper-systemAlbum-guidelines.md @@ -5,7 +5,7 @@ The **photoAccessHelper** module provides APIs for managing system albums, inclu > **NOTE** > > 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). 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. **How to Develop** 1. [Obtain the image and videos in **Favorites**](#obtaining-images-and-videos-in-favorites). -2. Set **isFavorite** to **false**. -3. Use **FileAsset.favorite** to remove the image from **Favorites**. +2. Set **favoriteState** to **false**. +3. Use **FileAsset.setFavorite** to remove the image from **Favorites**. ```ts diff --git a/en/application-dev/file-management/save-user-file.md b/en/application-dev/file-management/save-user-file.md index d47592c74dff6211a7301516c8a76f07f648812e..f0fadf5b62dd836c7d2c2f1508c8f0828ced86e9 100644 --- a/en/application-dev/file-management/save-user-file.md +++ b/en/application-dev/file-management/save-user-file.md @@ -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. -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 -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 import picker from '@ohos.file.picker'; 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 - const photoSaveOptions = new picker.PhotoSaveOptions(); // Create a photoSaveOptions instance. - photoSaveOptions.newFileNames = ["PhotoViewPicker01.jpg"]; // (Optional) Set the names of the files to save. + const context = getContext(this); + 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. - - ```ts - let uri = null; - const photoViewPicker = new picker.PhotoViewPicker(); - photoViewPicker.save(photoSaveOptions).then((photoSaveResult) => { - uri = photoSaveResult[0]; - console.info('photoViewPicker.save to file succeed and uri is:' + uri); - }).catch((err) => { - console.error(`Invoke photoViewPicker.save failed, code is ${err.code}, message is ${err.message}`); - }) + 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 + let uri:string; + async photoViewPickerSave() { + try { + const photoSaveOptions = new picker.PhotoSaveOptions(); // Create a photoSaveOptions instance. + 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. + + 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**. - ```ts - 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. + 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. ```ts - let writeLen = fs.writeSync(file.fd, 'hello, world'); - console.info('write data to file succeed and size is:' + writeLen); - fs.closeSync(file); + async writeOnly(uri) { + try { + 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 diff --git a/en/application-dev/reference/apis/js-apis-file-backup.md b/en/application-dev/reference/apis/js-apis-file-backup.md index 2c2586c9530b639abdd8060285ee0db7210fb04f..1a2e47e86411b900fb32cf02193290bfcf84fe24 100644 --- a/en/application-dev/reference/apis/js-apis-file-backup.md +++ b/en/application-dev/reference/apis/js-apis-file-backup.md @@ -353,7 +353,7 @@ A constructor used to create a **SessionBackup** instance. ```js import fs from '@ohos.file.fs'; - let generalCallbacks = backup.GeneralCallbacks({ + let generalCallbacks = ({ onFileReady: (err, file) => { if (err) { console.error('onFileReady failed with err: ' + err); @@ -568,7 +568,7 @@ A constructor used to create a **SessionRestore** instance. ```js import fs from '@ohos.file.fs'; - let generalCallbacks = backup.GeneralCallbacks({ + let generalCallbacks = ({ onFileReady: (err, file) => { if (err) { console.error('onFileReady failed with err: ' + err); diff --git a/en/application-dev/reference/apis/js-apis-file-picker.md b/en/application-dev/reference/apis/js-apis-file-picker.md index f08294549c59a444bd8b7f3d8d72e34533c9d59b..b8572f3bf4df0d6a60b5f7835ac1bf9346d19b1f 100644 --- a/en/application-dev/reference/apis/js-apis-file-picker.md +++ b/en/application-dev/reference/apis/js-apis-file-picker.md @@ -1,11 +1,11 @@ # @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** > > 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 ```js @@ -138,7 +138,7 @@ async function example() { save(option?: PhotoSaveOptions) : Promise<Array<string>> -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 @@ -177,7 +177,7 @@ async function example() { save(option: PhotoSaveOptions, callback: AsyncCallback<Array<string>>) : 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 @@ -213,7 +213,7 @@ async function example() { save(callback: AsyncCallback<Array<string>>) : 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 @@ -727,7 +727,7 @@ Defines information about the images or videos selected. | Name | Type | Readable| Writable| Description | | ----------------------- | ------------------- | ---- | ---- | ------------------------------ | | photoUris | Array<string> | 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 diff --git a/en/application-dev/reference/apis/js-apis-photoAccessHelper.md b/en/application-dev/reference/apis/js-apis-photoAccessHelper.md index 288dd14f4a990fc64567a7293b8acfa917cb7ba4..808334727bbbf917dad8a7f801bcc7896ad12ee3 100644 --- a/en/application-dev/reference/apis/js-apis-photoAccessHelper.md +++ b/en/application-dev/reference/apis/js-apis-photoAccessHelper.md @@ -4,7 +4,7 @@ The **photoAccessHelper** module provides APIs for album management, including c > **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 @@ -341,7 +341,7 @@ For details about the error codes, see [File Management Error Codes](../errorcod | ID| Error Message| | -------- | ---------------------------------------- | -| 202 | Called by non-system application. | +| 202 | Called by non-system application. | | 401 | if type displayName is not string. | | 14000001 | if type of displayName is invalid. | @@ -401,9 +401,9 @@ async function example() { let options = { title: 'testPhoto' } - phAccessHelper.createAsset(photoType, extension, options, (err, photoAsset) => { - if (photoAsset != undefined) { - console.info('createAsset file displayName' + photoAsset.displayName); + phAccessHelper.createAsset(photoType, extension, options, (err, uri) => { + if (uri != undefined) { + console.info('createAsset uri' + uri); console.info('createAsset successfully'); } else { console.error('createAsset failed, message = ', err); @@ -445,9 +445,9 @@ async function example() { console.info('createAssetDemo'); let photoType = photoAccessHelper.PhotoType.IMAGE; let extension = 'jpg'; - phAccessHelper.createAsset(photoType, extension, (err, photoAsset) => { - if (photoAsset != undefined) { - console.info('createAsset file displayName' + photoAsset.displayName); + phAccessHelper.createAsset(photoType, extension, (err, uri) => { + if (uri != undefined) { + console.info('createAsset uri' + uri); console.info('createAsset successfully'); } else { console.error('createAsset failed, message = ', err); @@ -499,8 +499,8 @@ async function example() { let options = { title: 'testPhoto' } - let photoAsset = await phAccessHelper.createAsset(photoType,extension, options); - console.info('createAsset file displayName' + photoAsset.displayName); + let uri = await phAccessHelper.createAsset(photoType, extension, options); + console.info('createAsset uri' + uri); console.info('createAsset successfully'); } catch (err) { console.error('createAsset failed, message = ', err); @@ -1077,15 +1077,15 @@ async function example() { //file had changed, do something } // Register onCallback1. - phAccessHelper.registerChange(photoAsset.uri, false, onCallback1); + phAccessHelper.registerChange(photoAsset.uri, false, onCallback1); // Register onCallback2. phAccessHelper.registerChange(photoAsset.uri, false, onCallback2); - photoAsset.favorite(true, (err) => { + photoAsset.setFavorite(true, (err) => { if (err == undefined) { - console.info('favorite successfully'); + console.info('setFavorite successfully'); } else { - console.error('favorite failed with error:' + err); + console.error('setFavorite failed with error:' + err); } }); } @@ -1145,11 +1145,11 @@ async function example() { phAccessHelper.registerChange(photoAsset.uri, false, onCallback2); // Unregister the listening of onCallback1. phAccessHelper.unRegisterChange(photoAsset.uri, onCallback1); - photoAsset.favorite(true, (err) => { + photoAsset.setFavorite(true, (err) => { if (err == undefined) { - console.info('favorite successfully'); + console.info('setFavorite successfully'); } 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 | -------- | ---------------------------------------- | | 401 | if values to commit is invalid. | -**Example** +**Example** ```ts import dataSharePredicates from '@ohos.data.dataSharePredicates'; @@ -2839,7 +2839,7 @@ Obtains image and video assets. This API uses an asynchronous callback to return | 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<[FetchResult](#fetchresult)<[PhotoAsset](#photoasset)>> | Yes | Callback invoked to return the image and video assets obtained.| **Error codes** @@ -2856,17 +2856,17 @@ For details about the error codes, see [Universal Error Codes](../errorcodes/err import dataSharePredicates from '@ohos.data.dataSharePredicates'; async function example() { - console.info('albumGetPhotoAssetsDemoCallback'); - + console.info('albumGetAssetsDemoCallback'); let predicates = new dataSharePredicates.DataSharePredicates(); let albumFetchOptions = { + fetchColumns: [], predicates: predicates }; let fetchOption = { fetchColumns: [], 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(); album.getAssets(fetchOption, (err, albumFetchResult) => { if (albumFetchResult != undefined) { @@ -2914,17 +2914,18 @@ For details about the error codes, see [Universal Error Codes](../errorcodes/err import dataSharePredicates from '@ohos.data.dataSharePredicates'; async function example() { - console.info('albumGetPhotoAssetsDemoPromise'); + console.info('albumGetAssetsDemoPromise'); let predicates = new dataSharePredicates.DataSharePredicates(); let albumFetchOptions = { + fetchColumns: [], predicates: predicates }; let fetchOption = { fetchColumns: [], 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(); album.getAssets(fetchOption).then((albumFetchResult) => { console.info('album getPhotoAssets successfully, getCount: ' + albumFetchResult.getCount()); @@ -2967,9 +2968,10 @@ async function example() { console.info('albumCommitModifyDemo'); let predicates = new dataSharePredicates.DataSharePredicates(); let albumFetchOptions = { + fetchColumns: [], 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(); album.albumName = 'hello'; album.commitModify((err) => { @@ -3015,9 +3017,10 @@ async function example() { console.info('albumCommitModifyDemo'); let predicates = new dataSharePredicates.DataSharePredicates(); let albumFetchOptions = { + fetchColumns: [], 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(); album.albumName = 'hello'; album.commitModify().then(() => { @@ -3496,6 +3499,131 @@ async function example() { } ``` +### setCoverUri + +setCoverUri(uri: string, callback: AsyncCallback<void>): void; + +Sets the album cover. This API uses an asynchronous callback to return the result. + +**NOTE**
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<void> | 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<void>; + +Sets the album cover. This API uses a promise to return the result. + +**NOTE**
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<void> | 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 Enumerates the member types. @@ -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. | | 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. | +| 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.)
**System API**: This is a system API. | ## AlbumKeys @@ -3618,6 +3747,7 @@ Defines the options for creating an image or video asset. | Name | Type | Mandatory| Description | | ---------------------- | ------------------- | ---- | ------------------------------------------------ | | 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.)
**System API**: This is a system API. | ## CreateOptions diff --git a/en/application-dev/reference/apis/js-apis-uripermissionmanager.md b/en/application-dev/reference/apis/js-apis-uripermissionmanager.md index 104ab731f95b6989c8483755cd692cc6625f5b33..abb2be686b6dc20f624f316c2173c54f75fb89b7 100644 --- a/en/application-dev/reference/apis/js-apis-uripermissionmanager.md +++ b/en/application-dev/reference/apis/js-apis-uripermissionmanager.md @@ -53,12 +53,12 @@ For details about the error codes, see [Ability Error Codes](../errorcodes/error ```js import uriPermissionManager from '@ohos.application.uriPermissionManager'; import WantConstant from '@ohos.ability.wantConstant'; - import fileio from '@ohos.fileio'; + import fs from '@ohos.file.fs'; import fileUri from '@ohos.file.fileuri'; let targetBundleName = 'com.example.test_case1' 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) { console.log("mkdir error"+err.message) } else { @@ -115,13 +115,13 @@ By default, an application can authorize its own URIs to another application. If ```js import uriPermissionManager from '@ohos.application.uriPermissionManager'; import WantConstant from '@ohos.ability.wantConstant'; - import fileio from '@ohos.fileio'; + import fs from '@ohos.file.fs'; import fileUri from '@ohos.file.fileuri'; let targetBundleName = 'com.example.test_case1' 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) { console.log("mkdir error"+err.message) } else { diff --git a/en/application-dev/reference/apis/js-apis-userFileManager.md b/en/application-dev/reference/apis/js-apis-userFileManager.md index ea449c88207f5f6bfd5a8bc4573dc4c7b775f357..d3732ddaf19e0014dc9f77681241253b37aa91eb 100644 --- a/en/application-dev/reference/apis/js-apis-userFileManager.md +++ b/en/application-dev/reference/apis/js-apis-userFileManager.md @@ -481,113 +481,6 @@ async function example() { } ``` -### getPhotoAlbums - -getPhotoAlbums(options: AlbumFetchOptions, callback: AsyncCallback<FetchResult<Album>>): void; - - -Obtains image and video albums. This API uses an asynchronous callback to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | ------------------------ | ---- | ------------------------- | -| options | [AlbumFetchOptions](#albumfetchoptions) | Yes | Options for fetching the albums. | -| callback | AsyncCallback<[FetchResult](#fetchresult)<[Album](#album)>> | Yes | Callback invoked to return the 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<FetchResult<Album>>; - -Obtains image and video albums. This API uses a promise to return the result. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Required permissions**: ohos.permission.READ_IMAGEVIDEO - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | ------------------------ | ---- | ------------------------- | -| options | [AlbumFetchOptions](#albumfetchoptions) | Yes | Options for fetching the albums. | - -**Return value** - -| Type | Description | -| --------------------------- | -------------- | -| Promise<[FetchResult](#fetchresult)<[Album](#album)>> | Promise used to return the 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); - } -} -``` - ### createAlbum10+ createAlbum(name: string, callback: AsyncCallback<Album>): void; @@ -935,12 +828,124 @@ async function example() { } ``` +### getPhotoAlbums + +getPhotoAlbums(options: AlbumFetchOptions, callback: AsyncCallback<FetchResult<Album>>): void; + +Obtains image and video albums. This API uses an asynchronous callback to return the result. + +This API will be deprecated. Use [getAlbums10+](#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<[FetchResult](#fetchresult)<[Album](#album)>> | 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<FetchResult<Album>>; + +Obtains image and video albums. This API uses a promise to return the result. + +This API will be deprecated. Use [getAlbums10+](#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<[FetchResult](#fetchresult)<[Album](#album)>> | 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(type: PrivateAlbumType, callback: AsyncCallback<FetchResult<PrivateAlbum>>): void; Obtains the system album. This API uses an asynchronous callback to return the result. +This API will be deprecated. Use [getAlbums10+](#getalbums10) instead. + **System capability**: SystemCapability.FileManagement.UserFileManager.Core **Required permissions**: ohos.permission.READ_IMAGEVIDEO @@ -982,6 +987,8 @@ getPrivateAlbum(type: PrivateAlbumType): Promise<FetchResult<PrivateAlbum& Obtains the system album. This API uses a promise to return the result. +This API will be deprecated. Use [getAlbums10+](#getalbums10) instead. + **System capability**: SystemCapability.FileManagement.UserFileManager.Core **Required permissions**: ohos.permission.READ_IMAGEVIDEO @@ -1252,102 +1259,6 @@ async function example() { } ``` -### on - -on(type: ChangeEvent, callback: Callback<void>): void - -Subscribes to changes of the file management library. This API uses a callback to return the result. - -This API will be deprecated. Use [on10+](#on10) instead. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | -------------------- | ---- | ------------------------------------------------------------ | -| type | [ChangeEvent](#changeevent) | Yes | Type of event to subscribe to.
**deviceChange** indicates the device change.
**albumChange** indicates the album change.
**imageChange** indicates the image change.
**audioChange** indicates the audio file change.
**videoChange** indicates the video file change.
**remoteFileChange** indicates the file change on the registered device.| -| callback | Callback<void> | Yes | Callback that returns no value. | - -**Example** - -```ts -async function example() { - console.info('onDemo'); - let count = 0; - mgr.on('imageChange', () => { - count++; - // Image file changed. Do something. - }); - try { - let testFileName = 'testFile' + Date.now() + '.jpg'; - let fileAsset = await mgr.createPhotoAsset(testFileName); - console.info('createPhotoAsset file displayName' + fileAsset.displayName); - console.info('createPhotoAsset successfully'); - } catch (err) { - console.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<void>): void - -Unsubscribes from changes of the file management library. This API uses a callback to return the result. - -This API will be deprecated. Use [off10+](#off10) instead. - -**System capability**: SystemCapability.FileManagement.UserFileManager.Core - -**Parameters** - -| Name | Type | Mandatory| Description | -| -------- | -------------------- | ---- | ------------------------------------------------------------ | -| type | [ChangeEvent](#changeevent) | Yes | Type of event to subscribe to.
**deviceChange** indicates the device change.
**albumChange** indicates the album change.
**imageChange** indicates the image change.
**audioChange** indicates the audio file change.
**videoChange** indicates the video file change.
**remoteFileChange** indicates the change of the file on a registered device.| -| callback | Callback<void> | No | Callback that returns no value. | - -**Example** - -```ts -async function example() { - console.info('offDemo'); - let count = 0; - mgr.on('imageChange', () => { - count++; - // Image file changed. Do something. - }); - - mgr.off('imageChange', () => { - // Unsubscription succeeds. - }); - - try { - let testFileName = 'testFile' + Date.now() + '.jpg'; - let fileAsset = await mgr.createPhotoAsset(testFileName); - console.info('createPhotoAsset file displayName' + fileAsset.displayName); - console.info('createPhotoAsset successfully'); - } catch (err) { - console.error('createPhotoAsset failed, message = ' + err); - } - // Sleep 1s. - if (count == 0) { - console.info('offDemo success'); - } else { - console.error('offDemo fail'); - } -} -``` - ### getActivePeers getActivePeers(callback: AsyncCallback<Array<PeerInfo>>): void; @@ -1427,7 +1338,7 @@ Obtains information about all peer devices. This API uses an asynchronous callba | Name | Type | Mandatory| Description | | -------- | --------------------------------- | ---- | ------------ | -| callback | AsyncCallback<Array<[PeerInfo](#peerinfo)>> | Yes | Callback invoked to return the information obtained.| +| callback | AsyncCallback<Array<[PeerInfo](#peerinfo)>> | Yes | Callback invoked to return the peer device information obtained.| **Example** @@ -1545,7 +1456,7 @@ async function example() { on(uri: string, forSubUri: boolean, callback: Callback<ChangeData>) : 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 @@ -1591,7 +1502,7 @@ async function example() { // File changed. Do something. } // Register onCallback1. - mgr.on(fileAsset.uri, false, onCallback1); + mgr.on(fileAsset.uri, false, onCallback1); // Register onCallback2. mgr.on(fileAsset.uri, false, onCallback2); @@ -1609,7 +1520,7 @@ async function example() { off(uri: string, callback?: Callback<ChangeData>): 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 @@ -1618,7 +1529,7 @@ Disables listening for the specified URI. Multiple callbacks can be registered f | Name | Type | Mandatory| Description | | -------- | ------------------------------------------- | ---- | ------------------------------------------------------------ | | uri | string | Yes | URI of the file asset or album, or [DefaultChangeUri](#defaultchangeuri10).| -| callback | Callback<[ChangeData](#changedata10)> | No | Callback registered by [on10+](#on10). If this parameter is not specified, all callbacks registered for the URI will be unregistered.
**NOTE**: The specified callback will not be invoked.| +| callback | Callback<[ChangeData](#changedata10)> | No | Callback registered by [on10+](#on10). If this parameter is not specified, all listener callbacks registered for the URI will be unregistered.
**NOTE**: The specified callback will not be invoked.| **Error codes** @@ -1667,6 +1578,102 @@ async function example() { } ``` +### on + +on(type: ChangeEvent, callback: Callback<void>): void + +Subscribes to changes of the file management library. This API uses a callback to return the result. + +This API will be deprecated. Use [on10+](#on10) instead. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | -------------------- | ---- | ------------------------------------------------------------ | +| type | [ChangeEvent](#changeevent) | Yes | Type of event to subscribe to.
**deviceChange** indicates the device change.
**albumChange** indicates the album change.
**imageChange** indicates the image change.
**audioChange** indicates the audio file change.
**videoChange** indicates the video file change.
**remoteFileChange** indicates the file change on the registered device.| +| callback | Callback<void> | Yes | Callback that returns no value. | + +**Example** + +```ts +async function example() { + console.info('onDemo'); + let count = 0; + mgr.on('imageChange', () => { + count++; + // Image file changed. Do something. + }); + try { + let testFileName = 'testFile' + Date.now() + '.jpg'; + let fileAsset = await mgr.createPhotoAsset(testFileName); + console.info('createPhotoAsset file displayName' + fileAsset.displayName); + console.info('createPhotoAsset successfully'); + } catch (err) { + console.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<void>): void + +Unsubscribes from changes of the file management library. This API uses a callback to return the result. + +This API will be deprecated. Use [off10+](#off10) instead. + +**System capability**: SystemCapability.FileManagement.UserFileManager.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | -------------------- | ---- | ------------------------------------------------------------ | +| type | [ChangeEvent](#changeevent) | Yes | Type of event to subscribe to.
**deviceChange** indicates the device change.
**albumChange** indicates the album change.
**imageChange** indicates the image change.
**audioChange** indicates the audio file change.
**videoChange** indicates the video file change.
**remoteFileChange** indicates the change of the file on a registered device.| +| callback | Callback<void> | No | Callback that returns no value. | + +**Example** + +```ts +async function example() { + console.info('offDemo'); + let count = 0; + mgr.on('imageChange', () => { + count++; + // Image file changed. Do something. + }); + + mgr.off('imageChange', () => { + // Unsubscription succeeds. + }); + + try { + let testFileName = 'testFile' + Date.now() + '.jpg'; + let fileAsset = await mgr.createPhotoAsset(testFileName); + console.info('createPhotoAsset file displayName' + fileAsset.displayName); + console.info('createPhotoAsset successfully'); + } catch (err) { + console.error('createPhotoAsset failed, message = ' + err); + } + // Sleep 1s. + if (count == 0) { + console.info('offDemo success'); + } else { + console.error('offDemo fail'); + } +} +``` + ## FileAsset 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 | ------------------- | ---------- | | Promise<void> | Promise that returns no value.| -**Example** +**Example** ```ts import dataSharePredicates from '@ohos.data.dataSharePredicates'; @@ -3488,6 +3495,8 @@ async function example() { Provides APIs for managing the system albums. +This API will be discarded. Use [Album](#album) instead. + ### Attributes **System capability**: SystemCapability.FileManagement.UserFileManager.Core @@ -3506,6 +3515,8 @@ getPhotoAssets(options: FetchOptions, callback: AsyncCallback<FetchResult< 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 **System capability**: SystemCapability.FileManagement.UserFileManager.Core @@ -3557,6 +3568,8 @@ getPhotoAssets(options: FetchOptions): Promise<FetchResult<FileAsset>&g 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 **System capability**: SystemCapability.FileManagement.UserFileManager.Core @@ -3607,6 +3620,8 @@ delete(uri: string, callback: AsyncCallback<void>): void; 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 **System capability**: SystemCapability.FileManagement.UserFileManager.Core @@ -3651,6 +3666,8 @@ delete(uri: string): Promise<void>; 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 **System capability**: SystemCapability.FileManagement.UserFileManager.Core @@ -3689,7 +3706,7 @@ async function example() { }).catch((err) => { console.error('trashAlbum.delete failed, message = ', err); }); -} +} ``` ### recover @@ -3698,6 +3715,8 @@ recover(uri: string, callback: AsyncCallback<void>): void; 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 **System capability**: SystemCapability.FileManagement.UserFileManager.Core @@ -3742,6 +3761,8 @@ recover(uri: string): Promise<void>; 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 **System capability**: SystemCapability.FileManagement.UserFileManager.Core @@ -3890,6 +3911,8 @@ Enumerate the album subtypes. Enumerates the system album types. +This API will be deprecated. Use [AlbumType](#albumtype10) and [AlbumSubType](#albumsubtype10) instead. + **System capability**: SystemCapability.FileManagement.UserFileManager.Core | Name | Value| Description | @@ -3938,6 +3961,7 @@ Defines the key information about an image or video file. | POSITION10+ | position | File location type. | | DATE_TRASHED10+ | 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. | | HIDDEN10+ | hidden | Whether the file is hidden. | +| CAMERA_SHOT_KEY10+ | 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 @@ -3962,6 +3986,7 @@ Options for creating an image or video asset. | Name | Type | Mandatory| Description | | ---------------------- | ------------------- | ---- | ------------------------------------------------ | | 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 diff --git a/en/application-dev/security/permission-list.md b/en/application-dev/security/permission-list.md index 302d4cd84cc962f429ddd0a1b198abda92db21a1..138f98bd08423c303fe73489104251f7638f0102 100644 --- a/en/application-dev/security/permission-list.md +++ b/en/application-dev/security/permission-list.md @@ -100,6 +100,18 @@ Allows an application to read telephony information. **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 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 ## 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 @@ -860,7 +872,7 @@ Allows an SA to call the network management, Wi-Fi, network adapter listening, a ## 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 @@ -956,7 +968,7 @@ Allows an application to clear application data. ## 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 @@ -1004,7 +1016,7 @@ Allows a system application to obtain Wi-Fi parameters. ## 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 @@ -1280,7 +1292,7 @@ Allows a device administrator application to set the screen-off time. ## 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 @@ -1656,7 +1668,7 @@ Allows an application to access geographical locations in the user's media file. ## 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 @@ -2683,3 +2695,39 @@ Allows an application to listen for the card running status. **Enable via ACL**: TRUE **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 diff --git a/en/device-dev/kernel/kernel-standard-newip.md b/en/device-dev/kernel/kernel-standard-newip.md index 2e6285aca8f1fb34a07496762ba888eecc0fdece..a9da3f3bc075a889872972f71992e32353743e27 100644 --- a/en/device-dev/kernel/kernel-standard-newip.md +++ b/en/device-dev/kernel/kernel-standard-newip.md @@ -22,8 +22,8 @@ New IP provides at least 1% higher payload transmission efficiency than IPv4 and | Scenario | Header Overhead (Bytes) | Payload Transmission Efficiency
(Wi-Fi MTU = 1500 Bytes, BT MTU = 255 Bytes)| | --------------- | ------------ | ------------------------------------------- | -| 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% | +| 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% | | New IP for Wi-Fi | 30 + 8 + 5 = 43 | (1500 - 43)/1500 = 97.13% | ## Variable-Length Header Format @@ -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 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. -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: @@ -119,8 +119,18 @@ out/kernel/OBJ/linux-5.10/net/newip/tcp_nip_output.o ```c /* 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. */ 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); #endif - if (trace_vendor_ninet_ehashfn_enabled()) { - if (sk->sk_family == AF_NINET) { - u32 ret = 0; + if (sk->sk_family == AF_NINET) { + u32 ret = 0; /* Register the New IP ehash function. */ - trace_vendor_ninet_ehashfn(sk, &ret); - return ret; - } + CALL_HCK_LITE_HOOK(nip_ninet_ehashfn_lhck, sk, &ret); + return ret; } /* IPv4 */ return inet_ehashfn(sock_net(sk), @@ -166,8 +174,8 @@ The user-mode application calls **socket()** to create a New IP socket and uses | API | Input | Output | Return Value | Description | | -------- | ------------------------------------------------------------ | ---------------------------------------------- | ---------------- | ------------------------------------------------------------ | -| socket | int **domain**, int type, int **protocol** | NA | Socket handle **sockfd**.| Creates a New IP socket.
**domain** must be **AF_NINET**, which indicates a New IP socket.
**protocol** can be **IPPROTO_TCP** or **IPPROTO_UDP**.
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.
**myaddr->sin_family** must be **AF_NINET**.| +| socket | int **domain**, int type, int **protocol** | NA | Socket handle **sockfd**.| Creates a New IP socket.
**domain** must be **AF_NINET**, which indicates a New IP socket.
**protocol** can be **IPPROTO_TCP** or **IPPROTO_UDP**.
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.
**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. | | 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. | diff --git a/zh-cn/application-dev/IDL/idl-guidelines.md b/zh-cn/application-dev/IDL/idl-guidelines.md index 8d124c2f0e91c74864a6af12879818269fc59e75..1ca2dd58dc48961748625de2a18bb46e77f9e807 100644 --- a/zh-cn/application-dev/IDL/idl-guidelines.md +++ b/zh-cn/application-dev/IDL/idl-guidelines.md @@ -441,3 +441,9 @@ export default class MySequenceable { 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 diff --git a/zh-cn/application-dev/application-models/accessibilityextensionability.md b/zh-cn/application-dev/application-models/accessibilityextensionability.md index fcc2ecdf420a01ad016a915b9778da619e4e13eb..82183a0d01561ceb6115026a373fca690e4b3ad6 100644 --- a/zh-cn/application-dev/application-models/accessibilityextensionability.md +++ b/zh-cn/application-dev/application-models/accessibilityextensionability.md @@ -138,5 +138,4 @@ onAccessibilityEvent(accessibilityEvent) { 针对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) diff --git a/zh-cn/application-dev/application-models/arkts-ui-widget-update-by-proxy.md b/zh-cn/application-dev/application-models/arkts-ui-widget-update-by-proxy.md index 1630e686e1cddd466e859c66e9f17e720744df8f..35476c1a8c09c8ef90f41c11359de11c25c81f20 100644 --- a/zh-cn/application-dev/application-models/arkts-ui-widget-update-by-proxy.md +++ b/zh-cn/application-dev/application-models/arkts-ui-widget-update-by-proxy.md @@ -219,3 +219,9 @@ ## 数据提供方开发步骤 参考[数据管理](../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 diff --git a/zh-cn/application-dev/application-models/arkts-ui-widget-working-principles.md b/zh-cn/application-dev/application-models/arkts-ui-widget-working-principles.md index 7585bbc02e566a5747acb8ba75acab6f8e224929..f42e1d9333c560dc5a0d0b6b7eedb446e54c0025 100644 --- a/zh-cn/application-dev/application-models/arkts-ui-widget-working-principles.md +++ b/zh-cn/application-dev/application-models/arkts-ui-widget-working-principles.md @@ -60,3 +60,11 @@ ArkTS卡片相较于JS卡片具备了更加丰富的能力,但也增加了使 - 暂不支持Hot Reload热重载。 - 暂不支持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 diff --git a/zh-cn/application-dev/application-models/common-event-static-subscription.md b/zh-cn/application-dev/application-models/common-event-static-subscription.md index 9f903c9ae3f004b0b2f6892254a44fdd0dbba748..8d850a19c6cb868e161a51c0ac99282b8dd5ca7c 100644 --- a/zh-cn/application-dev/application-models/common-event-static-subscription.md +++ b/zh-cn/application-dev/application-models/common-event-static-subscription.md @@ -118,5 +118,5 @@ 针对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) diff --git a/zh-cn/application-dev/application-models/component-startup-rules.md b/zh-cn/application-dev/application-models/component-startup-rules.md index 5637e046e1d8eab8b31b029ddbbe323b53de01cf..3adc5a0429600cb92edd26d95f5244c0785f0250 100644 --- a/zh-cn/application-dev/application-models/component-startup-rules.md +++ b/zh-cn/application-dev/application-models/component-startup-rules.md @@ -26,7 +26,7 @@ - 若目标组件exported字段配置为false,则需校验`ohos.permission.START_INVISIBLE_ABILITY`权限 - [组件exported配置参考](../quick-start/module-configuration-file.md#abilities标签) -- **位于后台的应用,启动组件需校验BACKGROUND权限** +- **位于后台的UIAbility应用,启动组件需校验BACKGROUND权限** - 应用前后台判断标准:若应用进程获焦或所属的UIAbility位于前台则判定为前台应用,否则为后台应用 - 需校验`ohos.permission.START_ABILITIES_FROM_BACKGROUND`权限 @@ -46,7 +46,9 @@ 设备内启动组件,不同场景下的规则不同,可分为如下两种场景: -- 启动或连接组件:UIAbility、ServiceExtensionAbility、DataShareExtensionAbility。 +- 启动UIAbility。 + +- 启动ServiceExtensionAbility、DataShareExtensionAbility。 - 通过startAbilityByCall接口启动UIAbility。 @@ -57,7 +59,9 @@ 跨设备启动组件,不同场景下的规则不同,可分为如下两种场景: -- 启动或连接组件:UIAbility、ServiceExtensionAbility、DataShareExtensionAbility。 +- 启动UIAbility。 + +- 启动ServiceExtensionAbility、DataShareExtensionAbility。 - 通过startAbilityByCall接口启动UIAbility。 diff --git a/zh-cn/application-dev/application-models/enterprise-extensionAbility.md b/zh-cn/application-dev/application-models/enterprise-extensionAbility.md index 2ab9b8335871442890636f86c65b9a2962c06aa6..5398016749d6dac651f6f4af862c119a2f298633 100644 --- a/zh-cn/application-dev/application-models/enterprise-extensionAbility.md +++ b/zh-cn/application-dev/application-models/enterprise-extensionAbility.md @@ -103,11 +103,8 @@ export default class EnterpriseAdminAbility extends EnterpriseAdminExtensionAbil } ``` - - ## 相关实例 针对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) diff --git a/zh-cn/application-dev/application-models/figures/component-startup-inner-stage.png b/zh-cn/application-dev/application-models/figures/component-startup-inner-stage.png index 756f26e8bf8812142c26c593ce46c3ac1bc2235e..0093027d336c0aea5aee54917cb8cffbf985dde1 100644 Binary files a/zh-cn/application-dev/application-models/figures/component-startup-inner-stage.png and b/zh-cn/application-dev/application-models/figures/component-startup-inner-stage.png differ diff --git a/zh-cn/application-dev/application-models/figures/component-startup-inter-stage.png b/zh-cn/application-dev/application-models/figures/component-startup-inter-stage.png index 09693c02ecb985ab7347d2a10d7602acb67738c4..3dc6700b70abf1d5e35e39c41366eb395865b10e 100644 Binary files a/zh-cn/application-dev/application-models/figures/component-startup-inter-stage.png and b/zh-cn/application-dev/application-models/figures/component-startup-inter-stage.png differ diff --git a/zh-cn/application-dev/application-models/js-ui-widget-development.md b/zh-cn/application-dev/application-models/js-ui-widget-development.md index cefb047cf176a22c032b21aec8a6c8b64e94ee6f..91c48a92ab12f1a4bdb3d9a1fe30776b731f9b66 100644 --- a/zh-cn/application-dev/application-models/js-ui-widget-development.md +++ b/zh-cn/application-dev/application-models/js-ui-widget-development.md @@ -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/StepsCardJS) \ No newline at end of file diff --git a/zh-cn/application-dev/application-models/mission-management-overview.md b/zh-cn/application-dev/application-models/mission-management-overview.md index fff740fe26ef54d4bb85ac5bfd759f6519f9a681..f2d3dcc3f5e91fb51f06593b0bc48e306e91db1e 100644 --- a/zh-cn/application-dev/application-models/mission-management-overview.md +++ b/zh-cn/application-dev/application-models/mission-management-overview.md @@ -126,4 +126,8 @@ }) ``` - +## 相关实例 + +针对任务管理开发,有以下相关实例可供参考: + +- [任务管理(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/MissionManager) diff --git a/zh-cn/application-dev/application-models/service-widget-overview.md b/zh-cn/application-dev/application-models/service-widget-overview.md index e7625bfd399b3adb9805cf552ac03f971e920f8c..f6c0368123f7994fe5205e875ddae6bd21da0192 100644 --- a/zh-cn/application-dev/application-models/service-widget-overview.md +++ b/zh-cn/application-dev/application-models/service-widget-overview.md @@ -60,11 +60,12 @@ ArkTS卡片与JS卡片具备不同的实现原理及特征,在场景能力上 针对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) diff --git a/zh-cn/application-dev/application-models/serviceextensionability.md b/zh-cn/application-dev/application-models/serviceextensionability.md index 0455b155238e3f3e194a4f2f54f00c90de0900eb..f08ee4a700dd99a7405f8b11ba53e2bfda7481ae 100644 --- a/zh-cn/application-dev/application-models/serviceextensionability.md +++ b/zh-cn/application-dev/application-models/serviceextensionability.md @@ -453,5 +453,8 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap 针对ServiceExtensionAbility开发,有以下相关实例可供参考: -- [`AbilityConnectServiceExtension`:Ability与ServiceExtensionAbility通信(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/IDL/AbilityConnectServiceExtension) -- [`StageModel`:Stage模型(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/ApplicationModels/StageModel) +- [跨任务链返回(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/TestRely/LauncherTest/CrossChainBack) + +- [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) diff --git a/zh-cn/application-dev/application-models/stage-model-development-overview.md b/zh-cn/application-dev/application-models/stage-model-development-overview.md index 7854471b8c8884033b7905b862fe36861e4fc643..baaf723a4c3e921a0466dc4c66556853f0f33310 100644 --- a/zh-cn/application-dev/application-models/stage-model-development-overview.md +++ b/zh-cn/application-dev/application-models/stage-model-development-overview.md @@ -41,3 +41,9 @@ | 了解线程模型 | 本章节介绍了Stage模型的线程模型以及几种常用的线程间通信方式。 | - [Emitter](itc-with-emitter.md)
- [Worker](itc-with-worker.md) | | 任务管理 | 本章节介绍了Stage模型中任务管理的基本概念和典型场景。 | - [任务管理场景介绍](mission-management-overview.md)
- [任务管理与启动模式](mission-management-launch-type.md)
- [页面栈和任务链](page-mission-stack.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 diff --git a/zh-cn/application-dev/application-models/uiability-launch-type.md b/zh-cn/application-dev/application-models/uiability-launch-type.md index 724e5b5ee637d20b912c7fba6daf9229f01c1440..47786105543886bc88feff018078433dcb4e573c 100644 --- a/zh-cn/application-dev/application-models/uiability-launch-type.md +++ b/zh-cn/application-dev/application-models/uiability-launch-type.md @@ -151,3 +151,9 @@ specified启动模式为指定实例模式,针对一些特殊场景使用( 2. 在最近任务列表中关闭`文件A`的任务进程,此时`UIAbility实例1`被销毁,回到桌面,再次打开`文件A`,此时对应启动一个新的UIAbility实例,例如启动`UIAbility实例2`。 3. 回到桌面,打开`文件B`,此时对应启动一个新的UIAbility实例,例如启动`UIAbility实例3`。 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 diff --git a/zh-cn/application-dev/application-models/want-overview.md b/zh-cn/application-dev/application-models/want-overview.md index aa7fb7e17f6f40ffecfdb93dbc0537abeaa47ba3..ff8b133436e1dae1ac2fafc8ab82aa09a83d1d7d 100644 --- a/zh-cn/application-dev/application-models/want-overview.md +++ b/zh-cn/application-dev/application-models/want-overview.md @@ -48,6 +48,6 @@ > - 匹配到一个满足条件的应用组件:直接启动该应用组件。 > - 匹配到多个满足条件的应用组件(UIAbility):弹出选择框让用户选择。 > - > - 调用方传入的want参数中不带有abilityName和bundleName,则不允许通过隐式Want启动所有应用的ServiceExtensionAbility。 - > - > - 调用方传入的want参数中带有bundleName,则允许使用startServiceExtensionAbility()方法隐式Want启动ServiceExtensionAbility,默认返回优先级最高的ServiceExtensionAbility,如果优先级相同,返回第一个。 + > - 对于启动ServiceExtensionAbility的场景: + > - 调用方传入的want参数中带有abilityName,则不允许通过隐式Want启动ServiceExtensionAbility。 + > - 调用方传入的want参数中带有bundleName,则允许使用startServiceExtensionAbility()方法隐式Want启动ServiceExtensionAbility,默认返回优先级最高的ServiceExtensionAbility,如果优先级相同,返回第一个。 diff --git a/zh-cn/application-dev/application-models/windowextensionability.md b/zh-cn/application-dev/application-models/windowextensionability.md index 66069a2abf512ac0eb713aaf2e6d28f686f5a760..b23f9e915aac3974728267137785c1887873039c 100644 --- a/zh-cn/application-dev/application-models/windowextensionability.md +++ b/zh-cn/application-dev/application-models/windowextensionability.md @@ -116,4 +116,4 @@ struct Index { 针对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) diff --git a/zh-cn/application-dev/arkts-utils/arkts-commonlibrary-overview.md b/zh-cn/application-dev/arkts-utils/arkts-commonlibrary-overview.md index 3e47b6e0408b7c51dcda9614506df1e0fb7f00fe..9f2d9b08834d7713413afe3ee6784faf1fbf1888 100644 --- a/zh-cn/application-dev/arkts-utils/arkts-commonlibrary-overview.md +++ b/zh-cn/application-dev/arkts-utils/arkts-commonlibrary-overview.md @@ -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) diff --git a/zh-cn/application-dev/arkts-utils/multi-thread-concurrency-overview.md b/zh-cn/application-dev/arkts-utils/multi-thread-concurrency-overview.md index d9bbe2dd7c7178f2e27bf1255835eb53d086f04b..dfc06c0b89f9088dde5c4a1db6321c16907d8aad 100644 --- a/zh-cn/application-dev/arkts-utils/multi-thread-concurrency-overview.md +++ b/zh-cn/application-dev/arkts-utils/multi-thread-concurrency-overview.md @@ -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) diff --git a/zh-cn/application-dev/connectivity/http-request.md b/zh-cn/application-dev/connectivity/http-request.md index 59f2fbe9f993aa1d42e1e6948974973831b190bc..525f6f37e8aac9f99b6522399779afed7fa56199 100644 --- a/zh-cn/application-dev/connectivity/http-request.md +++ b/zh-cn/application-dev/connectivity/http-request.md @@ -52,7 +52,8 @@ httpRequest.on('headersReceive', (header) => { console.info('header: ' + JSON.stringify(header)); }); httpRequest.request( - // 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定"EXAMPLE_URL", + // 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定 + "EXAMPLE_URL", { method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET // 开发者根据自身业务需要添加header字段 @@ -81,7 +82,7 @@ httpRequest.request( // 当该请求使用完毕时,调用destroy方法主动销毁 httpRequest.destroy(); } else { - console.info('error:' + JSON.stringify(err)); + console.error('error:' + JSON.stringify(err)); // 取消订阅HTTP响应头事件 httpRequest.off('headersReceive'); // 当该请求使用完毕时,调用destroy方法主动销毁 @@ -146,7 +147,7 @@ httpRequest.requestInStream( readTimeout: 60000, // 可选,默认为60000ms。若传输的数据较大,需要较长的时间,建议增大该参数以保证数据传输正常终止 usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定 }, (err, data) => { - console.info('error:' + JSON.stringify(err)); + console.error('error:' + JSON.stringify(err)); console.info('ResponseCode :' + JSON.stringify(data)); // 取消订阅HTTP响应头事件 httpRequest.off('headersReceive'); @@ -166,5 +167,8 @@ httpRequest.requestInStream( 针对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) \ No newline at end of file diff --git a/zh-cn/application-dev/connectivity/ipc-rpc-development-guideline.md b/zh-cn/application-dev/connectivity/ipc-rpc-development-guideline.md index d82d03c298cae4709b440e7d7a40db53836ee535..5cda83f99b457bde0348c2cf99d9e170e9e2d659 100755 --- a/zh-cn/application-dev/connectivity/ipc-rpc-development-guideline.md +++ b/zh-cn/application-dev/connectivity/ipc-rpc-development-guideline.md @@ -355,3 +355,8 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信, globalThis.context.disconnectServiceExtensionAbility(connectId); ``` +## 相关实例 + +针对IPC与RPC通信开发,有以下相关实例可供参考: + +- [RPC通信(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/RPC) diff --git a/zh-cn/application-dev/connectivity/socket-connection.md b/zh-cn/application-dev/connectivity/socket-connection.md index 12068f2ed0412a6b91f5891f98a832c3ddc51720..e6b3c58b4be7b5216ad5feab7e77518889c89fd9 100644 --- a/zh-cn/application-dev/connectivity/socket-connection.md +++ b/zh-cn/application-dev/connectivity/socket-connection.md @@ -409,4 +409,4 @@ tlsTwoWay.close((err) => { 针对Socket连接开发,有以下相关实例可供参考: -- [`Socket`:Socket 连接(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/Socket) \ No newline at end of file +- [网络管理-Socket连接(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/Socket) \ No newline at end of file diff --git a/zh-cn/application-dev/connectivity/websocket-connection.md b/zh-cn/application-dev/connectivity/websocket-connection.md index f0235e12fe2a050c8b317e47ba3a254e66760e0b..c0ba37b5d53e79cfb2d987ac8ec470acc7ba9bf6 100644 --- a/zh-cn/application-dev/connectivity/websocket-connection.md +++ b/zh-cn/application-dev/connectivity/websocket-connection.md @@ -85,4 +85,4 @@ ws.connect(defaultIpAddress, (err, value) => { 针对WebSocket连接的开发,有以下相关实例可供参考: -- [`WebSocket`:WebSocket(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/WebSocket) \ No newline at end of file +- [WebSocket(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/WebSocket) \ No newline at end of file diff --git a/zh-cn/application-dev/database/data-persistence-by-preferences.md b/zh-cn/application-dev/database/data-persistence-by-preferences.md index 6557cbf7eb54e38604c38d308e4ae373e761b609..8385bd06cfc8326bccb04c79e430018b2ff56730 100644 --- a/zh-cn/application-dev/database/data-persistence-by-preferences.md +++ b/zh-cn/application-dev/database/data-persistence-by-preferences.md @@ -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) diff --git a/zh-cn/application-dev/database/data-sync-of-distributed-data-object.md b/zh-cn/application-dev/database/data-sync-of-distributed-data-object.md index 27484e1f586f5eaeda0896793adeb6ef7a2256ac..4dd9be9bcc82e00fef53b5ad901e2582ccc18af7 100644 --- a/zh-cn/application-dev/database/data-sync-of-distributed-data-object.md +++ b/zh-cn/application-dev/database/data-sync-of-distributed-data-object.md @@ -304,4 +304,12 @@ localObject.setSessionId(() => { 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 diff --git a/zh-cn/application-dev/database/data-sync-of-kv-store.md b/zh-cn/application-dev/database/data-sync-of-kv-store.md index 3dca8f745164ab33075f9d5eae262526a4f18ce5..3d491d4d5c637b85b1dcf484e6b248fbedf2a524 100644 --- a/zh-cn/application-dev/database/data-sync-of-kv-store.md +++ b/zh-cn/application-dev/database/data-sync-of-kv-store.md @@ -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) \ No newline at end of file diff --git a/zh-cn/application-dev/database/data-sync-of-rdb-store.md b/zh-cn/application-dev/database/data-sync-of-rdb-store.md index eaa45ed4dde5c7f216d906ceee334d7f23d57d00..9f8030ff400296a9551cd000f41894c644d89787 100644 --- a/zh-cn/application-dev/database/data-sync-of-rdb-store.md +++ b/zh-cn/application-dev/database/data-sync-of-rdb-store.md @@ -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 diff --git a/zh-cn/application-dev/database/share-data-by-datashareextensionability.md b/zh-cn/application-dev/database/share-data-by-datashareextensionability.md index d5f8a05ff7a7ea72b4be00fff91d6bfc8389cebe..831902663ef160655c5bb85b804fde2b62e0e77e 100644 --- a/zh-cn/application-dev/database/share-data-by-datashareextensionability.md +++ b/zh-cn/application-dev/database/share-data-by-datashareextensionability.md @@ -243,4 +243,4 @@ 针对数据共享开发,有以下相关实例可供参考: -- [`CrossAppDataShare`:系统应用跨应用数据共享(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/DataManagement/CrossAppDataShare) \ No newline at end of file +- [系统应用跨应用数据共享(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/DataManagement/CrossAppDataShare) \ No newline at end of file diff --git a/zh-cn/application-dev/database/sync-app-data-across-devices-overview.md b/zh-cn/application-dev/database/sync-app-data-across-devices-overview.md index bc20513037b2cb0751db143b8192990bff13c355..f8475f43756eaaed02e8ff79b1cf862e892519fb 100644 --- a/zh-cn/application-dev/database/sync-app-data-across-devices-overview.md +++ b/zh-cn/application-dev/database/sync-app-data-across-devices-overview.md @@ -37,3 +37,9 @@ ## 跨设备同步访问控制机制 数据跨设备同步时,数据管理基于设备等级和数据安全标签进行访问控制,具体可见[跨设备同步访问控制机制](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 diff --git a/zh-cn/application-dev/device-usage-statistics/device-usage-statistics-use-guide.md b/zh-cn/application-dev/device-usage-statistics/device-usage-statistics-use-guide.md index 25644938494efeb3524e29381afab75d8ef5cfd4..686cfa481f5b56496d233050009352819c9fbbbd 100644 --- a/zh-cn/application-dev/device-usage-statistics/device-usage-statistics-use-guide.md +++ b/zh-cn/application-dev/device-usage-statistics/device-usage-statistics-use-guide.md @@ -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) + diff --git a/zh-cn/application-dev/device/location-guidelines.md b/zh-cn/application-dev/device/location-guidelines.md index a3fada8824c3aa2ec083443531884ce02cc96e56..06392107148d98c7a6996bd2da8f170f7da17225 100644 --- a/zh-cn/application-dev/device/location-guidelines.md +++ b/zh-cn/application-dev/device/location-guidelines.md @@ -406,4 +406,10 @@ }); ``` -5. 当设备进入或者退出该围栏时,系统会自动触发WantAgent的动作。 \ No newline at end of file +5. 当设备进入或者退出该围栏时,系统会自动触发WantAgent的动作。 + +## 相关实例 + +针对位置开发,有以下相关实例可供参考: + +- [位置服务(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Location) \ No newline at end of file diff --git a/zh-cn/application-dev/device/vibrator-guidelines.md b/zh-cn/application-dev/device/vibrator-guidelines.md index 0e523ec504de6808314611e054093c611947c6de..d04b5036ddaf67718f87098661c0d6ce4e4af524 100644 --- a/zh-cn/application-dev/device/vibrator-guidelines.md +++ b/zh-cn/application-dev/device/vibrator-guidelines.md @@ -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) -- [`CustomHaptic`:自定义振动(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/CustomHaptic) +- [振动(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/BasicVibration) + +- [自定义振动(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/CustomHaptic) diff --git a/zh-cn/application-dev/dfx/appfreeze-guidelines.md b/zh-cn/application-dev/dfx/appfreeze-guidelines.md index a8228da78376037e37ced78bee0558b510f11e03..a4fcdc4bc9dd441187d0c67031bc2c17efd84563 100644 --- a/zh-cn/application-dev/dfx/appfreeze-guidelines.md +++ b/zh-cn/application-dev/dfx/appfreeze-guidelines.md @@ -193,3 +193,9 @@ APP_LIFECYCLE_TIMEOUT: ![appfreeze_20230310105874](figures/appfreeze_20230310105874.png) 其他的日志信息可以参考[通用日志信息](#日志主干通用信息)进行分析。需要特别说明的是,一般情况下生命周期切换大概率主线程也会卡死。可以结合两个日志的三个堆栈、两个BinderCatcher信息,进行对比查看。 + +## 相关实例 + +针对故障日志获取,有以下相关实力可供参考: + +- [故障日志获取(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DFX/FaultLogger) \ No newline at end of file diff --git a/zh-cn/application-dev/dfx/cppcrash-guidelines.md b/zh-cn/application-dev/dfx/cppcrash-guidelines.md index e4a18bdd91431ded5f42e4ca753e64ba1556b8ee..e8febc7957861d93e7d3384d23e80b78d3cdfe49 100644 --- a/zh-cn/application-dev/dfx/cppcrash-guidelines.md +++ b/zh-cn/application-dev/dfx/cppcrash-guidelines.md @@ -105,3 +105,9 @@ Thread name:crasher <- 异常线程名 范例中的崩溃故障是由赋值给一块不可写的区域导致的,代码行为dfx_crasher.c文件的57行,修改后可以避免发生此崩溃。\ 另外,使用addr2line后,如果得出的行号看起来不是很正确,可以考虑对地址进行微调(如减1),或者考虑关闭一些编译优化,已知使用LTO的二进制可能无法正确获得行号。 + +## 相关实例 + +针对故障日志获取,有以下相关实力可供参考: + +- [故障日志获取(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DFX/FaultLogger) \ No newline at end of file diff --git a/zh-cn/application-dev/dfx/hiappevent-guidelines.md b/zh-cn/application-dev/dfx/hiappevent-guidelines.md index bcb7ad3d6bbe8355cc7d2b65f1e5b542db6bb533..865455e43d7dc69b8a1a19a4f73f826246cfd00f 100644 --- a/zh-cn/application-dev/dfx/hiappevent-guidelines.md +++ b/zh-cn/application-dev/dfx/hiappevent-guidelines.md @@ -151,4 +151,6 @@ HiAppEvent是在系统层面为应用开发者提供的一种事件打点机制 针对应用事件开发,有以下相关实例可供参考: -- [`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/DotTest) + +- [日志打印(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DFX/Logger) \ No newline at end of file diff --git a/zh-cn/application-dev/faqs/faqs-graphics.md b/zh-cn/application-dev/faqs/faqs-graphics.md index 426529f1568fba9f53c85da3d9c70a0a8aa0f01a..d7ab452619cca0361f39752b849fcaa2fa1e0419 100644 --- a/zh-cn/application-dev/faqs/faqs-graphics.md +++ b/zh-cn/application-dev/faqs/faqs-graphics.md @@ -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模型 diff --git a/zh-cn/application-dev/file-management/app-file-backup-extension.md b/zh-cn/application-dev/file-management/app-file-backup-extension.md index db27d229aeac026169913492460e86638b415be7..985fe3e3f0110552c32e1dfbeb6912e71b77e1d4 100644 --- a/zh-cn/application-dev/file-management/app-file-backup-extension.md +++ b/zh-cn/application-dev/file-management/app-file-backup-extension.md @@ -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 diff --git a/zh-cn/application-dev/file-management/file-management-overview.md b/zh-cn/application-dev/file-management/file-management-overview.md index 26c1f4c04bd78752520bf6414e3396f1cb11abf1..51b9affad7836d8ce650de6a55b9c977ce8656bb 100644 --- a/zh-cn/application-dev/file-management/file-management-overview.md +++ b/zh-cn/application-dev/file-management/file-management-overview.md @@ -23,3 +23,9 @@ **图1** 文件分类模型示意图 ![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 diff --git a/zh-cn/application-dev/internationalization/i18n-guidelines.md b/zh-cn/application-dev/internationalization/i18n-guidelines.md index 61f40445363d54cd2a86de56e2068f803cd4df33..c4f4b9c1d28ae74b866f19f80d05a3cc4039f120 100644 --- a/zh-cn/application-dev/internationalization/i18n-guidelines.md +++ b/zh-cn/application-dev/internationalization/i18n-guidelines.md @@ -731,4 +731,12 @@ try { ```js 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 diff --git a/zh-cn/application-dev/key-features/multi-device-app-dev/appgallery-home-page.md b/zh-cn/application-dev/key-features/multi-device-app-dev/appgallery-home-page.md index 8eba7442a2e8968184a359c05610f986a9f402af..ef260f22a073be5e0e7db207252357dfdaee4c91 100644 --- a/zh-cn/application-dev/key-features/multi-device-app-dev/appgallery-home-page.md +++ b/zh-cn/application-dev/key-features/multi-device-app-dev/appgallery-home-page.md @@ -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) diff --git a/zh-cn/application-dev/key-features/multi-device-app-dev/music-album-page.md b/zh-cn/application-dev/key-features/multi-device-app-dev/music-album-page.md index 4e400e55d06d31176c87e3801d6c82519ebc9f07..5a0b02bb4bc4ff63889514acd17f45483447050f 100644 --- a/zh-cn/application-dev/key-features/multi-device-app-dev/music-album-page.md +++ b/zh-cn/application-dev/key-features/multi-device-app-dev/music-album-page.md @@ -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) diff --git a/zh-cn/application-dev/key-features/multi-device-app-dev/page-development-intro.md b/zh-cn/application-dev/key-features/multi-device-app-dev/page-development-intro.md index 18dc61660685447bba3e030fd7b1c20b7ba567ac..866e3da6ff2c7a9b677c15b9d2bf9bdd24c58ba5 100644 --- a/zh-cn/application-dev/key-features/multi-device-app-dev/page-development-intro.md +++ b/zh-cn/application-dev/key-features/multi-device-app-dev/page-development-intro.md @@ -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/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/MultiColumns) | 声明式开发范式 | 本示例分别展示了多场景下,一多分栏控件的响应式变化效果。 | | [音乐专辑页](https://gitee.com/openharmony/codelabs/tree/master/ExcellentCase/MultiDeviceMusic) | 声明式开发范式 | 基于自适应和响应式布局,实现一次开发、多端部署音乐专辑页面。 | | [视频应用](https://gitee.com/openharmony/codelabs/tree/master/ExcellentCase/Multi_device_V2) | 声明式开发范式 | 基于自适应布局和响应式布局能力,实现了常见的视频播放应用的主界面。 | diff --git a/zh-cn/application-dev/key-features/multi-device-app-dev/settings-application-page.md b/zh-cn/application-dev/key-features/multi-device-app-dev/settings-application-page.md index 9b837b444cf2b582d6169a6bb003a33c018af8ee..13531ae35efb4610815474c350244d565563766c 100644 --- a/zh-cn/application-dev/key-features/multi-device-app-dev/settings-application-page.md +++ b/zh-cn/application-dev/key-features/multi-device-app-dev/settings-application-page.md @@ -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) diff --git a/zh-cn/application-dev/media/audio-call-development.md b/zh-cn/application-dev/media/audio-call-development.md index 949707dc814c6c53673369bdc57e58460064eb06..b750bd26d8b463646f8701132ba6ea21c684ed09 100644 --- a/zh-cn/application-dev/media/audio-call-development.md +++ b/zh-cn/application-dev/media/audio-call-development.md @@ -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 diff --git a/zh-cn/application-dev/media/av-overview.md b/zh-cn/application-dev/media/av-overview.md index 44612b2b54eaf2c1bbcf67c9a9f9da68113926d0..a1cad2424036d4acc6956c900e9d5516393c60d6 100644 --- a/zh-cn/application-dev/media/av-overview.md +++ b/zh-cn/application-dev/media/av-overview.md @@ -63,3 +63,11 @@ audio模块下的接口支持PCM编码,包括AudioRenderer、AudioCapturer、T 小尾数指的是小端模式,即数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。这种存储模式将地址的高低和数据的位权有效结合起来,高地址部分权值高,低地址部分权值低。 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 diff --git a/zh-cn/application-dev/media/camera-overview.md b/zh-cn/application-dev/media/camera-overview.md index c70c86aa89aa2d4bb5bbaf070da49aeb3dbaa17b..15aafd04d4865fa0086b42544d2ee1c2f2753f13 100644 --- a/zh-cn/application-dev/media/camera-overview.md +++ b/zh-cn/application-dev/media/camera-overview.md @@ -25,3 +25,9 @@ 相机应用通过控制相机,实现图像显示(预览)、照片保存(拍照)、视频录制(录像)等基础操作。在实现基本操作过程中,相机服务会控制相机设备采集和输出数据,采集的图像数据在相机底层的设备硬件接口(HDI,Hardware Device Interfaces),直接通过BufferQueue传递到具体的功能模块进行处理。BufferQueue在应用开发中无需关注,用于将底层处理的数据及时送到上层进行图像显示。 以视频录制为例进行说明,相机应用在录制视频过程中,媒体录制服务先创建一个视频Surface用于传递数据,并提供给相机服务,相机服务可控制相机设备采集视频数据,生成视频流。采集的数据通过底层相机HDI处理后,通过Surface将视频流传递给媒体录制服务,媒体录制服务对视频数据进行处理后,保存为视频文件,完成视频录制。 + +## 相关实例 + +针对相机开发,有以下相关实例可供参考: + +- [相机和媒体库(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Media/Camera) diff --git a/zh-cn/application-dev/media/image-overview.md b/zh-cn/application-dev/media/image-overview.md index 7806a34f384fd8b36077a186aeba2f9888643733..be09df9c3d5bc03958ded97be2bb043ad12d23c3 100644 --- a/zh-cn/application-dev/media/image-overview.md +++ b/zh-cn/application-dev/media/image-overview.md @@ -36,3 +36,13 @@ 5. [图片编码](image-encoding.md):使用图片打包器类ImagePacker,将PixelMap或ImageSource进行压缩编码,生成一张新的图片。 除上述基本图片开发能力外,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 diff --git a/zh-cn/application-dev/media/media-application-overview.md b/zh-cn/application-dev/media/media-application-overview.md index 7793805c68033a643b2deadb821be6cc6f0fa51f..bf65edff7cc878a3b69637b2be864b948958d997 100644 --- a/zh-cn/application-dev/media/media-application-overview.md +++ b/zh-cn/application-dev/media/media-application-overview.md @@ -17,3 +17,13 @@ - 相机(camera):提供精确控制相机镜头,采集视觉信息的接口与服务。 - 图片(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 diff --git a/zh-cn/application-dev/media/using-avsession-controller.md b/zh-cn/application-dev/media/using-avsession-controller.md index 9d9fd7d17c3fdb9487ba1cd4bb21047e919845ed..63e0dac55222f350e0c8a96160e8d0c0e9b94fb9 100644 --- a/zh-cn/application-dev/media/using-avsession-controller.md +++ b/zh-cn/application-dev/media/using-avsession-controller.md @@ -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 diff --git a/zh-cn/application-dev/media/using-avsession-developer.md b/zh-cn/application-dev/media/using-avsession-developer.md index 8d398a9c1043c22f7a1ee21151295566eb57848b..57ecb7be0fc082d319008dfe48db178bd6d8864b 100644 --- a/zh-cn/application-dev/media/using-avsession-developer.md +++ b/zh-cn/application-dev/media/using-avsession-developer.md @@ -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 diff --git a/zh-cn/application-dev/media/video-playback.md b/zh-cn/application-dev/media/video-playback.md index e5b68e731b58cc7f6dde3211fd97623c3bf01d7b..48705406e4875b7e126602188564ef30f59ba02d 100644 --- a/zh-cn/application-dev/media/video-playback.md +++ b/zh-cn/application-dev/media/video-playback.md @@ -264,4 +264,6 @@ export class AVPlayerDemo { 针对视频播放,有以下相关实例可供参考: -- [`VideoPlayer`:视频播放器(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/VideoPlayer) \ No newline at end of file +- [视频播放(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/VideoPlay) + +- [视频播放器(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/VideoPlayer) \ No newline at end of file diff --git a/zh-cn/application-dev/napi/rawfile-guidelines.md b/zh-cn/application-dev/napi/rawfile-guidelines.md index dacfe03d5bff4354aebf6f19617a57fb38d5fba9..1a7cd57da0904ed2dcb638532008fbe2413111ce 100644 --- a/zh-cn/application-dev/napi/rawfile-guidelines.md +++ b/zh-cn/application-dev/napi/rawfile-guidelines.md @@ -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) diff --git a/zh-cn/application-dev/napi/xcomponent-guidelines.md b/zh-cn/application-dev/napi/xcomponent-guidelines.md index 14d176da8269fbaa801ad4f46f7ce301b64cabd6..97c0410ad59511760acba64a1b18fbe5fa7c2c46 100644 --- a/zh-cn/application-dev/napi/xcomponent-guidelines.md +++ b/zh-cn/application-dev/napi/xcomponent-guidelines.md @@ -899,4 +899,4 @@ XComponent({ id: 'xcomponentId1', type: 'surface', libraryname: 'nativerender' } 针对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) diff --git a/zh-cn/application-dev/notification/notification-overview.md b/zh-cn/application-dev/notification/notification-overview.md index 8d94d296892616eae51485476ce4f2aead49df44..1b5378f52df2129fd49a44af3ac4f7415bc2fa9d 100644 --- a/zh-cn/application-dev/notification/notification-overview.md +++ b/zh-cn/application-dev/notification/notification-overview.md @@ -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) \ No newline at end of file +- [公共事件的订阅和发布(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Notification/CustomCommonEvent) + +- [自定义通知推送(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 diff --git a/zh-cn/application-dev/quick-start/arkts-appstorage.md b/zh-cn/application-dev/quick-start/arkts-appstorage.md index 778dba37b9b36aed2d4e7d315e618f0610930336..932186e02b1497af6b3df8212f3d674104d07e4b 100644 --- a/zh-cn/application-dev/quick-start/arkts-appstorage.md +++ b/zh-cn/application-dev/quick-start/arkts-appstorage.md @@ -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 = [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 @@ -293,10 +369,9 @@ export struct TapImage { } ``` -以下示例为消息机制方式订阅事件,会导致回调监听的节点数较多,非常耗时,不推荐以此来实现应用代码。 - +以上通知事件逻辑简单,也可以简化成三元表达式。 -```ts +``` // xxx.ets class ViewData { title: string; @@ -337,22 +412,11 @@ struct Gallery2 { @Component export struct TapImage { - @StorageLink('tapIndex') @Watch('onTapIndexChange') tapIndex: number = -1; + @StorageLink('tapIndex') 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) @@ -360,14 +424,18 @@ export struct TapImage { .onClick(() => { 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)配合使用时,需要注意以下几点: diff --git a/zh-cn/application-dev/quick-start/arkts-create-custom-components.md b/zh-cn/application-dev/quick-start/arkts-create-custom-components.md index 2b8fe92da38cb37568a5e58ff78ff553d445bab9..0a77d97d59264950ceba45d6a2854236baa7bb7b 100644 --- a/zh-cn/application-dev/quick-start/arkts-create-custom-components.md +++ b/zh-cn/application-dev/quick-start/arkts-create-custom-components.md @@ -70,8 +70,6 @@ struct ParentComponent { - [自定义组件通用样式](#自定义组件通用样式) -- [自定义属性方法](#自定义属性方法) - ## 自定义组件的基本结构 @@ -347,68 +345,4 @@ struct MyComponent { > > 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的值。 - diff --git a/zh-cn/application-dev/quick-start/arkts-state-management-overview.md b/zh-cn/application-dev/quick-start/arkts-state-management-overview.md index ed7d43741eae5df53d697e46ec447562c84ed193..76676a1a5d9e88b04fadc779d2c001c5506a5f39 100644 --- a/zh-cn/application-dev/quick-start/arkts-state-management-overview.md +++ b/zh-cn/application-dev/quick-start/arkts-state-management-overview.md @@ -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) \ No newline at end of file diff --git a/zh-cn/application-dev/quick-start/multi-hap-objective.md b/zh-cn/application-dev/quick-start/multi-hap-objective.md index 5597b5ba12ba390f96be7c946990f7d5180d3adc..9bc83c477f126d6f2bf0e923d5351b0217c66013 100644 --- a/zh-cn/application-dev/quick-start/multi-hap-objective.md +++ b/zh-cn/application-dev/quick-start/multi-hap-objective.md @@ -5,4 +5,10 @@ - 方便开发者将多HAP合理地组合并部署到不同的设备上。例如应用程序包含一个Entry包和两个Featrue包(Feature1和Feature2)。其中Entry包可以部署到设备A和设备B,Feature1只能部署到设备A,Feature2包只部署到设备B上,那么开发者就可以方便的组合Entry和Feature1部署到设备A上,组合Entry和Feature2部署到设备B上。 -- 方便开发者按需加载所需模块,减少包大小。开发者可以将一个应用的某些HAP配置成按需加载。应用在启动阶段初始用不到的特性,可以配置暂不加载,当用户用到这些特性的时候,可由应用自动下载这些特性HAP,一定程度上减少应用包的大小。 \ No newline at end of file +- 方便开发者按需加载所需模块,减少包大小。开发者可以将一个应用的某些HAP配置成按需加载。应用在启动阶段初始用不到的特性,可以配置暂不加载,当用户用到这些特性的时候,可由应用自动下载这些特性HAP,一定程度上减少应用包的大小。 + +## 相关实例 + +针对多HAP开发,有以下相关实例可供参考: + +- [多HAP(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Project/ApplicationHap/MultiHap) \ No newline at end of file diff --git a/zh-cn/application-dev/quick-start/resource-categories-and-access.md b/zh-cn/application-dev/quick-start/resource-categories-and-access.md index 6602ec1268bc5dcdc6a7ea2f4c8986f2c5379196..947edd41e9fa3ed8e8c042118b957ee6a1bb18e5 100644 --- a/zh-cn/application-dev/quick-start/resource-categories-and-access.md +++ b/zh-cn/application-dev/quick-start/resource-categories-and-access.md @@ -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) diff --git a/zh-cn/application-dev/reference/apis/Readme-CN.md b/zh-cn/application-dev/reference/apis/Readme-CN.md index 9cac4378d9d74356332fb9e6cd6c13928420e4c0..a83459632b68ab259cc5847789c088a7a87be924 100644 --- a/zh-cn/application-dev/reference/apis/Readme-CN.md +++ b/zh-cn/application-dev/reference/apis/Readme-CN.md @@ -301,6 +301,7 @@ - AI - [@ohos.ai.mindSporeLite (推理能力)](js-apis-mindSporeLite.md) + - [@ohos.ai.intelligentVoice (智能语音)](js-apis-intelligentVoice.md) - 电话服务 - [@ohos.contact (联系人)](js-apis-contact.md) diff --git a/zh-cn/application-dev/reference/apis/js-apis-WallpaperExtensionAbility.md b/zh-cn/application-dev/reference/apis/js-apis-WallpaperExtensionAbility.md index 14d17c83e90e424cd7d05a7df4adc487467094d9..ebcf57d0e24b2c209c8f88fd5d4e530e0226db86 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-WallpaperExtensionAbility.md +++ b/zh-cn/application-dev/reference/apis/js-apis-WallpaperExtensionAbility.md @@ -1,12 +1,12 @@ # @ohos.WallpaperExtensionAbility (WallpaperExtensionAbility) -通过本模块接口,开发者可自行开发壁纸应用,并管理壁纸应用生命周期。 +WallpaperExtensionAbility为壁纸拓展模块,提供应用生命周期回调和监听壁纸变化的能力。 > **说明:** > > 本模块首批接口从API version 10开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 > -> 本模块接口仅可在FA模型下使用。 +> 本模块接口仅可在Stage模型下使用。 > > 本模块接口均为系统接口。 diff --git a/zh-cn/application-dev/reference/apis/js-apis-avsession.md b/zh-cn/application-dev/reference/apis/js-apis-avsession.md index fdcda2f89e7886143bd628b9574edc7d54875bb0..6ef5769506965f53e49bbb386908a7ed0198c324 100755 --- a/zh-cn/application-dev/reference/apis/js-apis-avsession.md +++ b/zh-cn/application-dev/reference/apis/js-apis-avsession.md @@ -4528,7 +4528,7 @@ aVCastController.on('playPrevious', () => { off(type: 'playPrevious'): void -取消设置播放下一首资源的监听事件。 +取消设置播放上一首资源的监听事件。 **系统能力:** SystemCapability.Multimedia.AVSession.AVCast diff --git a/zh-cn/application-dev/reference/apis/js-apis-enterprise-bundleManager.md b/zh-cn/application-dev/reference/apis/js-apis-enterprise-bundleManager.md index 09f38a219d90d82cad22ea1acbc5cde7df96abbf..12ed7154da017ed90ec127a8cb409f67a56de973 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-enterprise-bundleManager.md +++ b/zh-cn/application-dev/reference/apis/js-apis-enterprise-bundleManager.md @@ -1545,4 +1545,167 @@ bundleManager.uninstall(wantTemp, 'bundleName', 100, true).then(() => { }).catch((err) => { 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\, callback: AsyncCallback\): void + +指定设备管理应用安装指定路径下的应用包。使用callback异步回调。 + +**需要权限:** ohos.permission.ENTERPRISE_INSTALL_BUNDLE + +**系统能力:** SystemCapability.Customization.EnterpriseDeviceManager + +**系统API**: 此接口为系统接口。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------------------------------------- | ---- | ------------------------------- | +| admin | [Want](js-apis-app-ability-want.md) | 是 | 设备管理应用。 | +| hapFilePaths | Array\ | 是 | 待安装应用包路径数组。 | +| callback | AsyncCallback<void> | 是 | 回调函数,当接口调用成功,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\, installParam: InstallParam, callback: AsyncCallback\): void + +指定设备管理应用安装指定路径下的指定安装参数的应用包,。使用callback异步回调。 + +**需要权限:** ohos.permission.ENTERPRISE_INSTALL_BUNDLE + +**系统能力:** SystemCapability.Customization.EnterpriseDeviceManager + +**系统API**: 此接口为系统接口。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------------------------------------- | ---- | ------------------------------- | +| admin | [Want](js-apis-app-ability-want.md) | 是 | 设备管理应用。 | +| hapFilePaths | Array\ | 是 | 待安装应用包路径数组。 | +| installParam | [InstallParam](#installparam) | 是 | 应用包安装参数。 | +| callback | AsyncCallback<void> | 是 | 回调函数,当接口调用成功,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\, installParam?: InstallParam): Promise\ + +指定设备管理应用安装指定路径下的应用包。使用promise异步回调。 + +**需要权限:** ohos.permission.ENTERPRISE_INSTALL_BUNDLE + +**系统能力:** SystemCapability.Customization.EnterpriseDeviceManager + +**系统API**: 此接口为系统接口。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ----- | ----------------------------------- | ---- | ------- | +| admin | [Want](js-apis-app-ability-want.md) | 是 | 设备管理应用。 | +| hapFilePaths | Array\ | 是 | 待安装应用包路径数组。 | +| installParam | [InstallParam](#installparam) | 否 | 应用包安装参数。 | + +**返回值:** + +| 类型 | 说明 | +| --------------------- | ------------------------- | +| Promise<void> | 无返回结果的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 diff --git a/zh-cn/application-dev/reference/apis/js-apis-fileAccess.md b/zh-cn/application-dev/reference/apis/js-apis-fileAccess.md index dedb6a0dcb8d5c590ca43c0e805be64156e851c1..a8fc1059a782ea024c2865797d4bfc8d77a428c8 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-fileAccess.md +++ b/zh-cn/application-dev/reference/apis/js-apis-fileAccess.md @@ -248,7 +248,7 @@ listFile(filter?: Filter) : FileIterator try { let fileIterator = fileInfoDir.listFile(); // 含过滤器实现的listFile - // let fileIterator = rootInfo.listFile(filter); + // let fileIterator = fileInfoDir.listFile(filter); if (!fileIterator) { console.error("listFile interface returns an undefined object"); return; @@ -304,7 +304,7 @@ scanFile(filter?: Filter) : FileIterator; try { let fileIterator = fileInfoDir.scanFile(); // 含过滤器实现的scanFile - // let fileIterator = rootInfo.scanFile(filter); + // let fileIterator = fileInfoDir.scanFile(filter); if (!fileIterator) { console.error("scanFile interface returns an undefined object"); return; diff --git a/zh-cn/application-dev/reference/apis/js-apis-inner-application-accessibilityExtensionContext.md b/zh-cn/application-dev/reference/apis/js-apis-inner-application-accessibilityExtensionContext.md index 9d3b0892d3fb6dc9c4d8cfe0f080667fabdae274..af31fca7a6ecb076efbfc12b2d240415dd7a71d5 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-inner-application-accessibilityExtensionContext.md +++ b/zh-cn/application-dev/reference/apis/js-apis-inner-application-accessibilityExtensionContext.md @@ -285,7 +285,7 @@ getWindowRootElement(windowId?: number): Promise\; | 类型 | 说明 | | ----------------------------------- | ---------------------- | -| Promise<AccessibilityElement> | Promise对象,返回指定屏幕的所有窗口。 | +| Promise<AccessibilityElement> | Promise对象,返回指定窗口的根节点元素。 | **错误码:** @@ -355,7 +355,7 @@ try { getWindowRootElement(windowId: number, callback: AsyncCallback\): void; -获取指定屏幕中的所有窗口, 使用callback异步回调。 +获取指定窗口的根节点元素, 使用callback异步回调。 **系统能力:** SystemCapability.BarrierFree.Accessibility.Core diff --git a/zh-cn/application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md b/zh-cn/application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md index 227a55aa00171fb10605e3a6378cf77c5b34b8b7..0e0cc543271976b40f60ae7b5c4ad23e50ff2734 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md +++ b/zh-cn/application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md @@ -37,6 +37,7 @@ startAbility(want: Want, callback: AsyncCallback<void>): void; - 调用方应用位于后台时,使用该接口启动Ability需申请`ohos.permission.START_ABILITIES_FROM_BACKGROUND`权限 - 跨应用场景下,目标Ability的exported属性若配置为false,调用方应用需申请`ohos.permission.START_INVISIBLE_ABILITY`权限 - 组件启动规则详见:[组件启动规则(Stage模型)](../../application-models/component-startup-rules.md) + - 跨任务链启动时,如果需要跨任务链进行返回,需要参考[Want](js-apis-app-ability-want.md)中的parameter参数用法。 **系统能力**:SystemCapability.Ability.AbilityRuntime.Core @@ -44,7 +45,7 @@ startAbility(want: Want, callback: AsyncCallback<void>): void; | 参数名 | 类型 | 必填 | 说明 | | -------- | -------- | -------- | -------- | -| want | [Want](js-apis-application-want.md) | 是 | 启动Ability的want信息。 | +| want | [Want](js-apis-app-ability-want.md) | 是 | 启动Ability的want信息。 | | callback | AsyncCallback<void> | 是 | callback形式返回启动结果。 | **错误码:** diff --git a/zh-cn/application-dev/reference/apis/js-apis-installer.md b/zh-cn/application-dev/reference/apis/js-apis-installer.md index ee690cbd2bbbdd9a36f1a5eeda591768eff4010d..a7ce7fe8c3e63b76a11272e8aa18bbcc84b776b0 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-installer.md +++ b/zh-cn/application-dev/reference/apis/js-apis-installer.md @@ -19,6 +19,9 @@ import installer from '@ohos.bundle.installer'; | ohos.permission.INSTALL_ENTERPRISE_BUNDLE | system_core | 允许应用安装企业InHouse应用。 | | ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE | system_core | 允许在企业设备上安装企业MDM应用包。 | | 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#权限等级说明) @@ -95,11 +98,15 @@ install(hapFilePaths: Array<string>, installParam: InstallParam, callback: **系统接口:** 此接口为系统接口。 -**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE10+ -> **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限调用此接口。 +**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE10+ 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE10+ 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE10+ +> **说明:** 从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权限 > +> 安装企业NORMAL应用需要ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE或ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限 +> +> 安装企业MDM应用需要ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限 +> > 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限 **系统能力:** SystemCapability.BundleManager.BundleFramework.Core @@ -135,6 +142,7 @@ install(hapFilePaths: Array<string>, installParam: InstallParam, callback: | 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. | +| 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<string>, callback: AsyncCallback<void>): **系统接口:** 此接口为系统接口。 -**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE10+ -> **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限调用此接口。 +**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE10+ 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE10+ 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE10+ +> **说明:** 从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权限 > +> 安装企业NORMAL应用需要ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE或ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限 +> +> 安装企业MDM应用需要ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限 +> > 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限 **系统能力:** SystemCapability.BundleManager.BundleFramework.Core @@ -208,6 +220,7 @@ install(hapFilePaths: Array<string>, callback: AsyncCallback<void>): | 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. | +| 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\, installParam?: InstallParam) : Promise\10+ -> **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限调用此接口。 +**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE10+ 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE10+ 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE10+ +> **说明:** 从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权限 > +> 安装企业NORMAL应用需要ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE或ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限 +> +> 安装企业MDM应用需要ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限 +> > 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限 **系统能力:** SystemCapability.BundleManager.BundleFramework.Core @@ -285,6 +302,7 @@ install(hapFilePaths: Array\, installParam?: InstallParam) : Promise\10+ **系统能力:** SystemCapability.BundleManager.BundleFramework.Core @@ -381,7 +399,7 @@ uninstall(bundleName: string, callback: AsyncCallback<void>): void; **系统接口:** 此接口为系统接口。 -**需要权限:** ohos.permission.INSTALL_BUNDLE +**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.UNINSTALL_BUNDLE10+ **系统能力:** SystemCapability.BundleManager.BundleFramework.Core @@ -433,7 +451,7 @@ uninstall(bundleName: string, installParam?: InstallParam) : Promise\; **系统接口:** 此接口为系统接口。 -**需要权限:** ohos.permission.INSTALL_BUNDLE +**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.UNINSTALL_BUNDLE10+ **系统能力:** SystemCapability.BundleManager.BundleFramework.Core @@ -496,7 +514,7 @@ recover(bundleName: string, installParam: InstallParam, callback: AsyncCallback& **系统接口:** 此接口为系统接口。 -**需要权限:** ohos.permission.INSTALL_BUNDLE +**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.RECOVER_BUNDLE10+ **系统能力:** SystemCapability.BundleManager.BundleFramework.Core @@ -554,7 +572,7 @@ recover(bundleName: string, callback: AsyncCallback<void>): void; **系统接口:** 此接口为系统接口。 -**需要权限:** ohos.permission.INSTALL_BUNDLE +**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.RECOVER_BUNDLE10+ **系统能力:** SystemCapability.BundleManager.BundleFramework.Core @@ -604,7 +622,7 @@ recover(bundleName: string, installParam?: InstallParam) : Promise\; **系统接口:** 此接口为系统接口。 -**需要权限:** ohos.permission.INSTALL_BUNDLE +**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.RECOVER_BUNDLE10+ **系统能力:** SystemCapability.BundleManager.BundleFramework.Core @@ -664,7 +682,7 @@ uninstall(uninstallParam: UninstallParam, callback : AsyncCallback\) : voi **系统接口:** 此接口为系统接口。 -**需要权限:** ohos.permission.INSTALL_BUNDLE +**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.UNINSTALL_BUNDLE10+ **系统能力:** SystemCapability.BundleManager.BundleFramework.Core @@ -718,7 +736,7 @@ uninstall(uninstallParam: UninstallParam) : Promise\; **系统接口:** 此接口为系统接口。 -**需要权限:** ohos.permission.INSTALL_BUNDLE +**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.UNINSTALL_BUNDLE10+ **系统能力:** SystemCapability.BundleManager.BundleFramework.Core @@ -769,6 +787,220 @@ try { } ``` +## BundleInstaller.updateBundleForSelf10+ + +updateBundleForSelf(hapFilePaths: Array, installParam: InstallParam, callback: AsyncCallback): void; + +以异步方法更新当前应用,仅限企业设备上的企业MDM应用调用,且传入的hapFilePaths中的hap必须都属于当前应用,使用callback形式返回结果。 + +**系统接口:** 此接口为系统接口。 + +**需要权限:** ohos.permission.INSTALL_SELF_BUNDLE + +**系统能力:** SystemCapability.BundleManager.BundleFramework.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| --------------- | ---------------------------------------------------- | ---- | ------------------------------------------------------------ | +| hapFilePaths | Array<string> | 是 | 存储应用程序包的路径。路径应该是当前应用程序中存放HAP的数据目录。当传入的路径是一个目录时, 该目录下只能放同一个应用的HAP,且这些HAP的签名需要保持一致。 | +| installParam | [InstallParam](#installparam) | 是 | 指定安装所需的其他参数。 | +| callback | AsyncCallback<void> | 是 | 回调函数,安装应用成功,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.updateBundleForSelf10+ + +updateBundleForSelf(hapFilePaths: Array, callback: AsyncCallback): void; + +以异步方法更新当前应用,仅限企业设备上的企业MDM应用调用,且传入的hapFilePaths中的hap必须都属于当前应用,使用callback形式返回结果。 + +**系统接口:** 此接口为系统接口。 + +**需要权限:** ohos.permission.INSTALL_SELF_BUNDLE + +**系统能力:** SystemCapability.BundleManager.BundleFramework.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| --------------- | ---------------------------------------------------- | ---- | ------------------------------------------------------------ | +| hapFilePaths | Array<string> | 是 | 存储应用程序包的路径。路径应该是当前应用程序中存放HAP的数据目录。当传入的路径是一个目录时, 该目录下只能放同一个应用的HAP,且这些HAP的签名需要保持一致。 | +| callback | AsyncCallback<void> | 是 | 回调函数,安装应用成功,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.updateBundleForSelf10+ + +updateBundleForSelf(hapFilePaths: Array, installParam?: InstallParam): Promise; + +以异步方法更新当前应用,仅限企业设备上的企业MDM应用调用,且传入的hapFilePaths中的hap必须都属于当前应用,使用promise形式返回结果。 + +**系统接口:** 此接口为系统接口。 + +**需要权限:** ohos.permission.INSTALL_SELF_BUNDLE + +**系统能力:** SystemCapability.BundleManager.BundleFramework.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| --------------- | ---------------------------------------------------- | ---- | ------------------------------------------------------------ | +| hapFilePaths | Array<string> | 是 | 存储应用程序包的路径。路径应该是当前应用程序中存放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 应用程序安装卸载哈希参数信息。 diff --git a/zh-cn/application-dev/reference/apis/js-apis-intelligentVoice.md b/zh-cn/application-dev/reference/apis/js-apis-intelligentVoice.md new file mode 100755 index 0000000000000000000000000000000000000000..49ed5e37dfce2cf5221189da6965ee734e229f30 --- /dev/null +++ b/zh-cn/application-dev/reference/apis/js-apis-intelligentVoice.md @@ -0,0 +1,1643 @@ +# @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<EnrollIntelligentVoiceEngine>): 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<EnrollIntelligentVoiceEngine> + + +创建智能语音注册引擎实例,使用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<WakeupIntelligentVoiceEngine>): 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<WakeupIntelligentVoiceEngine> + +创建智能语音唤醒引擎实例,使用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<IntelligentVoiceEngineType> + +获取支持的智能语音引擎列表信息。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Array\<[IntelligentVoiceEngineType](#intelligentvoiceenginetype)\> | 支持的智能语音引擎类型数组。 | + +**示例:** + +```js +let info = intelligentVoiceManager.getCapabilityInfo(); +``` + +### on('serviceChange') + +on(type: 'serviceChange', callback: Callback<ServiceChangeType>): 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\): 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<Array<string>>): void + +获取支持的区域,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| callback | AsyncCallback<Array<string>> | 是 | 返回支持区域的数组,当前只支持中国,对应取值为'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<Array<string>> + +获取支持的区域,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise<Array<string>> | 返回支持区域的数组,当前只支持中国,对应取值为'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<void>): void + +初始化注册智能语音引擎,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| config | [EnrollEngineConfig](#enrollengineconfig) | 是 | 注册引擎配置。 | +| callback |AsyncCallback<void> | 是 | 返回初始化结果。 | + +**错误码:** + +以下错误码的详细介绍请参见[智能语音错误码](../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<void> + +初始化注册智能语音引擎,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| config | [EnrollEngineConfig](#enrollengineconfig) | 是 | config表示注册引擎配置。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise<void> | 无返回结果的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<EnrollCallbackInfo>): void + +获取注册结果,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| isLast | boolean | 是 | isLast表示是否为最后一次注册,false为非最后一次,true为最后一次。 | +| callback | AsyncCallback<[EnrollCallbackInfo](#enrollcallbackinfo)> | 是 | 返回注册结果。 | + +**示例:** + +```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<EnrollCallbackInfo> + +获取注册结果,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| isLast | boolean | 是 | isLast表示是否为最后一次注册,false为非最后一次,true为最后一次。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise<[EnrollCallbackInfo](#enrollcallbackinfo)> | 返回注册结果。 | + +**示例:** + +```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<void>): void + +停止注册,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| callback | AsyncCallback<void> | 是 | 返回停止结果。 | + +**示例:** + +```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<void> + +停止注册,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise<void> | 无返回结果的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<void>): void + +提交注册,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| callback | AsyncCallback<void> | 是 | 返回确认注册结果。 | + +**错误码:** + +以下错误码的详细介绍请参见[智能语音错误码](../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<void> + +提交注册,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise<void> | 无返回结果的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 + +设置唤醒应用的hap信息,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| info | [WakeupHapInfo](#wakeuphapinfo) | 是 | 唤醒hap信息。 | +| callback | AsyncCallback\ | 是 | 返回设置唤醒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\ + +设置唤醒应用的hap信息,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise<void> | 无返回结果的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 + +设置唤醒灵敏度,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| sensibility | [SensibilityType](#sensibilitytype) | 是 | 灵敏度类型。 | +| callback | AsyncCallback\ | 是 | 返回设置灵敏度的结果。 | + +**错误码:** + +以下错误码的详细介绍请参见[智能语音错误码](../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\ + +设置唤醒灵敏度,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| sensibility | [SensibilityType](#sensibilitytype) | 是 | 灵敏度类型。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise<void> | 无返回结果的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 + +设置指定的智能语音参数,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| key | string | 是 | 键。 | +| value | string | 是 | 值。 | +| callback | AsyncCallback\ | 是 | 返回设置智能语音参数的结果。 | + +**错误码:** + +以下错误码的详细介绍请参见[智能语音错误码](../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\ + +设置指定的智能语音参数,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| key | string | 是 | 键。 | +| value | string | 是 | 值。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise<void> | 无返回结果的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\): void + +获取指定的智能语音参数,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| key | string | 是 | 键。 | +| callback | AsyncCallback\ | 是 | 返回智能语音参数。 | + +**错误码:** + +以下错误码的详细介绍请参见[智能语音错误码](../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\ + +获取指定的智能语音参数,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| key | string | 是 | 键。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise\ | 返回智能语音参数。 | + +**错误码:** + +以下错误码的详细介绍请参见[智能语音错误码](../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<void>): void + +释放注册智能语音引擎,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| callback | AsyncCallback\ | 是 | 返回释放注册引擎的结果。 | + +**示例:** + +```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<void> + +释放注册智能语音引擎,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise<void> | 无返回结果的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<Array<string>>): void + +获取支持的区域,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| callback | AsyncCallback<Array<string>> | 是 | 返回支持区域的数组,当前只支持中国,对应取值为'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<Array<string>> + +获取支持的区域,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise<Array<string>> | 返回支持区域的数组,当前只支持中国,对应取值为'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 + +设置唤醒应用的hap信息,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| info | [WakeupHapInfo](#wakeuphapinfo) | 是 | 唤醒hap信息。 | +| callback | AsyncCallback\ | 是 | 返回设置唤醒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\ + +设置唤醒应用的hap信息,使用promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| info | [WakeupHapInfo](#wakeuphapinfo) | 是 | 唤醒hap信息。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise<void> | 无返回结果的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 + +设置唤醒灵敏度,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| sensibility | [SensibilityType](#sensibilitytype) | 是 | 灵敏度类型。 | +| callback | AsyncCallback\ | 是 | 返回设置灵敏度的结果。 | + +**错误码:** + +以下错误码的详细介绍请参见[智能语音错误码](../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\ + +设置唤醒灵敏度,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| sensibility | [SensibilityType](#sensibilitytype) | 是 | 灵敏度类型。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise<void> | 无返回结果的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 + +设置指定的智能语音参数,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| key | string | 是 | 键。 | +| value | string | 是 | 值。 | +| callback | AsyncCallback\ | 是 | 返回设置智能语音参数的结果。 | + +**错误码:** + +以下错误码的详细介绍请参见[智能语音错误码](../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\ + +设置指定的智能语音参数,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| key | string | 是 | 键。 | +| value | string | 是 | 值。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise<void> | 无返回结果的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\): void + +获取指定的智能语音参数,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| key | string | 是 | 键。 | +| callback | AsyncCallback\ | 是 | 返回智能语音参数。 | + +**错误码:** + +以下错误码的详细介绍请参见[智能语音错误码](../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\ + +获取指定的智能语音参数,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| key | string | 是 | 键。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise\ | 返回智能语音参数。 | + +**错误码:** + +以下错误码的详细介绍请参见[智能语音错误码](../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 + +释放唤醒智能语音引擎,使用callback异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| callback | AsyncCallback\ | 是 | 返回释放唤醒引擎的结果。 | + +**示例:** + +```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\ + +释放唤醒智能语音引擎,使用Promise异步回调。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Promise<void> | 无返回结果的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\): 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\): void; + +取消订阅唤醒事件。 + +**需要权限:** ohos.permission.MANAGE_INTELLIGENT_VOICE + +**系统能力:** SystemCapability.AI.IntelligentVoice.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | --- | ------------------------------------------- | +| type |string | 是 | 唤醒智能语音事件,固定取为'wakeupIntelligentVoiceEvent'。 | +| callback | Callback\<[WakeupIntelligentVoiceEngineCallbackInfo](#wakeupintelligentvoiceenginecallbackinfo)\> | 否 | 收到唤醒事件的对应处理。无参数,则取消所有的订阅,否则,取消对应的订阅 | + +**示例:** + +```js +wakeupIntelligentVoiceEngine.off('wakeupIntelligentVoiceEvent'); +``` diff --git a/zh-cn/application-dev/reference/apis/js-apis-notificationSubscribe.md b/zh-cn/application-dev/reference/apis/js-apis-notificationSubscribe.md index 07245ceba265a5abdb9fe5de0d046419b91704d9..3969df3f2968d1a8226c360cb29b3e0b17c7d78b 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-notificationSubscribe.md +++ b/zh-cn/application-dev/reference/apis/js-apis-notificationSubscribe.md @@ -443,6 +443,90 @@ notificationSubscribe.remove(hashCode, reason).then(() => { console.info("remove success"); }); ``` +## NotificationSubscribe.remove + +remove(hashCodes: Array\, reason: RemoveReason, callback: AsyncCallback\): void + +批量删除指定通知(Callback形式)。 + +**系统能力**:SystemCapability.Notification.Notification + +**需要权限**: ohos.permission.NOTIFICATION_CONTROLLER + +**系统API**: 此接口为系统接口,三方应用不支持调用。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|-----------|-------------------------------| ---- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| hashCodes | Array\ | 是 | 通知唯一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\ | 是 | 删除指定通知回调函数。 | + +**错误码:** + +错误码详细介绍请参考[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\, reason: RemoveReason): Promise\ + +批量删除指定通知(Promise形式)。 + +**系统能力**:SystemCapability.Notification.Notification + +**需要权限**: ohos.permission.NOTIFICATION_CONTROLLER + +**系统API**: 此接口为系统接口,三方应用不支持调用。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|-----------|-------------------------------| ---- |-------------| +| hashCodes | Array\ | 是 | 通知唯一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 diff --git a/zh-cn/application-dev/reference/apis/js-apis-request.md b/zh-cn/application-dev/reference/apis/js-apis-request.md index 5e767823515e06bfb372746b0fdecf0967c457cc..eec7af90de0a05030997618f7915a077aeba3580 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-request.md +++ b/zh-cn/application-dev/reference/apis/js-apis-request.md @@ -282,6 +282,10 @@ on(type: 'progress', callback:(uploadedSize: number, totalSize: number) => vo 订阅上传任务进度监听,同步方法,使用callback形式返回结果。 +> **说明:** +> +> 当应用处于后台时,为满足功耗性能要求,不支持调用此接口进行回调。 + **需要权限**:ohos.permission.INTERNET **系统能力**: SystemCapability.MiscServices.Upload @@ -839,6 +843,10 @@ on(type: 'progress', callback:(receivedSize: number, totalSize: number) => vo 订阅下载任务进度监听,同步方法,使用callback形式返回结果。 +> **说明:** +> +> 当应用处于后台时,为满足功耗性能要求,不支持调用此接口进行回调。 + **需要权限**:ohos.permission.INTERNET **系统能力**: SystemCapability.MiscServices.Download diff --git a/zh-cn/application-dev/reference/apis/js-apis-uiappearance.md b/zh-cn/application-dev/reference/apis/js-apis-uiappearance.md index a3f5ed1d72ab614ad2180c16468b793674b9f0c3..141138a52de55578e3d26b38943f1b7dcf7f2241 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-uiappearance.md +++ b/zh-cn/application-dev/reference/apis/js-apis-uiappearance.md @@ -40,16 +40,34 @@ setDarkMode(mode: DarkMode, callback: AsyncCallback\): void **系统能力:** SystemCapability.ArkUI.UiAppearance **参数:** + | 参数名 | 类型 | 必填 | 说明 | | -- | -- | -- | -- | | mode | [DarkMode](#darkmode) | 是 | 指定系统的深色模式配置 | | callback | AsyncCallback\| 是 | 配置深色模式的异步回调 | +**错误码:** + +错误码详细介绍请参考[errcode-uiappearance](../errorcodes/errorcode-uiappearance.md)。 + +| 错误码ID | 错误码信息 | +| -- | -- | +| 500001 | Internal error. | + **示例:** + ```ts -uiAppearance.setDarkMode(uiAppearance.DarkMode.ALWAYS_DARK, (err) => { - console.info(`${err}`); -}) +try { + 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\; **系统能力:** SystemCapability.ArkUI.UiAppearance **参数:** + | 参数名 | 类型 | 必填 | 说明 | | -- | -- | -- | -- | | mode | [DarkMode](#darkmode) | 是 | 指定系统深色模式配置 | @@ -74,13 +93,26 @@ setDarkMode(mode: DarkMode): Promise\; | ------ | ------------------------------ | | Promise\ | Promise对象。无返回结果的Promise对象。| +**错误码:** + +错误码详细介绍请参考[errcode-uiappearance](../errorcodes/errorcode-uiappearance.md)。 + +| 错误码ID | 错误码信息 | +| -- | -- | +| 500001 | Internal error. | + **示例:** + ```ts -uiAppearance.setDarkMode(uiAppearance.DarkMode.ALWAYS_DARK).then(() => { - console.log('Set dark-mode successfully.'); -}).catch((err) => { - console.log(`Set dark-mode failed, ${err}`); -}); +try { + uiAppearance.setDarkMode(uiAppearance.DarkMode.ALWAYS_DARK).then(() => { + console.info('Set dark-mode successfully.'); + }).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; **系统能力:** SystemCapability.ArkUI.UiAppearance **返回值:** + | 类型 | 说明 | | -- | -- | |[DarkMode](#darkmode) | 系统当前的深色模式配置 | +**错误码:** + +错误码详细介绍请参考[errcode-uiappearance](../errorcodes/errorcode-uiappearance.md)。 + +| 错误码ID | 错误码信息 | +| -- | -- | +| 500001 | Internal error. | + **示例:** + ```ts -let darkMode = uiAppearance.getDarkMode(); -console.log(`Get dark-mode ${darkMode}`); +try { + 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 diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-navigation.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-navigation.md index 420c4edd5e47e3fd3cf060e42d08eafdb07ff8a0..51b3b67b3de6570bb2874963987a754f87fb9033 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-navigation.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-navigation.md @@ -330,7 +330,7 @@ constructor(name: string, param: unknown) | 名称 | 描述 | | ----- | ---------------------------------------- | | Stack | 导航栏与内容区独立显示,相当于两个页面。 | -| Split | 导航栏与内容区分两栏显示。 | +| Split | 导航栏与内容区分两栏显示。
以下navBarWidthRange的值用[minNavBarWidth,maxNavBarWidth]表示
1.当navBarWidth属性的值,在navBarWidthRange属性的值范围以外时,navBarWidth按如下规则显示:
navBarWidth < minNavBarWidth时,navBarWidth修正为minNavBarWidth;
navBarWidth > maxNavBarWidth,且组件宽度 - minContentWidth大于maxNavBarWidth时,navBarWidth修正为maxNavBarWidth;
navBarWidth > maxNavBarWidth,且组件宽度 - minContentWidth小于minNavBarWidth时,navBarWidth修正为minNavBarWidth;
navBarWidth > maxNavBarWidth,且组件宽度 - minContentWidth在navBarWidthRange范围内,navBarWidth修正为组件宽度 - minContentWidth。
2.缩小组件尺寸时,先缩小内容区的尺寸至minContentWidth,然后再缩小导航栏的尺寸至minNavBarWidth。若继续缩小,先缩小内容区,内容区消失后再缩小导航栏。
3.设置导航栏为固定尺寸时,若持续缩小组件尺寸,导航栏最后压缩显示。
4.当navBarWidth值与minContentWidth的值相加大于组件尺寸时,会优先显示导航栏。 | | Auto | API version 9之前:窗口宽度>=520vp时,采用Split模式显示;窗口宽度<520vp时,采用Stack模式显示。
API version 10及以上:窗口宽度>=600vp时,采用Split模式显示;窗口宽度<600vp时,采用Stack模式显示,600vp等于minNavBarWidth(240vp) + minContentWidth (360vp)。 | ## TitleHeight枚举说明 diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-progress.md b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-progress.md index 6c920619bc70bf2ef064f678c0bf3ef6e98e1c42..6483676af80582371ae3c8d12a47e509186a3f82 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-progress.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-progress.md @@ -97,6 +97,7 @@ Progress(options: {value: number, total?: number, type?: ProgressType}) | 名称 | 参数类型 | 必填 | 描述 | | ------------- | ---------------------------- | ---- | ------------------------------------------------------------------------------------------ | | strokeWidth | [Length](ts-types.md#length) | 否 | 设置进度条宽度(不支持百分比设置)。
默认值:4.0vp | +| strokeRadius | [PX](ts-types.md#px10) \| [VP](ts-types.md#vp10) \| [LPX](ts-types.md#lpx10) \| [Resource](ts-types.md#resource)| 否 | 设置线性进度条圆角半径。
取值范围[0, strokeWidth / 2]。默认值:strokeWidth / 2。 | | enableScanEffect | boolean | 否 | 进度条扫光效果的开关。
默认值: false | | enableSmoothEffect | boolean | 否 | 进度平滑动效的开关。开启平滑动效后设置进度,进度会从当前值渐变至设定值,否则进度从当前值突变至设定值。
默认值:true | diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-container-sidebarcontainer.md b/zh-cn/application-dev/reference/arkui-ts/ts-container-sidebarcontainer.md index 14eeab03c89f587dcf09e6f8f63f78d13caf3984..72eb33eaa2c724fab078873adb3072c39193213a 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-container-sidebarcontainer.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-container-sidebarcontainer.md @@ -51,7 +51,7 @@ SideBarContainer( type?: SideBarContainerType ) | autoHide9+ | boolean | 设置当侧边栏拖拽到小于最小宽度后,是否自动隐藏。
默认值:true
**说明:**
受minSideBarWidth属性方法影响,minSideBarWidth属性方法未设置值使用默认值。
拖拽过程中判断是否要自动隐藏。小于最小宽度时需要阻尼效果触发隐藏(越界一段距离) | | sideBarPosition9+ | [SideBarPosition](#sidebarposition9枚举说明) | 设置侧边栏显示位置。
默认值:SideBarPosition.Start | | divider10+ | [DividerStyle](#dividerstyle10对象说明) \| null | 设置分割线的样式。
- 默认为DividerStyle:显示分割线。
- null:不显示分割线。 | -| minContentWidth10+ | [Dimension](ts-types.md#dimension10) | SideBarContainer组件内容区的最小宽度。
默认值:360vp
单位:vp
**说明:**
设置为小于0的值时按默认值显示,未设置时为0vp。
Embed场景下,增大组件尺寸时仅增大内容区的尺寸,缩小组件尺寸时,先缩小内容区的尺寸至minContentWidth,然后再缩小侧边栏的尺寸,当缩小侧边栏的尺寸至minSideBarWidth后,继续缩小组件尺寸时,会保持侧边栏最小尺寸,继续缩小内容区尺寸,并采用截断方式显示内容区,内容区尺寸可以缩小至0vp。
minContentWidth优先于侧边栏的maxSideBarWidth与sideBarWidth属性,minContentWidth未设置时默认值优先级低于设置的minSideBarWidth与maxSideBarWidth属性。 | +| minContentWidth10+ | [Dimension](ts-types.md#dimension10) | SideBarContainer组件内容区的最小宽度。
默认值:360vp
单位:vp
**说明:**
设置为小于0的值时按默认值显示,未设置时为0vp。
Embed场景下,增大组件尺寸时仅增大内容区的尺寸。
缩小组件尺寸时,先缩小内容区的尺寸至minContentWidth。继续缩小组件尺寸时,保持内容区宽度minContentWidth不变,优先缩小侧边栏的尺寸。
当缩小侧边栏的尺寸至minSideBarWidth后,继续缩小组件尺寸时,
- 如果autoHide属性为false,则会保持侧边栏宽度minSideBarWidth和内容区宽度minContentWidth不变,但内容区会被截断显示;
- 如果autoHide属性为true,则会优先隐藏侧边栏,然后继续缩小至内容区宽度minContentWidth后,内容区宽度保持不变,但内容区会被截断显示。
minContentWidth优先于侧边栏的maxSideBarWidth与sideBarWidth属性,minContentWidth未设置时默认值优先级低于设置的minSideBarWidth与maxSideBarWidth属性。 | ## ButtonStyle对象说明 diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-modal-transition.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-modal-transition.md index b8a54dbbc3f3710602348cd339cd7943f91ed2e6..f6481ebae86c468d9901d966fac855f6e22c3957 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-modal-transition.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-modal-transition.md @@ -5,7 +5,10 @@ > **说明:** > > 从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 +> > 不支持横竖屏切换。 +> +> 不支持路由跳转。 ## 属性 diff --git a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-sheet-transition.md b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-sheet-transition.md index fa047a20d64d73fa857980255429bc647b1efbe8..24f51ad16c7020c6ef07a7b7b160e5f79fc41012 100644 --- a/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-sheet-transition.md +++ b/zh-cn/application-dev/reference/arkui-ts/ts-universal-attributes-sheet-transition.md @@ -7,6 +7,8 @@ > 从API Version 10开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 > > 不支持横竖屏切换。 +> +> 不支持路由跳转。 ## 属性 diff --git a/zh-cn/application-dev/reference/errorcodes/Readme-CN.md b/zh-cn/application-dev/reference/errorcodes/Readme-CN.md index 9de43495d8ee9b58aaed97e93e5cf932d7a3f6d9..57264109d1157191419aff36b38f3c864aa01eed 100644 --- a/zh-cn/application-dev/reference/errorcodes/Readme-CN.md +++ b/zh-cn/application-dev/reference/errorcodes/Readme-CN.md @@ -5,6 +5,8 @@ - [元能力子系统错误码](errorcode-ability.md) - [DistributedSchedule错误码](errorcode-DistributedSchedule.md) - [卡片错误码](errorcode-form.md) +- AI业务 + - [智能语音错误码](errorcode-intelligentVoice.md) - 包管理 - [包管理子系统通用错误码](errorcode-bundle.md) - [zlib子系统错误码](errorcode-zlib.md) diff --git a/zh-cn/application-dev/reference/errorcodes/errorcode-bundle.md b/zh-cn/application-dev/reference/errorcodes/errorcode-bundle.md index f4165f866c88ea888fca71850f891b4e9d4fbe39..153e3420be130cd831becc382a529e75a6320a79 100644 --- a/zh-cn/application-dev/reference/errorcodes/errorcode-bundle.md +++ b/zh-cn/application-dev/reference/errorcodes/errorcode-bundle.md @@ -644,4 +644,44 @@ Failed to install the HAP because the code signature verification is failed. **处理步骤**
1. 检查代码签名文件对应的module是否包含在安装包路径之中。 2. 检查提供的代码签名文件的路径是否合法。 -3. 使用和安装包匹配的代码签名文件。 \ No newline at end of file +3. 使用和安装包匹配的代码签名文件。 + +## 17700049 应用自升级时安装的应用与调用方包名不同 +**错误信息**
+Failed to install the HAP because the bundleName is different from the bundleName of the caller application. + +**错误描述**
+企业mdm应用自升级时,安装的应用与调用方包名不同。 + +**可能原因**
+1. 要安装的hap或hsp不属于当前应用。 + +**处理步骤**
+1. 检查要安装的hap或hsp是否属于当前应用。 + +## 17700050 企业设备校验失败 +**错误信息**
+Failed to install the HAP because enterprise normal/MDM bundle cannot be installed on non-enterprise device. + +**错误描述**
+安装应用时,企业normal应用或企业mdm应用无法在非企业设备上安装。 + +**可能原因**
+1. 安装设备不是企业设备。 + +**处理步骤**
+1. 检查安装设备是否为企业设备。 +2. 检查设备参数const.bms.allowenterprisebundle是否为true + +## 17700051 应用自升级时安装的应用与调用方包名不同 +**错误信息**
+Failed to install the HAP because the distribution type of caller application is not enterprise_mdm. + +**错误描述**
+企业mdm应用自升级时,调用方的分发类型不是企业mdm。 + +**可能原因**
+1. 调用方的分发类型不是企业mdm。 + +**处理步骤**
+1. 检查应用的签名文件是否正确配置。 diff --git a/zh-cn/application-dev/reference/errorcodes/errorcode-intelligentVoice.md b/zh-cn/application-dev/reference/errorcodes/errorcode-intelligentVoice.md new file mode 100755 index 0000000000000000000000000000000000000000..9bee62e38caac99eea98dbc92fed5fa5993f904c --- /dev/null +++ b/zh-cn/application-dev/reference/errorcodes/errorcode-intelligentVoice.md @@ -0,0 +1,81 @@ +# 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)时,返回失败。 + +**可能原因** + +没有完成指定次数的注册流程。 + +**处理步骤** + +根据界面上要求的注册次数注册完成后再确认注册结果。 diff --git a/zh-cn/application-dev/reference/errorcodes/errorcode-uiappearance.md b/zh-cn/application-dev/reference/errorcodes/errorcode-uiappearance.md new file mode 100644 index 0000000000000000000000000000000000000000..4fd7d7144d81dee74ad782574af65da993aedd26 --- /dev/null +++ b/zh-cn/application-dev/reference/errorcodes/errorcode-uiappearance.md @@ -0,0 +1,23 @@ +# 用户界面外观服务错误码 + +> **说明:** +> +> 以下仅介绍本模块特有错误码,通用错误码请参考[通用错误码说明文档](errorcode-universal.md)。 + +## 500001 内部错误 + +**错误信息** + +Internal error. + +**错误描述** + +当出现了开发者解决不了的内部异常错误,如参数持久化错误,获取服务失败,配置深浅色模式失败等,系统会产生此错误码。 + +**可能原因** + +参数持久化错误,获取服务失败,配置深浅色模式失败等。 + +**处理步骤** + +NA diff --git a/zh-cn/application-dev/security/accesstoken-guidelines.md b/zh-cn/application-dev/security/accesstoken-guidelines.md index 9978828971c32bfbb31135ec30028fbc1ecd8add..57a4f6f752995e0cb33d12039d2b11490c87f102 100644 --- a/zh-cn/application-dev/security/accesstoken-guidelines.md +++ b/zh-cn/application-dev/security/accesstoken-guidelines.md @@ -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) diff --git a/zh-cn/application-dev/security/cert-guidelines.md b/zh-cn/application-dev/security/cert-guidelines.md index cb77fbca5ef8270c8440f941668c39a8f6c2f055..5d52618f76e1228834b165864f96c25e47802bc4 100755 --- a/zh-cn/application-dev/security/cert-guidelines.md +++ b/zh-cn/application-dev/security/cert-guidelines.md @@ -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 diff --git a/zh-cn/application-dev/security/cryptoFramework-guidelines.md b/zh-cn/application-dev/security/cryptoFramework-guidelines.md index c0dd86eae6a9f9bd3b29192f8e195bef2f78df3b..02113e758e5c00264401c9f1f46ca3e1e2021a30 100644 --- a/zh-cn/application-dev/security/cryptoFramework-guidelines.md +++ b/zh-cn/application-dev/security/cryptoFramework-guidelines.md @@ -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) diff --git a/zh-cn/application-dev/security/permission-group-list.md b/zh-cn/application-dev/security/permission-group-list.md index 4eda996029c2fdfe862c33a486dddde010a480b0..6882680e71728c0dfa9d5d234a522d7041e4b6bd 100644 --- a/zh-cn/application-dev/security/permission-group-list.md +++ b/zh-cn/application-dev/security/permission-group-list.md @@ -86,3 +86,7 @@ ## 读取已安装应用列表 - ohos.permission.GET_INSTALLED_BUNDLE_LIST + +## 蓝牙 + +- ohos.permission.ACCESS_BLUETOOTH diff --git a/zh-cn/application-dev/task-management/agent-powered-reminder.md b/zh-cn/application-dev/task-management/agent-powered-reminder.md index 5763f56f078e99480512617a4b19e09c90b1966d..a6bd8060ee0a53decc4ceb67c4fb4169cba23d1f 100644 --- a/zh-cn/application-dev/task-management/agent-powered-reminder.md +++ b/zh-cn/application-dev/task-management/agent-powered-reminder.md @@ -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) \ No newline at end of file diff --git a/zh-cn/application-dev/task-management/continuous-task.md b/zh-cn/application-dev/task-management/continuous-task.md index 7c4e84649ff67d792adbc3061a7ffbc495683c80..c027b5b4bb68cdb95319c94e54b66058366e8fd3 100644 --- a/zh-cn/application-dev/task-management/continuous-task.md +++ b/zh-cn/application-dev/task-management/continuous-task.md @@ -475,4 +475,4 @@ 针对长时任务开发,有以下相关实例可供参考: -- [ContinuousTask:长时任务(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/ContinuousTask) \ No newline at end of file +- [长时任务(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/ContinuousTask) \ No newline at end of file diff --git a/zh-cn/application-dev/task-management/transient-task.md b/zh-cn/application-dev/task-management/transient-task.md index b2e055e9eafcc7b3c32a9348172519935c75e81b..e83639ca331748d05bc19d404b17f6709887a5de 100644 --- a/zh-cn/application-dev/task-management/transient-task.md +++ b/zh-cn/application-dev/task-management/transient-task.md @@ -97,4 +97,4 @@ 针对短时任务开发,有以下相关实例可供参考: -- [短时任务(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/TransientTask) \ No newline at end of file +- [短时任务(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/TransientTask) \ No newline at end of file diff --git a/zh-cn/application-dev/task-management/work-scheduler.md b/zh-cn/application-dev/task-management/work-scheduler.md index e9f83c53723b3849f0542247f689410f47a60ac2..ddbe25b05d0a26a0287a3572b2f55c191ce5241b 100644 --- a/zh-cn/application-dev/task-management/work-scheduler.md +++ b/zh-cn/application-dev/task-management/work-scheduler.md @@ -210,4 +210,4 @@ WorkInfo参数用于设置应用条件,参数设置时需遵循以下规则: 针对延迟任务调度的开发,有以下相关示例可供参考: -- [WorkScheduler的创建与使用(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/WorkScheduler) \ No newline at end of file +- [延迟任务调度(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/WorkScheduler) \ No newline at end of file diff --git a/zh-cn/application-dev/telephony/telephony-call.md b/zh-cn/application-dev/telephony/telephony-call.md index 186774684e11a6c01b992e285e200bf4f3dea857..eb35ad9d63907e07e9cd798a2040a64f61d71fc1 100644 --- a/zh-cn/application-dev/telephony/telephony-call.md +++ b/zh-cn/application-dev/telephony/telephony-call.md @@ -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) diff --git a/zh-cn/application-dev/telephony/telephony-sms.md b/zh-cn/application-dev/telephony/telephony-sms.md index a6ee6145019ab2d49fdb3b2292889ae72708bfc9..4c353b85c7165391f9a315b725fb16ca7a6d95d0 100644 --- a/zh-cn/application-dev/telephony/telephony-sms.md +++ b/zh-cn/application-dev/telephony/telephony-sms.md @@ -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) diff --git a/zh-cn/application-dev/tools/bm-tool.md b/zh-cn/application-dev/tools/bm-tool.md index f7d9ff64e913212554d419eebfb16f0ec2556e5d..f5c4bccb9dc5b39f692d3799822efeac1ee0f3fa 100644 --- a/zh-cn/application-dev/tools/bm-tool.md +++ b/zh-cn/application-dev/tools/bm-tool.md @@ -326,3 +326,243 @@ bm dump-shared -n com.ohos.lib # 显示指定应用指定模块依赖的共享库信息 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 diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001389116960.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001389116960.png new file mode 100644 index 0000000000000000000000000000000000000000..ffbb9c855d78a68f8a986231289bd0fed7e5af30 Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001389116960.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001559130596.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001559130596.png new file mode 100644 index 0000000000000000000000000000000000000000..2905fde6bb4b32d85257bcb747b2e53be0397066 Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001559130596.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001560201786.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001560201786.png new file mode 100644 index 0000000000000000000000000000000000000000..7e0f38e78cb7b7129569a0245abd1470083a50c3 Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001560201786.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001560338986.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001560338986.png new file mode 100644 index 0000000000000000000000000000000000000000..c8caa493123b959a4e64dadf162abab3cb761a95 Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001560338986.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001585042216.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001585042216.png new file mode 100644 index 0000000000000000000000000000000000000000..4007248d359c66c464cf90ffe57a4d1adc28e18e Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001585042216.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001585201996.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001585201996.png new file mode 100644 index 0000000000000000000000000000000000000000..02f466053887ff304d3e2332d0bd643f9b5db3f5 Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001585201996.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001585361412.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001585361412.png new file mode 100644 index 0000000000000000000000000000000000000000..878fce9135a50637e4a7884fc480877d3d9a26ec Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001585361412.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001585521364.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001585521364.png new file mode 100644 index 0000000000000000000000000000000000000000..991423fa8ba9046bef06dfd70843486a9c8a980e Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001585521364.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001609001262.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001609001262.png new file mode 100644 index 0000000000000000000000000000000000000000..00b6017903bb013acb0c2570515533e86acfbd3c Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001609001262.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001609976041.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001609976041.png new file mode 100644 index 0000000000000000000000000000000000000000..2d2996af387e3575c6a72c2b1d6bb81aea24cf92 Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001609976041.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001610761941.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001610761941.png new file mode 100644 index 0000000000000000000000000000000000000000..ae15c786cfd8bae8697c22a1123291db325ba32d Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001610761941.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001635521909.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001635521909.png new file mode 100644 index 0000000000000000000000000000000000000000..eed9ac436735c08764e923958c568244e38a8b2e Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001635521909.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001635641893.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001635641893.png new file mode 100644 index 0000000000000000000000000000000000000000..9f068d6d9176def07b02bb8088595ef529e17113 Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001635641893.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001635761329.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001635761329.png new file mode 100644 index 0000000000000000000000000000000000000000..3cc3f0826bfd041bc4705a16a6ac47dea733b2d6 Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001635761329.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_00000016359212311.png b/zh-cn/application-dev/tools/figures/zh-cn_image_00000016359212311.png new file mode 100644 index 0000000000000000000000000000000000000000..9ec72e6c345962a82c4d57ae79b5722246472786 Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_00000016359212311.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_0000001635921233.png b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001635921233.png new file mode 100644 index 0000000000000000000000000000000000000000..b5ed77f5bdb9064b3b38aba6e679db768e811e27 Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_0000001635921233.png differ diff --git a/zh-cn/application-dev/tools/figures/zh-cn_image_00000016359212344.png b/zh-cn/application-dev/tools/figures/zh-cn_image_00000016359212344.png new file mode 100644 index 0000000000000000000000000000000000000000..bc4c854a434d1faa347bd1bdffd56385e4558880 Binary files /dev/null and b/zh-cn/application-dev/tools/figures/zh-cn_image_00000016359212344.png differ diff --git a/zh-cn/application-dev/ui/arkts-common-components-video-player.md b/zh-cn/application-dev/ui/arkts-common-components-video-player.md index 4caf36b0bc4a8bcc30fa7d38032ce592201eba19..27008cd8bfb45d9012582b52743351b9aba55d22 100644 --- a/zh-cn/application-dev/ui/arkts-common-components-video-player.md +++ b/zh-cn/application-dev/ui/arkts-common-components-video-player.md @@ -271,4 +271,6 @@ 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) \ No newline at end of file diff --git a/zh-cn/application-dev/ui/arkts-common-events-touch-screen-event.md b/zh-cn/application-dev/ui/arkts-common-events-touch-screen-event.md index f1dcb94d55dfa89441d4a006aee33ff4e81404e8..b1c50dc95922222e5647c9ea928f352cefcc3423 100644 --- a/zh-cn/application-dev/ui/arkts-common-events-touch-screen-event.md +++ b/zh-cn/application-dev/ui/arkts-common-events-touch-screen-event.md @@ -306,3 +306,9 @@ struct TouchExample { ![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 diff --git a/zh-cn/application-dev/ui/arkts-drawing-customization-on-canvas.md b/zh-cn/application-dev/ui/arkts-drawing-customization-on-canvas.md index 9dd34445b3926fa31ad932bfa1209dfdec52136f..a0d61caac54107fcd374f65c06cd204dfdb1a143 100644 --- a/zh-cn/application-dev/ui/arkts-drawing-customization-on-canvas.md +++ b/zh-cn/application-dev/ui/arkts-drawing-customization-on-canvas.md @@ -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) - [自定义抽奖转盘(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/CanvasComponent) \ No newline at end of file diff --git a/zh-cn/application-dev/ui/arkts-layout-development-create-grid.md b/zh-cn/application-dev/ui/arkts-layout-development-create-grid.md index 7d7f3427d3c3b4c6fd48c6de6c4e770194f0cbe1..c51b226e3f99c41b5cef2c14db6341893f273114 100644 --- a/zh-cn/application-dev/ui/arkts-layout-development-create-grid.md +++ b/zh-cn/application-dev/ui/arkts-layout-development-create-grid.md @@ -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) diff --git a/zh-cn/application-dev/ui/arkts-layout-development-media-query.md b/zh-cn/application-dev/ui/arkts-layout-development-media-query.md index 680ded8849daa5939040682e91691c2e91e0c93e..c7887abe8e8f3cffebbdafcebda1cd32fe8b4e14 100644 --- a/zh-cn/application-dev/ui/arkts-layout-development-media-query.md +++ b/zh-cn/application-dev/ui/arkts-layout-development-media-query.md @@ -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) diff --git a/zh-cn/application-dev/ui/arkts-layout-development-overview.md b/zh-cn/application-dev/ui/arkts-layout-development-overview.md index 71cc023c671501a99cdb79ac04c00b2ae44210ca..748d2cf434c5487a74180635fd4980a9e989b4e0 100644 --- a/zh-cn/application-dev/ui/arkts-layout-development-overview.md +++ b/zh-cn/application-dev/ui/arkts-layout-development-overview.md @@ -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) - [常用组件与布局(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/ArkTSComponents) \ No newline at end of file diff --git a/zh-cn/application-dev/ui/arkts-routing.md b/zh-cn/application-dev/ui/arkts-routing.md index 30a499b7fa6e69f7bcef7b58d839a8918c9cd09e..48890b0fc3f61f5f6ac92b9b292aa1b5ae806345 100644 --- a/zh-cn/application-dev/ui/arkts-routing.md +++ b/zh-cn/application-dev/ui/arkts-routing.md @@ -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 diff --git a/zh-cn/application-dev/ui/arkts-ui-development-overview.md b/zh-cn/application-dev/ui/arkts-ui-development-overview.md index 0246efd070d1e8086d56ba2c07279f343e02dcc6..2241dccd638978548f022f919f09f8109c0e1651 100644 --- a/zh-cn/application-dev/ui/arkts-ui-development-overview.md +++ b/zh-cn/application-dev/ui/arkts-ui-development-overview.md @@ -92,7 +92,7 @@ 基于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) diff --git a/zh-cn/application-dev/ui/ui-js-building-ui-component.md b/zh-cn/application-dev/ui/ui-js-building-ui-component.md index a81dccf88e65b1728f491bdc21e27aed71727f8c..79ee15470ed97e0f96adcb90a5d3ba04595c2c80 100755 --- a/zh-cn/application-dev/ui/ui-js-building-ui-component.md +++ b/zh-cn/application-dev/ui/ui-js-building-ui-component.md @@ -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) diff --git a/zh-cn/application-dev/ui/ui-js-components-canvas.md b/zh-cn/application-dev/ui/ui-js-components-canvas.md index f3dfef764b3cca6716fb2863c97ba720762f91b4..3d04d9763ac62f8372ad4dfd2f81b0629e1974c1 100644 --- a/zh-cn/application-dev/ui/ui-js-components-canvas.md +++ b/zh-cn/application-dev/ui/ui-js-components-canvas.md @@ -146,7 +146,7 @@ export default { 针对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) diff --git a/zh-cn/application-dev/ui/ui-js-components-slider.md b/zh-cn/application-dev/ui/ui-js-components-slider.md index 5f23f4dd01e1259d194e1c9e4e424f60d1cc71d7..2f67c96c10d86214af71df708b7434c4211f4132 100644 --- a/zh-cn/application-dev/ui/ui-js-components-slider.md +++ b/zh-cn/application-dev/ui/ui-js-components-slider.md @@ -217,7 +217,7 @@ export default{ 针对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) diff --git a/zh-cn/application-dev/ui/ui-js-components-swiper.md b/zh-cn/application-dev/ui/ui-js-components-swiper.md index 6cd5fbbc1bc375bfd0a49b2e857b9764a783683e..a69a1f56a16c9a1771b2147f10d54dfbba5cddb6 100644 --- a/zh-cn/application-dev/ui/ui-js-components-swiper.md +++ b/zh-cn/application-dev/ui/ui-js-components-swiper.md @@ -370,6 +370,6 @@ export default { 针对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) diff --git a/zh-cn/application-dev/ui/ui-js-overview.md b/zh-cn/application-dev/ui/ui-js-overview.md index 3cd71a6f6555772a3df1c68ab971525cded8d02e..450c6ee476f48fab804f6bea5a0420d4adea50b0 100755 --- a/zh-cn/application-dev/ui/ui-js-overview.md +++ b/zh-cn/application-dev/ui/ui-js-overview.md @@ -28,11 +28,3 @@ - **Porting Layer** 适配层主要完成对平台层进行抽象,提供抽象接口,可以对接到系统平台。比如:事件对接、渲染管线对接和系统生命周期对接等。 - - -## 相关实例 - -兼容JS的类Web开发范式的方舟开发框架,有以下相关实例可供参考: - -- [`JsComponentCollection`:JS组件集合(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection) - diff --git a/zh-cn/application-dev/web/web-in-app-frontend-page-function-invoking.md b/zh-cn/application-dev/web/web-in-app-frontend-page-function-invoking.md index 2a490281b417a51f408e09acf18b3e62c66a917e..a013ac3f5121a3a14dca5fb493c9fa2083e0519d 100644 --- a/zh-cn/application-dev/web/web-in-app-frontend-page-function-invoking.md +++ b/zh-cn/application-dev/web/web-in-app-frontend-page-function-invoking.md @@ -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 diff --git a/zh-cn/application-dev/web/web-page-loading-with-web-components.md b/zh-cn/application-dev/web/web-page-loading-with-web-components.md index 98a7ea1360330dd20be8fcfc3afe6e3f9de01922..46a1f5693b089de51201bd5457b4a8488698aedb 100644 --- a/zh-cn/application-dev/web/web-page-loading-with-web-components.md +++ b/zh-cn/application-dev/web/web-page-loading-with-web-components.md @@ -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 diff --git a/zh-cn/application-dev/windowmanager/application-window-stage.md b/zh-cn/application-dev/windowmanager/application-window-stage.md index 7002f628b892d5206ffcdc3d6538a4fde585ad51..8ede8ff45583213169a0d3d740938de00790788b 100644 --- a/zh-cn/application-dev/windowmanager/application-window-stage.md +++ b/zh-cn/application-dev/windowmanager/application-window-stage.md @@ -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) -- [`WindowManage`:窗口管理(ArkTS)(API9)](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/WindowManage) + +- [窗口(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/WindowManagement/WindowRatio) \ No newline at end of file diff --git a/zh-cn/device-dev/porting/porting-smallchip-driver-oom.md b/zh-cn/device-dev/porting/porting-smallchip-driver-oom.md index 2c7e246f02abd06bc5137cfa4e244f64a6ec136d..f79d43e6da68b7436ab2c52395aa2b3e155f4c42 100644 --- a/zh-cn/device-dev/porting/porting-smallchip-driver-oom.md +++ b/zh-cn/device-dev/porting/porting-smallchip-driver-oom.md @@ -8,9 +8,10 @@ 移植LCD驱动的主要工作是编写一个驱动,在驱动中生成模型的实例,并完成注册。 -这些LCD的驱动被放置在源码目录//drivers/hdf_core/framework/model/display/driver/panel中。 +这些LCD的驱动被放置在源码目录`//drivers/hdf_core/framework/model/display/driver/panel`中。 1. 创建Panel驱动 + 创建HDF驱动,在驱动初始化中调用RegisterPanel接口注册模型实例。如: @@ -36,7 +37,8 @@ ``` 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) **注意:** > moduleName 要与panel驱动中的moduleName相同。 @@ -61,12 +63,13 @@ ## 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)。 1. 创建触摸屏器件驱动 - 在上述touchscreen目录中创建名为touch_ic_name.c的文件。编写如下内容 + + 在上述touchscreen目录中创建名为`touch_ic_name.c`的文件。编写如下内容 ``` @@ -103,21 +106,22 @@ | int32_t (\*UpdateFirmware)(ChipDevice \*device) | 实现固件升级 | 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) **说明:** > moduleName 要与触摸屏驱动中的moduleName相同。 ``` - deviceN :: deviceNode { - policy = 0; - priority = 130; - preload = 0; - permission = 0660; - moduleName = "HDF_TOUCH_XXXX"; - deviceMatchAttr = "touch_XXXX_configs"; - } + deviceN :: deviceNode { + policy = 0; + priority = 130; + preload = 0; + permission = 0660; + moduleName = "HDF_TOUCH_XXXX"; + deviceMatchAttr = "touch_XXXX_configs"; + } ``` @@ -126,6 +130,7 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负责处理WLAN流量。 **图1** OpenHarmony WLAN结构示意图 + ![zh-cn_image_0000001207756867](figures/zh-cn_image_0000001207756867.png) 如图1,左半部分负责管理WLAN设备,右半部分负责WLAN流量。HDF WLAN分别为这两部分做了抽象,驱动的移植过程可以看做分别实现这两部分所需接口。这些接口有: @@ -141,8 +146,9 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负 具体的移植步骤如下: -1. 创建HDF WLAN 芯片驱动 - 在目录/device/vendor_name/peripheral/wifi/chip_name/ 创建文件 hdf_wlan_chip_name.c。内容模板如下: +1. 创建HDF WLAN芯片驱动 + + 在目录`/device/vendor_name/peripheral/wifi/chip_name/`创建文件`hdf_wlan_chip_name.c`。内容模板如下: ``` @@ -166,7 +172,7 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负 HDF_INIT(g_hdfXXXChipEntry); ``` - 在上述代码的CreateChipDriverFactory方法中,需要创建一个HdfChipDriverFactory类型的对象。该对象提供如下方法 + 在上述代码的CreateChipDriverFactory方法中,需要创建一个HdfChipDriverFactory类型的对象。该对象提供如下方法: | 接口 | 说明 | | -------- | -------- | @@ -178,7 +184,7 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负 | void (\*Release)(struct HdfChipDriver \*chipDriver) | 释放chipDriver | | uint8_t (\*GetMaxIFCount)(struct HdfChipDriverFactory \*factory) | 获取当前芯片支持的最大接口数 | - 其中Build方法负责创建一个管理指定网络接口的对象HdfChipDriver 。该对象需要提供方法: + 其中Build方法负责创建一个管理指定网络接口的对象HdfChipDriver。该对象需要提供方法: | 接口 | 说明 | | -------- | -------- | @@ -189,7 +195,8 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负 | struct HdfMac80211APOps \*apOps | 支持AP模式所需要的接口集 | 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设备,另一个部分负 ``` > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** - > 路径和文件中的vendor_name、product_name、chip_name请替换成实际名称 + > + > 路径和文件中的vendor_name、product_name、chip_name请替换成实际名称。 > > vendorId 和 deviceId需要根据实际芯片的识别码进行填写。 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 { - policy = 0; - preload = 2; - moduleName = "HDF_WLAN_CHIPS"; - deviceMatchAttr = "hdf_wlan_chips_chip_name"; - serviceName = "driverName"; - } + deviceN :: deviceNode { + policy = 0; + preload = 2; + moduleName = "HDF_WLAN_CHIPS"; + deviceMatchAttr = "hdf_wlan_chips_chip_name"; + serviceName = "driverName"; + } ``` > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** > moduleName 要与HDF WLAN 芯片驱动中的moduleName相同。 4. 修改Kconfig文件,让移植的WLAN模组出现再内核配置中 - 在device/vendor_name/drivers/Kconfig中增加配置菜单,模板如下 + + 在`device/vendor_name/drivers/Kconfig`中增加配置菜单,模板如下 ``` @@ -246,10 +256,11 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负 ``` > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** - > 请替换模板中的chip_name为实际的芯片名称 + > 请替换模板中的chip_name为实际的芯片名称。 5. 修改构建脚本,让驱动参与内核构建 - 在源码文件//device/vendor_name/drivers/lite.mk末尾追加如下内容 + + 在源码文件`//device/vendor_name/drivers/lite.mk`末尾追加如下内容。 ``` @@ -262,4 +273,4 @@ WLAN驱动分为两部分,一部分负责管理WLAN设备,另一个部分负 ``` > ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** - > 请替换模板中的chip_name为实际的芯片名称 + > 请替换模板中的chip_name为实际的芯片名称。 diff --git a/zh-cn/device-dev/porting/porting-smallchip-kernel-linux.md b/zh-cn/device-dev/porting/porting-smallchip-kernel-linux.md index 2b19663ca9314d684662e40ed273229aa72da186..c64e9e4eff3a918ea445f42cda16ad30e335eb9a 100644 --- a/zh-cn/device-dev/porting/porting-smallchip-kernel-linux.md +++ b/zh-cn/device-dev/porting/porting-smallchip-kernel-linux.md @@ -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 @@ -19,17 +19,20 @@ Linux内核移植主要涉及基于linux内核基线合入三方芯片补丁后 ## 适配编译和烧录启动 1. 准备内核config(特别是芯片相关的config)。 - config文件所在源码目录:kernel/linux/config/ - 以hi3516dv300芯片为例,可在对应的linux-4.19/arch/arm/configs/目录下新建<YOUR_CHIP>_small_defconfig,如hi3516dv300_small_defconfig表示针对hi3516dv300小型系统的defconfig。该config文件可以由基础defconfig文件small_common_defconfig与该芯片相关的config组合生成。 + config文件所在源码目录:`kernel/linux/config/` + + 以hi3516dv300芯片为例,可在对应的`linux-4.19/arch/arm/configs/`目录下新建<YOUR_CHIP>_small_defconfig,如`hi3516dv300_small_defconfig`表示针对hi3516dv300小型系统的defconfig。该config文件可以由基础defconfig文件`small_common_defconfig`与该芯片相关的config组合生成。 2. 准备芯片补丁。 - 补丁文件所在源码目录:kernel/linux/patches/linux-4.19 + + 补丁文件所在源码目录:`kernel/linux/patches/linux-4.19` 以hi3516dv300芯片为例,参考已有的patch目录hi3516dv300_small_patch目录,新建<YOUR_CHIP>_patch目录,放置相关芯片补丁,注意hdf.patch等驱动补丁。 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内核基线合入三方芯片补丁后 (2)编译失败,内核版本差异(函数实现调整等)需要针对性进行内核适配。 > ![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/<\*\*\*>/kernel/linux-4.19,可以在该目录下进行补丁的修改适配。 + > - 对应拷贝后的目录位于:`out/<***>/kernel/linux-4.19`,可以在该目录下进行补丁的修改适配。 4. 烧录启动。 + 由于不同芯片的开发板的烧录方式不一样,此处不表述具体的烧录方式。需要注意烧录的各镜像的大小及启动参数的配置,参考hi3516dv300采用uboot启动参数: @@ -56,43 +60,56 @@ Linux内核移植主要涉及基于linux内核基线合入三方芯片补丁后 调试init进程、启动shell和运行简单的用户态程序,验证内核移植是否成功。OpenHarmony小型系统的OS镜像结构以及linux用户态的启动流程如下图1所示: **图1** 基于linux内核的OS镜像结构和用户态程序启动流程 + ![zh-cn_image_0000001154372318](figures/zh-cn_image_0000001154372318.png) 基于上述流程,推荐按以下步骤完成验证: 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 -> mksh“和“/lib/ld-musl-arm.so.1 -> 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文件生成是否符合预期。 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程序启动正常: **图2** init启动正常日志 + ![zh-cn_image_0000001154212516](figures/zh-cn_image_0000001154212516.png) 正常进入shell后执行ls命令,串口打印信息如下图: **图3** 正常进入shell后输入ls命令串口打印 + ![zh-cn_image_0000001200171991](figures/zh-cn_image_0000001200171991.png) 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 diff --git a/zh-cn/device-dev/porting/porting-smallchip-prepare-building.md b/zh-cn/device-dev/porting/porting-smallchip-prepare-building.md index 3f2930abbdb933d16d32022117ab4986c9e961ca..2cb0437484d41d372caf08c437a5db7f6919d058 100644 --- a/zh-cn/device-dev/porting/porting-smallchip-prepare-building.md +++ b/zh-cn/device-dev/porting/porting-smallchip-prepare-building.md @@ -20,7 +20,8 @@ sudo apt-get install gcc-arm-linux-gnueabi 了解编译框架和搭建完编译环境后,请参考如下步骤新建芯片解决方案: 1. 新建目录 - 芯片解决方案的目录规则为:device/{芯片解决方案厂商}/{开发板}。以海思的hispark_taurus开发板为例,在代码根目录执行如下命令建立目录: + + 芯片解决方案的目录规则为:`device/{芯片解决方案厂商}/{开发板}`。以海思的hispark_taurus开发板为例,在代码根目录执行如下命令建立目录: ``` @@ -59,7 +60,8 @@ sudo apt-get install gcc-arm-linux-gnueabi 目录树建立后开发板相关的源码放到hispark_taurus目录下。 2. 配置开发板编译选项 - 步骤1中的config.gni可配置开发板相关的编译选项,编译构建框架将会遵照该配置文件中的参数编译所有用户态OS组件。其中关键的字段说明如下: + + 步骤1中的`config.gni`可配置开发板相关的编译选项,编译构建框架将会遵照该配置文件中的参数编译所有用户态OS组件。其中关键的字段说明如下: ``` @@ -75,7 +77,7 @@ sudo apt-get install gcc-arm-linux-gnueabi 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". @@ -121,9 +123,10 @@ sudo apt-get install gcc-arm-linux-gnueabi ``` 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 ``` 4. 编译调试 - 在开发板目录下执行hb set和hb build即可启动芯片解决方案的编译,编译框架会以开发板下的BUILD.gn为入口启动编译。 + + 在开发板目录下执行`hb set`和`hb build`即可启动芯片解决方案的编译,编译框架会以开发板下的`BUILD.gn`为入口启动编译。 diff --git a/zh-cn/device-dev/porting/standard-system-porting-guide.md b/zh-cn/device-dev/porting/standard-system-porting-guide.md index a9ffb4db04f67dbb3e572a68210a3d17c1ce43b8..72db49201ee862d04e4dee379d1e5424bfff4c9f 100644 --- a/zh-cn/device-dev/porting/standard-system-porting-guide.md +++ b/zh-cn/device-dev/porting/standard-system-porting-guide.md @@ -11,7 +11,7 @@ ### 定义产品 -在“//vendor/MyProductVendor/{product_name}名称的目录下创建一个config.json文件,该文件用于描述产品所使用的SOC 以及所需的子系统。配置如下: +在`//vendor/MyProductVendor/{product_name}`名称的目录下创建一个config.json文件,该文件用于描述产品所使用的SOC 以及所需的子系统。配置如下: //vendor/MyProductVendor/MyProduct/config.json @@ -41,29 +41,20 @@ ``` 主要的配置内容 -product_name:产品名称 必填 - -version:版本 必填 - -type:配置的系统级别,包含(small,standard …) 必填 - -target_cpu :设备的CPU类型(根据实际情况,这里的target_cpu也可能是arm64 、riscv、 x86等。) 必填 - -ohos_version:操作系统版本 选填 - -device_company:device厂商名 必填 - -board:开发板名称 必填 - -enable_ramdisk:是否启动ramdisk 必填 - -kernel_type 选填 - -kernel_version 选填 kernel_type与 kernel_version在 standard 是固定的不需要写。 - -subsystems:系统需要启用的子系统。子系统可以简单理解为一块独立构建的功能块。必填 - -product_company:不体现在配置中,而是目录名,vendor下一级目录就是product_company,BUILD.gn脚本依然可以访问。 +| 配置项 | 说明 | +|-------|----------| +|product_name |(必填)产品名称| +|version|(必填)版本 | +|type|(必填)配置的系统级别,包含(small、standard等) | +|target_cpu |(必填)设备的CPU类型(根据实际情况,这里的target_cpu也可能是arm64 、riscv、 x86等)| +|ohos_version|(选填)操作系统版本| +|device_company|(必填)device厂商名| +|board|(必填)开发板名称| +|enable_ramdisk|(必填)是否启动ramdisk| +|kernel_type|(选填)内核类型| +|kernel_version|(选填)kernel_type与kernel_version在standard是固定的不需要写| +|subsystems|(必填)系统需要启用的子系统。子系统可以简单理解为一块独立构建的功能块。| +|product_company|不体现在配置中,而是目录名,vendor下一级目录就是product_company,BUILD.gn脚本依然可以访问。| 已定义的子系统可以在“//build/subsystem_config.json”中找到。当然你也可以定制子系统。 @@ -79,7 +70,7 @@ product_company:不体现在配置中,而是目录名,vendor下一级目 ./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下一级目 ### 为SOC添加内核构建的子系统 -修改文件 //build/subsystem_config.json增加一个子系统. 配置如下: +修改文件`//build/subsystem_config.json`增加一个子系统。配置如下: ``` @@ -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`。这一节会在这个目录创建构建脚本,告诉构建系统如何构建内核。 -建议的目录结构 +建议的目录结构: ``` @@ -126,9 +117,8 @@ BUILD.gn是subsystem构建的唯一入口。 期望的构建结果 - | | | -| -------- | -------- | | 文件 | 文件说明 | +| -------- | -------- | | $root_build_dir/packages/phone/images/uImage | 内核镜像 | | $root_build_dir/packages/phone/images/uboot | bootloader镜像 | @@ -156,11 +146,11 @@ BUILD.gn是subsystem构建的唯一入口。 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)。 @@ -172,115 +162,117 @@ BUILD.gn是subsystem构建的唯一入口。 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) -{ - struct PanelData *panel = CreateYourPanel(); - - // 注册 - if (RegisterPanel(panel) != HDF_SUCCESS) { - HDF_LOGE("%s: RegisterPanel failed", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} + ``` + int32_t XXXInit(struct HdfDeviceObject *object) + { + struct PanelData *panel = CreateYourPanel(); -struct HdfDriverEntry g_xxxxDevEntry = { - .moduleVersion = 1, - .moduleName = "LCD_XXXX", - .Init = XXXInit, -}; + // 注册 + if (RegisterPanel(panel) != HDF_SUCCESS) { + HDF_LOGE("%s: RegisterPanel failed", __func__); + 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); + ``` -``` -root { - ... - display :: host { - device_lcd :: device { - deviceN :: deviceNode { - policy = 0; - priority = 100; - preload = 2; - moduleName = "LCD_XXXX"; - } - } - } -} -``` +2. 配置加载panel驱动产品的所有设备信息被定义在文件`//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs`中。修改该文件,在display的host中,名为device_lcd的device中增加配置。 + + 注意:moduleName要与panel驱动中的moduleName相同。 + + ``` + root { + ... + display :: host { + device_lcd :: device { + 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) -{ - ChipDevice *tpImpl = CreateXXXXTpImpl(); - if(RegisterChipDevice(tpImpl) != HDF_SUCCESS) { - ReleaseXXXXTpImpl(tpImpl); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} + static int32_t HdfXXXXChipInit(struct HdfDeviceObject *device) + { + ChipDevice *tpImpl = CreateXXXXTpImpl(); + if(RegisterChipDevice(tpImpl) != HDF_SUCCESS) { + ReleaseXXXXTpImpl(tpImpl); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } -struct HdfDriverEntry g_touchXXXXChipEntry = { - .moduleVersion = 1, - .moduleName = "HDF_TOUCH_XXXX", - .Init = HdfXXXXChipInit, -}; + struct HdfDriverEntry g_touchXXXXChipEntry = { + .moduleVersion = 1, + .moduleName = "HDF_TOUCH_XXXX", + .Init = HdfXXXXChipInit, + }; -HDF_INIT(g_touchXXXXChipEntry); -``` + HDF_INIT(g_touchXXXXChipEntry); + ``` -其中ChipDevice中要提供若干方法。 + 其中ChipDevice中要提供若干方法。 - | | | -| -------- | -------- | -| 方法 | 实现说明 | -| int32_t (\*Init)(ChipDevice \*device) | 器件初始化 | -| int32_t (\*Detect)(ChipDevice \*device) | 器件探测 | -| int32_t (\*Suspend)(ChipDevice \*device) | 器件休眠 | -| int32_t (\*Resume)(ChipDevice \*device) | 器件唤醒 | -| int32_t (\*DataHandle)(ChipDevice \*device) | 从器件读取数据,将触摸点数据填写入device->driver->frameData中 | -| int32_t (\*UpdateFirmware)(ChipDevice \*device) | 固件升级 | + | 方法 | 实现说明 | + | -------- | -------- | + | int32_t (\*Init)(ChipDevice \*device) | 器件初始化 | + | int32_t (\*Detect)(ChipDevice \*device) | 器件探测 | + | int32_t (\*Suspend)(ChipDevice \*device) | 器件休眠 | + | int32_t (\*Resume)(ChipDevice \*device) | 器件唤醒 | + | int32_t (\*DataHandle)(ChipDevice \*device) | 从器件读取数据,将触摸点数据填写入device->driver->frameData中 | + | int32_t (\*UpdateFirmware)(ChipDevice \*device) | 固件升级 | -- 配置产品,加载器件驱动 - 产品的所有设备信息被定义在文件//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs中。修改该文件,在名为input的host中,名为device_touch_chip的device中增加配置。注意:moduleName 要与触摸屏驱动中的moduleName相同。 +2. 配置产品,加载器件驱动 + + 产品的所有设备信息被定义在文件`//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs`中。修改该文件,在名为input的host中,名为device_touch_chip的device中增加配置。注意:moduleName 要与触摸屏驱动中的moduleName相同。 -``` - deviceN :: deviceNode { - policy = 0; - priority = 130; - preload = 0; - permission = 0660; - moduleName = "HDF_TOUCH_XXXX"; - deviceMatchAttr = "touch_XXXX_configs"; - } -``` + ``` + deviceN :: deviceNode { + policy = 0; + priority = 130; + preload = 0; + permission = 0660; + moduleName = "HDF_TOUCH_XXXX"; + deviceMatchAttr = "touch_XXXX_configs"; + } + ``` -更详细的驱动开发指导,请参考 [TOUCHSCREEN](../driver/driver-peripherals-touch-des.md)。 + 更详细的驱动开发指导,请参考[TOUCHSCREEN](../driver/driver-peripherals-touch-des.md)。 ### WLAN @@ -293,135 +285,134 @@ Wi-Fi驱动分为两部分,一部分负责管理WLAN设备,另一个部分 支持一款芯片的主要工作是实现一个ChipDriver驱动。实现HDF_WLAN_CORE和NetDevice提供的接口。主要需要实现的接口有: -| | | | -| -------- | -------- | -------- | | 接口 | 定义头文件 | 说明 | +| -------- | -------- | -------- | | 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端口 | | NetDeviceInterFace | //drivers/hdf_core/framework/include/net/net_device.h | 与协议栈之间的接口,如发送数据、设置网络接口状态等 | 建议适配按如下步骤操作: -1.创建HDF驱动建议将代码放置在//device/MySoCVendor/peripheral/wifi/chip_name/,文件模板如下: - - -``` -static int32_t HdfWlanXXXChipDriverInit(struct HdfDeviceObject *device) { - static struct HdfChipDriverFactory factory = CreateChipDriverFactory(); - struct HdfChipDriverManager *driverMgr = HdfWlanGetChipDriverMgr(); - if (driverMgr->RegChipDriver(&factory) != HDF_SUCCESS) { - HDF_LOGE("%s fail: driverMgr is NULL!", __func__); - return HDF_FAILURE; - } - return HDF_SUCCESS; -} - -struct HdfDriverEntry g_hdfXXXChipEntry = { - .moduleVersion = 1, - .Init = HdfWlanXXXChipDriverInit, - .Release = HdfWlanXXXChipRelease, - .moduleName = "HDF_WIFI_CHIP_XXX" -}; - -HDF_INIT(g_hdfXXXChipEntry); -``` - -在CreateChipDriverFactory中,需要创建一个HdfChipDriverFactory,接口如下: - - | | | -| -------- | -------- | -| 接口 | 说明 | -| const char \*driverName | 当前driverName | -| int32_t (\*InitChip)(struct HdfWlanDevice \*device) | 初始化芯片 | -| int32_t (\*DeinitChip)(struct HdfWlanDevice \*device) | 去初始化芯片 | -| void (_ReleaseFactory)(struct HdfChipDriverFactory _factory) | 释放HdfChipDriverFactory对象 | -| struct HdfChipDriver _(_Build)(struct HdfWlanDevice \*device, uint8_t ifIndex) | 创建一个HdfChipDriver;输入参数中,device是设备信息,ifIndex是当前创建的接口在这个芯片中的序号 | -| void (_Release)(struct HdfChipDriver _chipDriver) | 释放chipDriver | -| uint8_t (\*GetMaxIFCount)(struct HdfChipDriverFactory \*factory) | 获取当前芯片支持的最大接口数 | - -HdfChipDriver需要实现的接口有 - - | | | -| -------- | -------- | -| 接口 | 说明 | -| int32_t (\*init)(struct HdfChipDriver \*chipDriver, NetDevice \*netDev) | 初始化当前网络接口,这里需要向netDev提供接口NetDeviceInterFace | -| int32_t (\*deinit)(struct HdfChipDriver \*chipDriver, NetDevice \*netDev) | 去初始化当前网络接口 | -| struct HdfMac80211BaseOps \*ops | WLAN基础能力接口集 | -| struct HdfMac80211STAOps \*staOps | 支持STA模式所需的接口集 | -| struct HdfMac80211APOps \*apOps | 支持AP模式所需要的接口集 | - -2.编写配置文件,描述驱动支持的设备 - -在产品配置目录下创建芯片的配置文件//vendor/MyProductVendor/MyProduct/config/wifi/wlan_chip_chip_name.hcs。 - -注意: 路径中的vendor_name、product_name、chip_name请替换成实际名称。 - -模板如下: - - -``` -root { - wlan_config { - chip_name :& chipList { - chip_name :: chipInst { - match_attr = "hdf_wlan_chips_chip_name"; /* 这是配置匹配属性,用于提供驱动的配置根 */ - driverName = "driverName"; /* 需要与HdfChipDriverFactory中的driverName相同*/ - sdio { - vendorId = 0x0296; - deviceId = [0x5347]; - } - } - } - } -} -``` - -3.编写配置文件,加载驱动 - -产品的所有设备信息被定义在文件//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs中。修改该文件,在名为network的host中,名为device_wlan_chips的device中增加配置。注意:moduleName 要与触摸屏驱动中的moduleName相同。 - - -``` - deviceN :: deviceNode { - policy = 0; - preload = 2; - moduleName = "HDF_WLAN_CHIPS"; - deviceMatchAttr = "hdf_wlan_chips_chip_name"; - serviceName = "driverName"; - } -``` - -4.构建驱动 - -- 创建内核菜单在//device/MySoCVendor/peripheral目录中创建Kconfig文件,内容模板如下: - +1. 创建HDF驱动建议将代码放置在`//device/MySoCVendor/peripheral/wifi/chip_name/`,文件模板如下: + + + ``` + static int32_t HdfWlanXXXChipDriverInit(struct HdfDeviceObject *device) { + static struct HdfChipDriverFactory factory = CreateChipDriverFactory(); + struct HdfChipDriverManager *driverMgr = HdfWlanGetChipDriverMgr(); + if (driverMgr->RegChipDriver(&factory) != HDF_SUCCESS) { + HDF_LOGE("%s fail: driverMgr is NULL!", __func__); + return HDF_FAILURE; + } + return HDF_SUCCESS; + } + + struct HdfDriverEntry g_hdfXXXChipEntry = { + .moduleVersion = 1, + .Init = HdfWlanXXXChipDriverInit, + .Release = HdfWlanXXXChipRelease, + .moduleName = "HDF_WIFI_CHIP_XXX" + }; + + HDF_INIT(g_hdfXXXChipEntry); + ``` + + 在CreateChipDriverFactory中,需要创建一个HdfChipDriverFactory,接口如下: + + + + | 接口 | 说明 | + | -------- | -------- | + | const char \*driverName | 当前driverName | + | int32_t (\*InitChip)(struct HdfWlanDevice \*device) | 初始化芯片 | + | int32_t (\*DeinitChip)(struct HdfWlanDevice \*device) | 去初始化芯片 | + | void (_ReleaseFactory)(struct HdfChipDriverFactory _factory) | 释放HdfChipDriverFactory对象 | + | struct HdfChipDriver _(_Build)(struct HdfWlanDevice \*device, uint8_t ifIndex) | 创建一个HdfChipDriver;输入参数中,device是设备信息,ifIndex是当前创建的接口在这个芯片中的序号 | + | void (_Release)(struct HdfChipDriver _chipDriver) | 释放chipDriver | + | uint8_t (\*GetMaxIFCount)(struct HdfChipDriverFactory \*factory) | 获取当前芯片支持的最大接口数 | + + HdfChipDriver需要实现的接口有: + + | 接口 | 说明 | + | -------- | -------- | + | int32_t (\*init)(struct HdfChipDriver \*chipDriver, NetDevice \*netDev) | 初始化当前网络接口,这里需要向netDev提供接口NetDeviceInterFace | + | int32_t (\*deinit)(struct HdfChipDriver \*chipDriver, NetDevice \*netDev) | 去初始化当前网络接口 | + | struct HdfMac80211BaseOps \*ops | WLAN基础能力接口集 | + | struct HdfMac80211STAOps \*staOps | 支持STA模式所需的接口集 | + | struct HdfMac80211APOps \*apOps | 支持AP模式所需要的接口集 | + +2. 编写配置文件,描述驱动支持的设备。 + + 在产品配置目录下创建芯片的配置文件`//vendor/MyProductVendor/MyProduct/config/wifi/wlan_chip_chip_name.hcs`。 + + 注意: 路径中的vendor_name、product_name、chip_name请替换成实际名称。 + + 模板如下: + + ``` + root { + wlan_config { + chip_name :& chipList { + chip_name :: chipInst { + match_attr = "hdf_wlan_chips_chip_name"; /* 这是配置匹配属性,用于提供驱动的配置根 */ + driverName = "driverName"; /* 需要与HdfChipDriverFactory中的driverName相同*/ + sdio { + vendorId = 0x0296; + deviceId = [0x5347]; + } + } + } + } + } + ``` + +3. 编写配置文件,加载驱动。 + + 产品的所有设备信息被定义在文件`//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs`中。修改该文件,在名为network的host中,名为device_wlan_chips的device中增加配置。 + + 注意:moduleName 要与触摸屏驱动中的moduleName相同。 + + ``` + deviceN :: deviceNode { + policy = 0; + preload = 2; + moduleName = "HDF_WLAN_CHIPS"; + deviceMatchAttr = "hdf_wlan_chips_chip_name"; + serviceName = "driverName"; + } + ``` + +4. 构建驱动 + + - 创建内核菜单在`//device/MySoCVendor/peripheral`目录中创建Kconfig文件,内容模板如下: -``` -config DRIVERS_WLAN_XXX - bool "Enable XXX WLAN Host driver" - default n - depends on DRIVERS_HDF_WIFI - help - Answer Y to enable XXX Host driver. Support chip xxx -``` + ``` + config DRIVERS_WLAN_XXX + bool "Enable XXX WLAN Host driver" + default n + depends on DRIVERS_HDF_WIFI + help + 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 -obj-$(CONFIG_DRIVERS_WLAN_XXX) += $(HDF_DEVICE_ROOT)/MySoCVendor/peripheral/build/standard/ -``` + ``` + HDF_DEVICE_ROOT := $(HDF_DIR_PREFIX)/../device + 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)。 ### 开发移植示例 diff --git a/zh-cn/release-notes/changelogs/OpenHarmony_4.0.10.1/changelog-ArkUI.md b/zh-cn/release-notes/changelogs/OpenHarmony_4.0.10.1/changelog-ArkUI.md new file mode 100644 index 0000000000000000000000000000000000000000..0fdc45cc5433250d9478b120d76969595e1ca577 --- /dev/null +++ b/zh-cn/release-notes/changelogs/OpenHarmony_4.0.10.1/changelog-ArkUI.md @@ -0,0 +1,375 @@ +# 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 = [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 = [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 = [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 + }) + } + } +} +``` diff --git a/zh-cn/release-notes/changelogs/OpenHarmony_4.0.10.3/changelogs-uiappearance.md b/zh-cn/release-notes/changelogs/OpenHarmony_4.0.10.3/changelogs-uiappearance.md new file mode 100644 index 0000000000000000000000000000000000000000..b9c337cb6255f89ac47d274ac7d71932b4c4ec42 --- /dev/null +++ b/zh-cn/release-notes/changelogs/OpenHarmony_4.0.10.3/changelogs-uiappearance.md @@ -0,0 +1,23 @@ +# 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参考。 diff --git a/zh-cn/release-notes/changelogs/OpenHarmony_4.0.9.5/changelogs-arkui.md b/zh-cn/release-notes/changelogs/OpenHarmony_4.0.9.5/changelogs-arkui.md index 793df76331639f4642d758edc75f30e6a3c99135..033db916826f6a21b81f93fa3e7ea526f5cd70cf 100644 --- a/zh-cn/release-notes/changelogs/OpenHarmony_4.0.9.5/changelogs-arkui.md +++ b/zh-cn/release-notes/changelogs/OpenHarmony_4.0.9.5/changelogs-arkui.md @@ -70,4 +70,59 @@ API Version 9: Free模式显示位置 API Version 10: Free模式显示位置与Full模式显示位置相同 -![Navigation](figures/navigation_title_mode_free_sdk10.png) \ No newline at end of file +![Navigation](figures/navigation_title_mode_free_sdk10.png) + +## 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 diff --git a/zh-cn/release-notes/changelogs/v4.0-beta2/changelogs-arkui.md b/zh-cn/release-notes/changelogs/v4.0-beta2/changelogs-arkui.md index 24e71533db08dc2aac909c0e8761a621b3bea33f..9793a0467c4be60aa92c3e80580c35835bc01889 100644 --- a/zh-cn/release-notes/changelogs/v4.0-beta2/changelogs-arkui.md +++ b/zh-cn/release-notes/changelogs/v4.0-beta2/changelogs-arkui.md @@ -76,3 +76,10 @@ API Version 10: Free模式显示位置与Full模式显示位置相同 **变更影响** 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 diff --git a/zh-cn/third-party-cases/Readme-CN.md b/zh-cn/third-party-cases/Readme-CN.md index 08e39e036dbbea1637eff05d97a44ed8649d9880..99ed832ca812f62074780f4b3e907d2a2caef77b 100644 --- a/zh-cn/third-party-cases/Readme-CN.md +++ b/zh-cn/third-party-cases/Readme-CN.md @@ -28,6 +28,8 @@ - [列表上拉加载更多内容](list-pullup-loading-data.md) - [如何删除多选框选项](delete-checkboxgroup-items.md) - [像素单位转换](pixel-format-transfer.md) +- [如何在UIAbility间进行跳转](jump-between-UIAbilities.md) +- [转场动画](transition-animation.md) ### 装饰器 - [控制页面刷新范围](overall-and-part-refresh.md) @@ -40,6 +42,7 @@ - [如何实现沉浸模式](immersion-mode.md) - [如何创建悬浮窗](float-window.md) - [保持屏幕常亮](keep-screen-on.md) +- [如何创建子窗口并与主窗口通信](subwindow-mainwindow-communication.md) ### 数据管理 - [用户首选项的基本使用](preferences-data-process.md) diff --git a/zh-cn/third-party-cases/figures/BottomTransition.gif b/zh-cn/third-party-cases/figures/BottomTransition.gif new file mode 100644 index 0000000000000000000000000000000000000000..e5b5abbe5c7206d251ba93e6853345bcaa4130ea Binary files /dev/null and b/zh-cn/third-party-cases/figures/BottomTransition.gif differ diff --git a/zh-cn/third-party-cases/figures/ComponentTransition.gif b/zh-cn/third-party-cases/figures/ComponentTransition.gif new file mode 100644 index 0000000000000000000000000000000000000000..22b99a5fc8c493af4631350b725562d5096d5d48 Binary files /dev/null and b/zh-cn/third-party-cases/figures/ComponentTransition.gif differ diff --git a/zh-cn/third-party-cases/figures/CustomTransition.gif b/zh-cn/third-party-cases/figures/CustomTransition.gif new file mode 100644 index 0000000000000000000000000000000000000000..4ef6fe89af78b41e09c927e2ac1f26f838b1d5a8 Binary files /dev/null and b/zh-cn/third-party-cases/figures/CustomTransition.gif differ diff --git a/zh-cn/third-party-cases/figures/FullCustomTransition.gif b/zh-cn/third-party-cases/figures/FullCustomTransition.gif new file mode 100644 index 0000000000000000000000000000000000000000..f6bce18e72ea355636438a0196d633b03e447bb9 Binary files /dev/null and b/zh-cn/third-party-cases/figures/FullCustomTransition.gif differ diff --git a/zh-cn/third-party-cases/figures/SharePage.gif b/zh-cn/third-party-cases/figures/SharePage.gif new file mode 100644 index 0000000000000000000000000000000000000000..98c886fe47f18f3553bca3b5abf7919bafbdb0ff Binary files /dev/null and b/zh-cn/third-party-cases/figures/SharePage.gif differ diff --git a/zh-cn/third-party-cases/figures/Transition-animation-tree.png b/zh-cn/third-party-cases/figures/Transition-animation-tree.png new file mode 100644 index 0000000000000000000000000000000000000000..e25c0b5b38e3384f7752465028c1402f7515f380 Binary files /dev/null and b/zh-cn/third-party-cases/figures/Transition-animation-tree.png differ diff --git a/zh-cn/third-party-cases/figures/UIAbility.gif b/zh-cn/third-party-cases/figures/UIAbility.gif new file mode 100644 index 0000000000000000000000000000000000000000..39478eb56793f0b1239d7d90a6e4570e0f6ef9a1 Binary files /dev/null and b/zh-cn/third-party-cases/figures/UIAbility.gif differ diff --git a/zh-cn/third-party-cases/figures/device-module.png b/zh-cn/third-party-cases/figures/device-module.png new file mode 100644 index 0000000000000000000000000000000000000000..dff2bce0c5533294f021598074424eca216b343d Binary files /dev/null and b/zh-cn/third-party-cases/figures/device-module.png differ diff --git a/zh-cn/third-party-cases/figures/subwindow-mainwindow-communication.gif b/zh-cn/third-party-cases/figures/subwindow-mainwindow-communication.gif new file mode 100644 index 0000000000000000000000000000000000000000..bfc9a607db95911482b7c52caa2294fca2c678f2 Binary files /dev/null and b/zh-cn/third-party-cases/figures/subwindow-mainwindow-communication.gif differ diff --git a/zh-cn/third-party-cases/jump-between-UIAbilities.md b/zh-cn/third-party-cases/jump-between-UIAbilities.md new file mode 100644 index 0000000000000000000000000000000000000000..b390a068787a81e95c3b3c054a81e7a204f21e56 --- /dev/null +++ b/zh-cn/third-party-cases/jump-between-UIAbilities.md @@ -0,0 +1,1038 @@ +# 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) diff --git a/zh-cn/third-party-cases/observed-and-objectlink.md b/zh-cn/third-party-cases/observed-and-objectlink.md index 1c7419c028ef305a2b98d976368ddf5c196d48a4..d062b057b208d3f2e330ae10616ad219497a81e9 100644 --- a/zh-cn/third-party-cases/observed-and-objectlink.md +++ b/zh-cn/third-party-cases/observed-and-objectlink.md @@ -16,7 +16,7 @@ 为便于理解,通过以下例子具体说明单层和多层状态变化: ```ts -class ClassA { +class ClassB { public c: number; constructor(c: number) { @@ -24,20 +24,20 @@ class ClassA { } } -class ClassB { - // ClassB成员变量的类型为ClassA,ClassA为被嵌套类 - public a: ClassA; +class ClassA { + // ClassA成员变量的类型为ClassB,ClassB为被嵌套类 + public b: ClassB; - constructor(a: ClassA) { - this.a = a; + constructor(b: ClassB) { + this.b = b; } } -b: ClassB -// 变量a为ClassB的成员变量,为第一层变量,所以变量a的状态变化即为第一层状态变化 -this.b.a = new ClassA(0) -// 变量c为被嵌套类ClassA的成员变量,变量c的状态变化即为第二层状态变化 -this.b.a.c = 5 +a: ClassA +// 变量b为ClassA的成员变量,为第一层变量,所以变量b的状态变化即为第一层状态变化 +this.a.b = new ClassB(0) +// 变量c为被嵌套类ClassB的成员变量,变量c的状态变化即为第二层状态变化 +this.a.b.c = 5 ``` ## 监听第一层状态变化 diff --git a/zh-cn/third-party-cases/preferences-data-process.md b/zh-cn/third-party-cases/preferences-data-process.md index 238b6f9f6d4445ad43adcbb3e018391f3fcf826d..c1e198bf86da6b571525f3b181e8fd51c263e172 100644 --- a/zh-cn/third-party-cases/preferences-data-process.md +++ b/zh-cn/third-party-cases/preferences-data-process.md @@ -128,6 +128,7 @@ }); }; } + export default new PreferenceModel(); ``` 2. UI中主要包含两大部分:文本和输入框,按钮。将这两部分分别抽取为子组件,在主页中进行调用。具体代码如下: 文本和输入框子组件: diff --git a/zh-cn/third-party-cases/subwindow-mainwindow-communication.md b/zh-cn/third-party-cases/subwindow-mainwindow-communication.md new file mode 100644 index 0000000000000000000000000000000000000000..f749de59314acc620eb97808c6b4a4be2bbb9576 --- /dev/null +++ b/zh-cn/third-party-cases/subwindow-mainwindow-communication.md @@ -0,0 +1,415 @@ +# 如何创建子窗口并与主窗口通信 + +## 场景介绍 +应用开发过程中,经常需要创建弹窗(子窗口)用来承载跟当前内容相关的业务,比如电话应用的拨号弹窗;阅读应用中长按当前内容触发的编辑弹窗;购物应用经常出现的抽奖活动弹窗等。 +本文为大家介绍如何创建子窗口并实现子窗口与主窗口的数据通信。 + +## 效果呈现 +本例最终效果如下: + +![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 diff --git a/zh-cn/third-party-cases/transition-animation.md b/zh-cn/third-party-cases/transition-animation.md new file mode 100644 index 0000000000000000000000000000000000000000..e69252a591e6d3ca58983673a70aebc5aadedc7b --- /dev/null +++ b/zh-cn/third-party-cases/transition-animation.md @@ -0,0 +1,959 @@ +# 转场动画的使用(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) + +