提交 05bce7c4 编写于 作者: X xsz233 提交者: Gitee

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

Signed-off-by: Nxsz233 <xushizhe@huawei.com>
...@@ -73,8 +73,8 @@ BackupExtensionAbility is a class derived from the [ExtensionAbility](../applica ...@@ -73,8 +73,8 @@ BackupExtensionAbility is a class derived from the [ExtensionAbility](../applica
"data/storage/el2/base/files/", "data/storage/el2/base/files/",
"data/storage/el2/base/preferences/", "data/storage/el2/base/preferences/",
"data/storage/el2/base/haps/*/database/", "data/storage/el2/base/haps/*/database/",
"data/storage/el2/base/haps/*/base/files/", "data/storage/el2/base/haps/*/files/",
"data/storage/el2/base/haps/*/base/preferences/", "data/storage/el2/base/haps/*/preferences/",
] ]
} }
``` ```
...@@ -42,7 +42,7 @@ let fetchOptions = { ...@@ -42,7 +42,7 @@ let fetchOptions = {
}; };
``` ```
Call **PhotoAccessHelper.getAssets** to obtain the image asset. Call **PhotoAccessHelper.getAssets** to obtain image assets.
```ts ```ts
try { try {
...@@ -55,7 +55,7 @@ try { ...@@ -55,7 +55,7 @@ try {
} }
``` ```
### Obtaining an Image or Video by URI ### Obtaining an Image or Video Asset by URI
Example: Obtain the image with the file URI **file://media/Photo/1**. Example: Obtain the image with the file URI **file://media/Photo/1**.
...@@ -70,7 +70,7 @@ let fetchOptions = { ...@@ -70,7 +70,7 @@ let fetchOptions = {
}; };
``` ```
Call **PhotoAccessHelper.getAssets** to obtain the image asset. Call **PhotoAccessHelper.getAssets** to obtain image assets.
```ts ```ts
try { try {
...@@ -103,7 +103,7 @@ let fetchOptions = { ...@@ -103,7 +103,7 @@ let fetchOptions = {
}; };
``` ```
Call **PhotoAccessHelper.getAssets** to obtain the image assets. Call **PhotoAccessHelper.getAssets** to obtain image assets.
```ts ```ts
try { try {
...@@ -250,7 +250,7 @@ The files moved to the trash will be retained for 30 days, and deleted permanent ...@@ -250,7 +250,7 @@ The files moved to the trash will be retained for 30 days, and deleted permanent
**Prerequisites** **Prerequisites**
- A **photoAccessHelper** instance is obtained - A **photoAccessHelper** instance is obtained.
- The application has the **ohos.permission.WRITE_IMAGEVIDEO** and **ohos.permission.READ_IMAGEVIDEO** permissions. - The application has the **ohos.permission.WRITE_IMAGEVIDEO** and **ohos.permission.READ_IMAGEVIDEO** permissions.
Example: Move the first file in the result set to the trash. Example: Move the first file in the result set to the trash.
......
...@@ -5,7 +5,7 @@ The **photoAccessHelper** module provides APIs for managing system albums, inclu ...@@ -5,7 +5,7 @@ The **photoAccessHelper** module provides APIs for managing system albums, inclu
> **NOTE** > **NOTE**
> >
> Before you start, refer to [photoAccessHelper Overview](photoAccessHelper-overview.md) to learn how to obtain a **photoAccessHelper** instance and apply for permissions required. > Before you start, refer to [photoAccessHelper Overview](photoAccessHelper-overview.md) to learn how to obtain a **photoAccessHelper** instance and apply for permissions required.
> By default, the **photoAccessHelper** instance obtained in [photoAccessHelper Overview](photoAccessHelper-overview.md) is used when **photoAccessHelper** APIs are used. If the code for obtaining the **photoAccessHelper** instance is not added, an error indicating that **photoAccessHelper** is not defined is reported. > By default, the **PhotoAccessHelper** instance obtained in [photoAccessHelper Overview](photoAccessHelper-overview.md) is used when **PhotoAccessHelper** APIs are used. If the code for obtaining the **PhotoAccessHelper** instance is not added, an error indicating that **PhotoAccessHelper** is not defined is reported.
To ensure application running efficiency, most **photoAccessHelper** calls are asynchronous in callback or promise mode. The following code samples use promise-based APIs. For details about the APIs, see [Album Management](../reference/apis/js-apis-photoAccessHelper.md). To ensure application running efficiency, most **photoAccessHelper** calls are asynchronous in callback or promise mode. The following code samples use promise-based APIs. For details about the APIs, see [Album Management](../reference/apis/js-apis-photoAccessHelper.md).
Unless otherwise specified, all the media assets to be obtained in this document exist in the database. If no media asset is obtained when the sample code is executed, check whether the media assets exist in the database. Unless otherwise specified, all the media assets to be obtained in this document exist in the database. If no media asset is obtained when the sample code is executed, check whether the media assets exist in the database.
...@@ -133,8 +133,8 @@ Example: Unfavorite an image. ...@@ -133,8 +133,8 @@ Example: Unfavorite an image.
**How to Develop** **How to Develop**
1. [Obtain the image and videos in **Favorites**](#obtaining-images-and-videos-in-favorites). 1. [Obtain the image and videos in **Favorites**](#obtaining-images-and-videos-in-favorites).
2. Set **isFavorite** to **false**. 2. Set **favoriteState** to **false**.
3. Use **FileAsset.favorite** to remove the image from **Favorites**. 3. Use **FileAsset.setFavorite** to remove the image from **Favorites**.
```ts ```ts
......
...@@ -2,55 +2,100 @@ ...@@ -2,55 +2,100 @@
When a user needs to download a file from the network to a local directory or save a user file into another directory, use **FilePicker** to save the file. When a user needs to download a file from the network to a local directory or save a user file into another directory, use **FilePicker** to save the file.
The operations for saving images, audio or video clips, and documents are similar. Call **save()** of the corresponding picker instance and pass in **saveOptions**. The operations for saving images, audio or video clips, and documents are similar. Call **save()** of the corresponding picker instance and pass in **saveOptions**. No permission is required if **FilePicker** is used to access files.
The **save()** interface saves the file in the file manager, not in the Gallery. The **save()** method saves the file in the file manager, not in the Gallery.
## Saving Images or Video Files ## Saving Images or Video Files
1. Import the **picker** module and **fs** module. For example, select an image from **Gallery** and save it to the file manager.
1. Import the [picker](../reference/apis/js-apis-file-picker.md), [fs](../reference/apis/js-apis-file-fs.md), [photoAccessHelper](../reference/apis/js-apis-photoAccessHelper.md), and [dataSharePredicates](../reference/apis/js-apis-data-dataSharePredicates.md) modules.
```ts ```ts
import picker from '@ohos.file.picker'; import picker from '@ohos.file.picker';
import fs from '@ohos.file.fs'; import fs from '@ohos.file.fs';
import photoAccessHelper from '@ohos.file.photoAccessHelper';
import dataSharePredicates from '@ohos.data.dataSharePredicates';
``` ```
2. Create a **photoSaveOptions** instance. 2. Obtain the thumbnail of the first image on the device. Before performing this operation, ensure that at least one image exists on the device.
```ts ```ts
const photoSaveOptions = new picker.PhotoSaveOptions(); // Create a photoSaveOptions instance. const context = getContext(this);
photoSaveOptions.newFileNames = ["PhotoViewPicker01.jpg"]; // (Optional) Set the names of the files to save. let photoAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
let pixelmapArrayBuffer;
async getPixelmap() {
try {
let predicates = new dataSharePredicates.DataSharePredicates();
let fetchOption = {
fetchColumns: [],
predicates: predicates
};
let fetchResult = await photoAccessHelper.getAssets(fetchOption);
console.info('[picker] getThumbnail fetchResult: ' + fetchResult);
const asset = await fetchResult.getFirstObject();
console.info('[picker] getThumbnail asset displayName = ', asset.displayName);
asset.getThumbnail().then((pixelMap) => {
let pixelBytesNumber = pixelMap.getPixelBytesNumber();
const readBuffer = new ArrayBuffer(pixelBytesNumber);
pixelMap.readPixelsToBuffer(readBuffer).then(() => {
pixelmapArrayBuffer = readBuffer;
})
}).catch((err) => {
console.error('[picker] getThumbnail failed with error: ' + err);
});
} catch (error) {
console.error('[picker] getThumbnail error = ' + error);
}
}
``` ```
3. Create a **photoViewPicker** instance and call [save()](../reference/apis/js-apis-file-picker.md#save) to open the **FilePicker** page to save the files. After the user selects the target folder, the file saving operation is complete. After the files are saved successfully, the URIs of the files saved are returned. 3. Create a **photoViewPicker** instance and call [save()](../reference/apis/js-apis-file-picker.md#save) to open the **FilePicker** page to save the image. After the user selects the target folder, the file saving operation is complete. After the image is saved successfully, the URI of the saved image is returned.
The permission on the URIs returned by **save()** is read/write. Further file operations can be performed based on the URIs in the result set. Note that the URI cannot be directly used in the **picker** callback to open a file. You need to define a global variable to save the URI and use a button to trigger file opening. The permission on the URI returned by **save()** is read/write. Further operations can be performed based on the URI in the result set. Note that the URI cannot be directly used in the **picker** callback to open a file. You need to define a global variable to save the URI and use a button to trigger file opening.
```ts ```ts
let uri = null; let uri:string;
const photoViewPicker = new picker.PhotoViewPicker(); async photoViewPickerSave() {
photoViewPicker.save(photoSaveOptions).then((photoSaveResult) => { try {
uri = photoSaveResult[0]; const photoSaveOptions = new picker.PhotoSaveOptions(); // Create a photoSaveOptions instance.
console.info('photoViewPicker.save to file succeed and uri is:' + uri); photoSaveOptions.newFileNames = ["PhotoViewPicker01.png"]; // (Optional) Name of the file to be saved. The file name in the square brackets can be customized and must be unique. If the file name already exists on the device, change the file name. Otherwise, an error will be returned.
}).catch((err) => {
console.error(`Invoke photoViewPicker.save failed, code is ${err.code}, message is ${err.message}`); const photoViewPicker = new picker.PhotoViewPicker();
}) try {
let photoSaveResult = await photoViewPicker.save(photoSaveOptions);
if (photoSaveResult != undefined) {
console.info("[picker] photoViewPickerSave photoSaveResult = " + JSON.stringify(photoSaveResult));
this.uri = photoSaveResult[0];
console.info('photoViewPicker.save to file succeed and uri is:' + photoSaveResult[0]);
}
} catch (err) {
console.error(`[picker] Invoke photoViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
}
} catch (error) {
console.info("[picker] photoViewPickerSave error = " + error);
}
}
``` ```
4. Use a button to trigger invocation of other functions. Use [fs.openSync()](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. Note that the **mode** parameter of **fs.openSync()** must be **fs.OpenMode.READ_WRITE**. 4. Use a button to trigger invocation of other functions. Use [fs.openSync()](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. Note that the **mode** parameter of **fs.openSync()** must be **fs.OpenMode.READ_WRITE**.
```ts Use [fs.write](../reference/apis/js-apis-file-fs.md#fswrite) to edit and modify the file based on the FD. After the modification is complete, close the FD.
let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
console.info('file fd: ' + file.fd);
```
5. Use [fs.writeSync()](../reference/apis/js-apis-file-fs.md#writesync) to edit the file based on the FD, and then close the FD.
```ts ```ts
let writeLen = fs.writeSync(file.fd, 'hello, world'); async writeOnly(uri) {
console.info('write data to file succeed and size is:' + writeLen); try {
fs.closeSync(file); let file = fs.openSync(uri, fs.OpenMode.WRITE_ONLY);
let writeLen = await fs.write(file.fd, pixelmapArrayBuffer);
fs.closeSync(file);
console.info("[picker] writeOnly writeLen = " + writeLen);
} catch (error) {
console.info("[picker] writeOnly error: " + error);
}
}
``` ```
## Saving Documents ## Saving Documents
......
...@@ -353,7 +353,7 @@ A constructor used to create a **SessionBackup** instance. ...@@ -353,7 +353,7 @@ A constructor used to create a **SessionBackup** instance.
```js ```js
import fs from '@ohos.file.fs'; import fs from '@ohos.file.fs';
let generalCallbacks = backup.GeneralCallbacks({ let generalCallbacks = ({
onFileReady: (err, file) => { onFileReady: (err, file) => {
if (err) { if (err) {
console.error('onFileReady failed with err: ' + err); console.error('onFileReady failed with err: ' + err);
...@@ -568,7 +568,7 @@ A constructor used to create a **SessionRestore** instance. ...@@ -568,7 +568,7 @@ A constructor used to create a **SessionRestore** instance.
```js ```js
import fs from '@ohos.file.fs'; import fs from '@ohos.file.fs';
let generalCallbacks = backup.GeneralCallbacks({ let generalCallbacks = ({
onFileReady: (err, file) => { onFileReady: (err, file) => {
if (err) { if (err) {
console.error('onFileReady failed with err: ' + err); console.error('onFileReady failed with err: ' + err);
......
# @ohos.file.picker (File Picker) # @ohos.file.picker (File Picker)
**Picker** encapsulates the system applications such as **PhotoViewPicker**, **DocumentViewPicker** and **AudioViewPicker** to provide capabilities of selecting and saving files of different types. The application can select the picker as required.
> **NOTE** > **NOTE**
> >
> The initial APIs of this module are supported since API version 9. Newly added APIs will be marked with a superscript to indicate their earliest API version. > The initial APIs of this module are supported since API version 9. Newly added APIs will be marked with a superscript to indicate their earliest API version.
**Picker** encapsulates the system applications such as **PhotoViewPicker**, **DocumentViewPicker** and **AudioViewPicker** to provide capabilities of selecting and saving files of different types. The application can select the picker as required.
## Modules to Import ## Modules to Import
```js ```js
...@@ -138,7 +138,7 @@ async function example() { ...@@ -138,7 +138,7 @@ async function example() {
save(option?: PhotoSaveOptions) : Promise&lt;Array&lt;string&gt;&gt; save(option?: PhotoSaveOptions) : Promise&lt;Array&lt;string&gt;&gt;
Saves one or more images or videos in a **photoPicker** page. This API uses a promise to return the result. You can pass in **PhotoSaveOptions** to specify the file names of the images or videos to save. Saves one or more images or videos in a **photoPicker** page. This API uses a promise to return the result. You can pass in **PhotoSaveOptions** to specify the file names of the images or videos to save. The **save()** API saves the file in the file manager, not in the Gallery.
**System capability**: SystemCapability.FileManagement.UserFileService **System capability**: SystemCapability.FileManagement.UserFileService
...@@ -177,7 +177,7 @@ async function example() { ...@@ -177,7 +177,7 @@ async function example() {
save(option: PhotoSaveOptions, callback: AsyncCallback&lt;Array&lt;string&gt;&gt;) : void save(option: PhotoSaveOptions, callback: AsyncCallback&lt;Array&lt;string&gt;&gt;) : void
Saves one or more images or videos in a **photoPicker** page. This API uses an asynchronous callback to return the result. You can pass in **PhotoSaveOptions** to specify the file names of the images or videos to save. Saves one or more images or videos in a **photoPicker** page. This API uses an asynchronous callback to return the result. You can pass in **PhotoSaveOptions** to specify the file names of the images or videos to save. The **save()** API saves the file in the file manager, not in the Gallery.
**System capability**: SystemCapability.FileManagement.UserFileService **System capability**: SystemCapability.FileManagement.UserFileService
...@@ -213,7 +213,7 @@ async function example() { ...@@ -213,7 +213,7 @@ async function example() {
save(callback: AsyncCallback&lt;Array&lt;string&gt;&gt;) : void save(callback: AsyncCallback&lt;Array&lt;string&gt;&gt;) : void
Saves one or more images or videos in a **photoPicker** page. This API uses an asynchronous callback to return the result. Saves one or more images or videos in a **photoPicker** page. This API uses an asynchronous callback to return the result. The **save()** API saves the file in the file manager, not in the Gallery.
**System capability**: SystemCapability.FileManagement.UserFileService **System capability**: SystemCapability.FileManagement.UserFileService
...@@ -727,7 +727,7 @@ Defines information about the images or videos selected. ...@@ -727,7 +727,7 @@ Defines information about the images or videos selected.
| Name | Type | Readable| Writable| Description | | Name | Type | Readable| Writable| Description |
| ----------------------- | ------------------- | ---- | ---- | ------------------------------ | | ----------------------- | ------------------- | ---- | ---- | ------------------------------ |
| photoUris | Array&lt;string&gt; | Yes | Yes | URIs of the media files selected.| | photoUris | Array&lt;string&gt; | Yes | Yes | URIs of the media files selected.|
| isOriginalPhoto | boolean | Yes | Yes | Whether the selected media file is the original image.| | isOriginalPhoto | boolean | Yes | Yes | Whether the selected media file is the original image.|
## PhotoSaveOptions ## PhotoSaveOptions
......
...@@ -4,7 +4,7 @@ The **photoAccessHelper** module provides APIs for album management, including c ...@@ -4,7 +4,7 @@ The **photoAccessHelper** module provides APIs for album management, including c
> **NOTE** > **NOTE**
> >
> - The initial APIs of this module are supported since API version 10. Newly added APIs will be marked with a superscript to indicate their earliest API version. > The initial APIs of this module are supported since API version 10. Newly added APIs will be marked with a superscript to indicate their earliest API version.
## Modules to Import ## Modules to Import
...@@ -341,7 +341,7 @@ For details about the error codes, see [File Management Error Codes](../errorcod ...@@ -341,7 +341,7 @@ For details about the error codes, see [File Management Error Codes](../errorcod
| ID| Error Message| | ID| Error Message|
| -------- | ---------------------------------------- | | -------- | ---------------------------------------- |
| 202 | Called by non-system application. | | 202 | Called by non-system application. |
| 401 | if type displayName is not string. | | 401 | if type displayName is not string. |
| 14000001 | if type of displayName is invalid. | | 14000001 | if type of displayName is invalid. |
...@@ -401,9 +401,9 @@ async function example() { ...@@ -401,9 +401,9 @@ async function example() {
let options = { let options = {
title: 'testPhoto' title: 'testPhoto'
} }
phAccessHelper.createAsset(photoType, extension, options, (err, photoAsset) => { phAccessHelper.createAsset(photoType, extension, options, (err, uri) => {
if (photoAsset != undefined) { if (uri != undefined) {
console.info('createAsset file displayName' + photoAsset.displayName); console.info('createAsset uri' + uri);
console.info('createAsset successfully'); console.info('createAsset successfully');
} else { } else {
console.error('createAsset failed, message = ', err); console.error('createAsset failed, message = ', err);
...@@ -445,9 +445,9 @@ async function example() { ...@@ -445,9 +445,9 @@ async function example() {
console.info('createAssetDemo'); console.info('createAssetDemo');
let photoType = photoAccessHelper.PhotoType.IMAGE; let photoType = photoAccessHelper.PhotoType.IMAGE;
let extension = 'jpg'; let extension = 'jpg';
phAccessHelper.createAsset(photoType, extension, (err, photoAsset) => { phAccessHelper.createAsset(photoType, extension, (err, uri) => {
if (photoAsset != undefined) { if (uri != undefined) {
console.info('createAsset file displayName' + photoAsset.displayName); console.info('createAsset uri' + uri);
console.info('createAsset successfully'); console.info('createAsset successfully');
} else { } else {
console.error('createAsset failed, message = ', err); console.error('createAsset failed, message = ', err);
...@@ -499,8 +499,8 @@ async function example() { ...@@ -499,8 +499,8 @@ async function example() {
let options = { let options = {
title: 'testPhoto' title: 'testPhoto'
} }
let photoAsset = await phAccessHelper.createAsset(photoType,extension, options); let uri = await phAccessHelper.createAsset(photoType, extension, options);
console.info('createAsset file displayName' + photoAsset.displayName); console.info('createAsset uri' + uri);
console.info('createAsset successfully'); console.info('createAsset successfully');
} catch (err) { } catch (err) {
console.error('createAsset failed, message = ', err); console.error('createAsset failed, message = ', err);
...@@ -1077,15 +1077,15 @@ async function example() { ...@@ -1077,15 +1077,15 @@ async function example() {
//file had changed, do something //file had changed, do something
} }
// Register onCallback1. // Register onCallback1.
phAccessHelper.registerChange(photoAsset.uri, false, onCallback1); phAccessHelper.registerChange(photoAsset.uri, false, onCallback1);
// Register onCallback2. // Register onCallback2.
phAccessHelper.registerChange(photoAsset.uri, false, onCallback2); phAccessHelper.registerChange(photoAsset.uri, false, onCallback2);
photoAsset.favorite(true, (err) => { photoAsset.setFavorite(true, (err) => {
if (err == undefined) { if (err == undefined) {
console.info('favorite successfully'); console.info('setFavorite successfully');
} else { } else {
console.error('favorite failed with error:' + err); console.error('setFavorite failed with error:' + err);
} }
}); });
} }
...@@ -1145,11 +1145,11 @@ async function example() { ...@@ -1145,11 +1145,11 @@ async function example() {
phAccessHelper.registerChange(photoAsset.uri, false, onCallback2); phAccessHelper.registerChange(photoAsset.uri, false, onCallback2);
// Unregister the listening of onCallback1. // Unregister the listening of onCallback1.
phAccessHelper.unRegisterChange(photoAsset.uri, onCallback1); phAccessHelper.unRegisterChange(photoAsset.uri, onCallback1);
photoAsset.favorite(true, (err) => { photoAsset.setFavorite(true, (err) => {
if (err == undefined) { if (err == undefined) {
console.info('favorite successfully'); console.info('setFavorite successfully');
} else { } else {
console.error('favorite failed with error:' + err); console.error('setFavorite failed with error:' + err);
} }
}); });
} }
...@@ -1539,7 +1539,7 @@ For details about the error codes, see [Universal Error Codes](../errorcodes/err ...@@ -1539,7 +1539,7 @@ For details about the error codes, see [Universal Error Codes](../errorcodes/err
| -------- | ---------------------------------------- | | -------- | ---------------------------------------- |
| 401 | if values to commit is invalid. | | 401 | if values to commit is invalid. |
**Example** **Example**
```ts ```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates'; import dataSharePredicates from '@ohos.data.dataSharePredicates';
...@@ -2839,7 +2839,7 @@ Obtains image and video assets. This API uses an asynchronous callback to return ...@@ -2839,7 +2839,7 @@ Obtains image and video assets. This API uses an asynchronous callback to return
| Name | Type | Mandatory| Description | | Name | Type | Mandatory| Description |
| -------- | ------------------------- | ---- | ---------- | | -------- | ------------------------- | ---- | ---------- |
| options | [FetchOptions](#fetchoptions) | Yes | Options for fetching the album files.| | options | [FetchOptions](#fetchoptions) | Yes | Options for fetching the albums.|
| callback | AsyncCallback&lt;[FetchResult](#fetchresult)&lt;[PhotoAsset](#photoasset)&gt;&gt; | Yes | Callback invoked to return the image and video assets obtained.| | callback | AsyncCallback&lt;[FetchResult](#fetchresult)&lt;[PhotoAsset](#photoasset)&gt;&gt; | Yes | Callback invoked to return the image and video assets obtained.|
**Error codes** **Error codes**
...@@ -2856,17 +2856,17 @@ For details about the error codes, see [Universal Error Codes](../errorcodes/err ...@@ -2856,17 +2856,17 @@ For details about the error codes, see [Universal Error Codes](../errorcodes/err
import dataSharePredicates from '@ohos.data.dataSharePredicates'; import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() { async function example() {
console.info('albumGetPhotoAssetsDemoCallback'); console.info('albumGetAssetsDemoCallback');
let predicates = new dataSharePredicates.DataSharePredicates(); let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = { let albumFetchOptions = {
fetchColumns: [],
predicates: predicates predicates: predicates
}; };
let fetchOption = { let fetchOption = {
fetchColumns: [], fetchColumns: [],
predicates: predicates predicates: predicates
}; };
const albumList = await phAccessHelper.getAlbums(albumFetchOptions); const albumList = await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, albumFetchOptions);
const album = await albumList.getFirstObject(); const album = await albumList.getFirstObject();
album.getAssets(fetchOption, (err, albumFetchResult) => { album.getAssets(fetchOption, (err, albumFetchResult) => {
if (albumFetchResult != undefined) { if (albumFetchResult != undefined) {
...@@ -2914,17 +2914,18 @@ For details about the error codes, see [Universal Error Codes](../errorcodes/err ...@@ -2914,17 +2914,18 @@ For details about the error codes, see [Universal Error Codes](../errorcodes/err
import dataSharePredicates from '@ohos.data.dataSharePredicates'; import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() { async function example() {
console.info('albumGetPhotoAssetsDemoPromise'); console.info('albumGetAssetsDemoPromise');
let predicates = new dataSharePredicates.DataSharePredicates(); let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = { let albumFetchOptions = {
fetchColumns: [],
predicates: predicates predicates: predicates
}; };
let fetchOption = { let fetchOption = {
fetchColumns: [], fetchColumns: [],
predicates: predicates predicates: predicates
}; };
const albumList = await phAccessHelper.getAlbums(albumFetchOptions); const albumList = await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, albumFetchOptions);
const album = await albumList.getFirstObject(); const album = await albumList.getFirstObject();
album.getAssets(fetchOption).then((albumFetchResult) => { album.getAssets(fetchOption).then((albumFetchResult) => {
console.info('album getPhotoAssets successfully, getCount: ' + albumFetchResult.getCount()); console.info('album getPhotoAssets successfully, getCount: ' + albumFetchResult.getCount());
...@@ -2967,9 +2968,10 @@ async function example() { ...@@ -2967,9 +2968,10 @@ async function example() {
console.info('albumCommitModifyDemo'); console.info('albumCommitModifyDemo');
let predicates = new dataSharePredicates.DataSharePredicates(); let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = { let albumFetchOptions = {
fetchColumns: [],
predicates: predicates predicates: predicates
}; };
const albumList = await phAccessHelper.getAlbums(albumFetchOptions); const albumList = await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, albumFetchOptions);
const album = await albumList.getFirstObject(); const album = await albumList.getFirstObject();
album.albumName = 'hello'; album.albumName = 'hello';
album.commitModify((err) => { album.commitModify((err) => {
...@@ -3015,9 +3017,10 @@ async function example() { ...@@ -3015,9 +3017,10 @@ async function example() {
console.info('albumCommitModifyDemo'); console.info('albumCommitModifyDemo');
let predicates = new dataSharePredicates.DataSharePredicates(); let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = { let albumFetchOptions = {
fetchColumns: [],
predicates: predicates predicates: predicates
}; };
const albumList = await phAccessHelper.getAlbums(albumFetchOptions); const albumList = await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC, albumFetchOptions);
const album = await albumList.getFirstObject(); const album = await albumList.getFirstObject();
album.albumName = 'hello'; album.albumName = 'hello';
album.commitModify().then(() => { album.commitModify().then(() => {
...@@ -3496,6 +3499,131 @@ async function example() { ...@@ -3496,6 +3499,131 @@ async function example() {
} }
``` ```
### setCoverUri
setCoverUri(uri: string, callback: AsyncCallback&lt;void&gt;): void;
Sets the album cover. This API uses an asynchronous callback to return the result.
**NOTE**<br>This API can be used to set the user album cover, but not the system album cover.
**System API**: This is a system API.
**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO
**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | ------------------------- | ---- | ---------- |
| uri | string | Yes | URI of the file to be set as the album cover.|
| callback | AsyncCallback&lt;void&gt; | Yes | Callback that returns no value.|
**Error codes**
For details about the error codes, see [Universal Error Codes](../errorcodes/errorcode-universal.md).
| ID| Error Message|
| -------- | ---------------------------------------- |
| 202 | Called by non-system application. |
| 401 | if parameter is invalid. |
**Example**
```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() {
try {
console.info('setCoverUriDemoCallback');
let predicates = new dataSharePredicates.DataSharePredicates();
let fetchOption = {
fetchColumns: [],
predicates: predicates
};
let albumFetchResult = await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC);
let album = await albumFetchResult.getFirstObject();
let fetchResult = await album.getAssets(fetchOption);
let asset = await fetchResult.getFirstObject();
album.setCoverUri(asset.uri, (err) => {
if (err === undefined) {
console.info('album setCoverUri successfully');
} else {
console.error('album setCoverUri failed with error: ' + err);
}
});
} catch (err) {
console.error('setCoverUriDemoCallback failed with error: ' + err);
}
}
```
### setCoverUri
setCoverUri(uri: string): Promise&lt;void&gt;;
Sets the album cover. This API uses a promise to return the result.
**NOTE**<br>This API can be used to set the user album cover, but not the system album cover.
**System API**: This is a system API.
**Required permissions**: ohos.permission.WRITE_IMAGEVIDEO
**System capability**: SystemCapability.FileManagement.PhotoAccessHelper.Core
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | ------------------------- | ---- | ---------- |
| uri | string | Yes | URI of the file to be set as the album cover.|
**Return value**
| Type | Description |
| --------------------------------------- | ----------------- |
|Promise&lt;void&gt; | Promise that returns no value.|
**Error codes**
For details about the error codes, see [Universal Error Codes](../errorcodes/errorcode-universal.md).
| ID| Error Message|
| -------- | ---------------------------------------- |
| 202 | Called by non-system application. |
| 401 | if parameter is invalid. |
**Example**
```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() {
try {
console.info('setCoverUriDemoCallback');
let predicates = new dataSharePredicates.DataSharePredicates();
let fetchOption = {
fetchColumns: [],
predicates: predicates
};
let albumFetchResult = await phAccessHelper.getAlbums(photoAccessHelper.AlbumType.USER, photoAccessHelper.AlbumSubtype.USER_GENERIC);
let album = await albumFetchResult.getFirstObject();
let fetchResult = await album.getAssets(fetchOption);
let asset = await fetchResult.getFirstObject();
album.setCoverUri(asset.uri, (err) => {
if (err === undefined) {
console.info('album setCoverUri successfully');
} else {
console.error('album setCoverUri failed with error: ' + err);
}
});
} catch (err) {
console.error('setCoverUriDemoCallback failed with error: ' + err);
}
}
```
## MemberType ## MemberType
Enumerates the member types. Enumerates the member types.
...@@ -3597,6 +3725,7 @@ Defines the key information about an image or video file. ...@@ -3597,6 +3725,7 @@ Defines the key information about an image or video file.
| POSITION | 'position' | File location type. **System API**: This is a system API. | | POSITION | 'position' | File location type. **System API**: This is a system API. |
| DATE_TRASHED | 'date_trashed' | Date when the file was deleted. The value is the number of seconds between the time when the file is deleted and January 1, 1970. **System API**: This is a system API. | | DATE_TRASHED | 'date_trashed' | Date when the file was deleted. The value is the number of seconds between the time when the file is deleted and January 1, 1970. **System API**: This is a system API. |
| HIDDEN | 'hidden' | Whether the file is hidden. **System API**: This is a system API. | | HIDDEN | 'hidden' | Whether the file is hidden. **System API**: This is a system API. |
| CAMERA_SHOT_KEY | 'camera_shot_key' | Key for the Untra Snamshot feature, which allows the camera to take photos or record videos with the screen off. (This parameter is available only for the system camera, and the key value is defined by the system camera.)<br/>**System API**: This is a system API. |
## AlbumKeys ## AlbumKeys
...@@ -3618,6 +3747,7 @@ Defines the options for creating an image or video asset. ...@@ -3618,6 +3747,7 @@ Defines the options for creating an image or video asset.
| Name | Type | Mandatory| Description | | Name | Type | Mandatory| Description |
| ---------------------- | ------------------- | ---- | ------------------------------------------------ | | ---------------------- | ------------------- | ---- | ------------------------------------------------ |
| subtype | [PhotoSubtype](#photosubtype) | No | Subtype of the image or video. **System API**: This is a system API. | | subtype | [PhotoSubtype](#photosubtype) | No | Subtype of the image or video. **System API**: This is a system API. |
| cameraShotKey | string | No | Key for the Untra Snamshot feature, which allows the camera to take photos or record videos with the screen off. (This parameter is available only for the system camera, and the key value is defined by the system camera.)<br/>**System API**: This is a system API. |
## CreateOptions ## CreateOptions
......
...@@ -53,12 +53,12 @@ For details about the error codes, see [Ability Error Codes](../errorcodes/error ...@@ -53,12 +53,12 @@ For details about the error codes, see [Ability Error Codes](../errorcodes/error
```js ```js
import uriPermissionManager from '@ohos.application.uriPermissionManager'; import uriPermissionManager from '@ohos.application.uriPermissionManager';
import WantConstant from '@ohos.ability.wantConstant'; import WantConstant from '@ohos.ability.wantConstant';
import fileio from '@ohos.fileio'; import fs from '@ohos.file.fs';
import fileUri from '@ohos.file.fileuri'; import fileUri from '@ohos.file.fileuri';
let targetBundleName = 'com.example.test_case1' let targetBundleName = 'com.example.test_case1'
let path = "file://com.example.test_case1/data/storage/el2/base/haps/entry_test/files/newDir"; let path = "file://com.example.test_case1/data/storage/el2/base/haps/entry_test/files/newDir";
fileio.mkdir(path, function (err) { fs.mkdir(path, function (err) {
if (err) { if (err) {
console.log("mkdir error"+err.message) console.log("mkdir error"+err.message)
} else { } else {
...@@ -115,13 +115,13 @@ By default, an application can authorize its own URIs to another application. If ...@@ -115,13 +115,13 @@ By default, an application can authorize its own URIs to another application. If
```js ```js
import uriPermissionManager from '@ohos.application.uriPermissionManager'; import uriPermissionManager from '@ohos.application.uriPermissionManager';
import WantConstant from '@ohos.ability.wantConstant'; import WantConstant from '@ohos.ability.wantConstant';
import fileio from '@ohos.fileio'; import fs from '@ohos.file.fs';
import fileUri from '@ohos.file.fileuri'; import fileUri from '@ohos.file.fileuri';
let targetBundleName = 'com.example.test_case1' let targetBundleName = 'com.example.test_case1'
let path = "file://com.example.test_case1/data/storage/el2/base/haps/entry_test/files/newDir"; let path = "file://com.example.test_case1/data/storage/el2/base/haps/entry_test/files/newDir";
fileio.mkdir(path, function (err) { fs.mkdir(path, function (err) {
if (err) { if (err) {
console.log("mkdir error"+err.message) console.log("mkdir error"+err.message)
} else { } else {
......
...@@ -481,113 +481,6 @@ async function example() { ...@@ -481,113 +481,6 @@ async function example() {
} }
``` ```
### getPhotoAlbums
getPhotoAlbums(options: AlbumFetchOptions, callback: AsyncCallback&lt;FetchResult&lt;Album&gt;&gt;): void;
Obtains image and video albums. This API uses an asynchronous callback to return the result.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Required permissions**: ohos.permission.READ_IMAGEVIDEO
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | ------------------------ | ---- | ------------------------- |
| options | [AlbumFetchOptions](#albumfetchoptions) | Yes | Options for fetching the albums. |
| callback | AsyncCallback&lt;[FetchResult](#fetchresult)&lt;[Album](#album)&gt;&gt; | Yes | Callback invoked to return the image and video albums obtained.|
**Error codes**
For details about the error codes, see [File Management Error Codes](../errorcodes/errorcode-filemanagement.md).
| ID| Error Message|
| -------- | ---------------------------------------- |
| 13900020 | if type options is not AlbumFetchOptions. |
**Example**
```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() {
console.info('getPhotoAlbumsDemo');
let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = {
predicates: predicates
};
mgr.getPhotoAlbums(albumFetchOptions, (err, fetchResult) => {
if (fetchResult != undefined) {
console.info('albums.count = ' + fetchResult.getCount());
fetchResult.getFirstObject((err, album) => {
if (album != undefined) {
console.info('first album.albumName = ' + album.albumName);
} else {
console.error('album is undefined, err = ', err);
}
});
} else {
console.error('getPhotoAlbums fail, message = ', err);
}
});
}
```
### getPhotoAlbums
getPhotoAlbums(options: AlbumFetchOptions): Promise&lt;FetchResult&lt;Album&gt;&gt;;
Obtains image and video albums. This API uses a promise to return the result.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Required permissions**: ohos.permission.READ_IMAGEVIDEO
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | ------------------------ | ---- | ------------------------- |
| options | [AlbumFetchOptions](#albumfetchoptions) | Yes | Options for fetching the albums. |
**Return value**
| Type | Description |
| --------------------------- | -------------- |
| Promise&lt;[FetchResult](#fetchresult)&lt;[Album](#album)&gt;&gt; | Promise used to return the image and video albums obtained.|
**Error codes**
For details about the error codes, see [File Management Error Codes](../errorcodes/errorcode-filemanagement.md).
| ID| Error Message|
| -------- | ---------------------------------------- |
| 13900020 | if type options is not AlbumFetchOptions. |
**Example**
```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() {
console.info('getPhotoAlbumsDemo');
let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = {
predicates: predicates
};
try {
let fetchResult = await mgr.getPhotoAlbums(albumFetchOptions);
console.info('album.count = ' + fetchResult.getCount());
const album = await fetchResult.getFirstObject();
console.info('first album.albumName = ' + album.albumName);
} catch (err) {
console.error('getPhotoAlbums fail, message = ' + err);
}
}
```
### createAlbum<sup>10+</sup> ### createAlbum<sup>10+</sup>
createAlbum(name: string, callback: AsyncCallback&lt;Album&gt;): void; createAlbum(name: string, callback: AsyncCallback&lt;Album&gt;): void;
...@@ -935,12 +828,124 @@ async function example() { ...@@ -935,12 +828,124 @@ async function example() {
} }
``` ```
### getPhotoAlbums
getPhotoAlbums(options: AlbumFetchOptions, callback: AsyncCallback&lt;FetchResult&lt;Album&gt;&gt;): void;
Obtains image and video albums. This API uses an asynchronous callback to return the result.
This API will be deprecated. Use [getAlbums<sup>10+</sup>](#getalbums10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Required permissions**: ohos.permission.READ_IMAGEVIDEO
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | ------------------------ | ---- | ------------------------- |
| options | [AlbumFetchOptions](#albumfetchoptions) | Yes | Options for fetching the albums. |
| callback | AsyncCallback&lt;[FetchResult](#fetchresult)&lt;[Album](#album)&gt;&gt; | Yes | Callback invoked to return the image and video albums obtained.|
**Error codes**
For details about the error codes, see [File Management Error Codes](../errorcodes/errorcode-filemanagement.md).
| ID| Error Message|
| -------- | ---------------------------------------- |
| 13900020 | if type options is not AlbumFetchOptions. |
**Example**
```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() {
console.info('getPhotoAlbumsDemo');
let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = {
predicates: predicates
};
mgr.getPhotoAlbums(albumFetchOptions, (err, fetchResult) => {
if (fetchResult != undefined) {
console.info('albums.count = ' + fetchResult.getCount());
fetchResult.getFirstObject((err, album) => {
if (album != undefined) {
console.info('first album.albumName = ' + album.albumName);
} else {
console.error('album is undefined, err = ', err);
}
});
} else {
console.error('getPhotoAlbums fail, message = ', err);
}
});
}
```
### getPhotoAlbums
getPhotoAlbums(options: AlbumFetchOptions): Promise&lt;FetchResult&lt;Album&gt;&gt;;
Obtains image and video albums. This API uses a promise to return the result.
This API will be deprecated. Use [getAlbums<sup>10+</sup>](#getalbums10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Required permissions**: ohos.permission.READ_IMAGEVIDEO
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | ------------------------ | ---- | ------------------------- |
| options | [AlbumFetchOptions](#albumfetchoptions) | Yes | Options for fetching the albums. |
**Return value**
| Type | Description |
| --------------------------- | -------------- |
| Promise&lt;[FetchResult](#fetchresult)&lt;[Album](#album)&gt;&gt; | Promise used to return the image and video albums obtained.|
**Error codes**
For details about the error codes, see [File Management Error Codes](../errorcodes/errorcode-filemanagement.md).
| ID| Error Message|
| -------- | ---------------------------------------- |
| 13900020 | if type options is not AlbumFetchOptions. |
**Example**
```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates';
async function example() {
console.info('getPhotoAlbumsDemo');
let predicates = new dataSharePredicates.DataSharePredicates();
let albumFetchOptions = {
predicates: predicates
};
try {
let fetchResult = await mgr.getPhotoAlbums(albumFetchOptions);
console.info('album.count = ' + fetchResult.getCount());
const album = await fetchResult.getFirstObject();
console.info('first album.albumName = ' + album.albumName);
} catch (err) {
console.error('getPhotoAlbums fail, message = ' + err);
}
}
```
### getPrivateAlbum ### getPrivateAlbum
getPrivateAlbum(type: PrivateAlbumType, callback: AsyncCallback&lt;FetchResult&lt;PrivateAlbum&gt;&gt;): void; getPrivateAlbum(type: PrivateAlbumType, callback: AsyncCallback&lt;FetchResult&lt;PrivateAlbum&gt;&gt;): void;
Obtains the system album. This API uses an asynchronous callback to return the result. Obtains the system album. This API uses an asynchronous callback to return the result.
This API will be deprecated. Use [getAlbums<sup>10+</sup>](#getalbums10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Required permissions**: ohos.permission.READ_IMAGEVIDEO **Required permissions**: ohos.permission.READ_IMAGEVIDEO
...@@ -982,6 +987,8 @@ getPrivateAlbum(type: PrivateAlbumType): Promise&lt;FetchResult&lt;PrivateAlbum& ...@@ -982,6 +987,8 @@ getPrivateAlbum(type: PrivateAlbumType): Promise&lt;FetchResult&lt;PrivateAlbum&
Obtains the system album. This API uses a promise to return the result. Obtains the system album. This API uses a promise to return the result.
This API will be deprecated. Use [getAlbums<sup>10+</sup>](#getalbums10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Required permissions**: ohos.permission.READ_IMAGEVIDEO **Required permissions**: ohos.permission.READ_IMAGEVIDEO
...@@ -1252,102 +1259,6 @@ async function example() { ...@@ -1252,102 +1259,6 @@ async function example() {
} }
``` ```
### on
on(type: ChangeEvent, callback: Callback&lt;void&gt;): void
Subscribes to changes of the file management library. This API uses a callback to return the result.
This API will be deprecated. Use [on<sup>10+</sup>](#on10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | -------------------- | ---- | ------------------------------------------------------------ |
| type | [ChangeEvent](#changeevent) | Yes | Type of event to subscribe to.<br>**deviceChange** indicates the device change.<br>**albumChange** indicates the album change.<br>**imageChange** indicates the image change.<br>**audioChange** indicates the audio file change.<br>**videoChange** indicates the video file change.<br>**remoteFileChange** indicates the file change on the registered device.|
| callback | Callback&lt;void&gt; | Yes | Callback that returns no value. |
**Example**
```ts
async function example() {
console.info('onDemo');
let count = 0;
mgr.on('imageChange', () => {
count++;
// Image file changed. Do something.
});
try {
let testFileName = 'testFile' + Date.now() + '.jpg';
let fileAsset = await mgr.createPhotoAsset(testFileName);
console.info('createPhotoAsset file displayName' + fileAsset.displayName);
console.info('createPhotoAsset successfully');
} catch (err) {
console.error('createPhotoAsset failed, message = ' + err);
}
// Sleep 1s.
if (count > 0) {
console.info('onDemo success');
} else {
console.error('onDemo fail');
}
mgr.off('imageChange', () => {
// Unsubscription succeeds.
});
}
```
### off
off(type: ChangeEvent, callback?: Callback&lt;void&gt;): void
Unsubscribes from changes of the file management library. This API uses a callback to return the result.
This API will be deprecated. Use [off<sup>10+</sup>](#off10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | -------------------- | ---- | ------------------------------------------------------------ |
| type | [ChangeEvent](#changeevent) | Yes | Type of event to subscribe to.<br>**deviceChange** indicates the device change.<br>**albumChange** indicates the album change.<br>**imageChange** indicates the image change.<br>**audioChange** indicates the audio file change.<br>**videoChange** indicates the video file change.<br>**remoteFileChange** indicates the change of the file on a registered device.|
| callback | Callback&lt;void&gt; | No | Callback that returns no value. |
**Example**
```ts
async function example() {
console.info('offDemo');
let count = 0;
mgr.on('imageChange', () => {
count++;
// Image file changed. Do something.
});
mgr.off('imageChange', () => {
// Unsubscription succeeds.
});
try {
let testFileName = 'testFile' + Date.now() + '.jpg';
let fileAsset = await mgr.createPhotoAsset(testFileName);
console.info('createPhotoAsset file displayName' + fileAsset.displayName);
console.info('createPhotoAsset successfully');
} catch (err) {
console.error('createPhotoAsset failed, message = ' + err);
}
// Sleep 1s.
if (count == 0) {
console.info('offDemo success');
} else {
console.error('offDemo fail');
}
}
```
### getActivePeers ### getActivePeers
getActivePeers(callback: AsyncCallback&lt;Array&lt;PeerInfo&gt;&gt;): void; getActivePeers(callback: AsyncCallback&lt;Array&lt;PeerInfo&gt;&gt;): void;
...@@ -1427,7 +1338,7 @@ Obtains information about all peer devices. This API uses an asynchronous callba ...@@ -1427,7 +1338,7 @@ Obtains information about all peer devices. This API uses an asynchronous callba
| Name | Type | Mandatory| Description | | Name | Type | Mandatory| Description |
| -------- | --------------------------------- | ---- | ------------ | | -------- | --------------------------------- | ---- | ------------ |
| callback | AsyncCallback&lt;Array&lt;[PeerInfo](#peerinfo)&gt;&gt; | Yes | Callback invoked to return the information obtained.| | callback | AsyncCallback&lt;Array&lt;[PeerInfo](#peerinfo)&gt;&gt; | Yes | Callback invoked to return the peer device information obtained.|
**Example** **Example**
...@@ -1545,7 +1456,7 @@ async function example() { ...@@ -1545,7 +1456,7 @@ async function example() {
on(uri: string, forSubUri: boolean, callback: Callback&lt;ChangeData&gt;) : void on(uri: string, forSubUri: boolean, callback: Callback&lt;ChangeData&gt;) : void
Enables listening for the specified URI. This API uses a callback to return the result. Registers a listener for the specified URI.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -1591,7 +1502,7 @@ async function example() { ...@@ -1591,7 +1502,7 @@ async function example() {
// File changed. Do something. // File changed. Do something.
} }
// Register onCallback1. // Register onCallback1.
mgr.on(fileAsset.uri, false, onCallback1); mgr.on(fileAsset.uri, false, onCallback1);
// Register onCallback2. // Register onCallback2.
mgr.on(fileAsset.uri, false, onCallback2); mgr.on(fileAsset.uri, false, onCallback2);
...@@ -1609,7 +1520,7 @@ async function example() { ...@@ -1609,7 +1520,7 @@ async function example() {
off(uri: string, callback?: Callback&lt;ChangeData&gt;): void off(uri: string, callback?: Callback&lt;ChangeData&gt;): void
Disables listening for the specified URI. Multiple callbacks can be registered for a URI for listening. You can use **off()** to disable the listening of the specified callbacks or all callbacks. Unregisters the listener for the specified URI. Multiple callbacks can be registered for a URI for listening. You can use this API to unregister the specified callbacks or all callbacks.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -1618,7 +1529,7 @@ Disables listening for the specified URI. Multiple callbacks can be registered f ...@@ -1618,7 +1529,7 @@ Disables listening for the specified URI. Multiple callbacks can be registered f
| Name | Type | Mandatory| Description | | Name | Type | Mandatory| Description |
| -------- | ------------------------------------------- | ---- | ------------------------------------------------------------ | | -------- | ------------------------------------------- | ---- | ------------------------------------------------------------ |
| uri | string | Yes | URI of the file asset or album, or [DefaultChangeUri](#defaultchangeuri10).| | uri | string | Yes | URI of the file asset or album, or [DefaultChangeUri](#defaultchangeuri10).|
| callback | Callback&lt;[ChangeData](#changedata10)&gt; | No | Callback registered by [on<sup>10+</sup>](#on10). If this parameter is not specified, all callbacks registered for the URI will be unregistered. <br>**NOTE**: The specified callback will not be invoked.| | callback | Callback&lt;[ChangeData](#changedata10)&gt; | No | Callback registered by [on<sup>10+</sup>](#on10). If this parameter is not specified, all listener callbacks registered for the URI will be unregistered. <br>**NOTE**: The specified callback will not be invoked.|
**Error codes** **Error codes**
...@@ -1667,6 +1578,102 @@ async function example() { ...@@ -1667,6 +1578,102 @@ async function example() {
} }
``` ```
### on
on(type: ChangeEvent, callback: Callback&lt;void&gt;): void
Subscribes to changes of the file management library. This API uses a callback to return the result.
This API will be deprecated. Use [on<sup>10+</sup>](#on10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | -------------------- | ---- | ------------------------------------------------------------ |
| type | [ChangeEvent](#changeevent) | Yes | Type of event to subscribe to.<br>**deviceChange** indicates the device change.<br>**albumChange** indicates the album change.<br>**imageChange** indicates the image change.<br>**audioChange** indicates the audio file change.<br>**videoChange** indicates the video file change.<br>**remoteFileChange** indicates the file change on the registered device.|
| callback | Callback&lt;void&gt; | Yes | Callback that returns no value. |
**Example**
```ts
async function example() {
console.info('onDemo');
let count = 0;
mgr.on('imageChange', () => {
count++;
// Image file changed. Do something.
});
try {
let testFileName = 'testFile' + Date.now() + '.jpg';
let fileAsset = await mgr.createPhotoAsset(testFileName);
console.info('createPhotoAsset file displayName' + fileAsset.displayName);
console.info('createPhotoAsset successfully');
} catch (err) {
console.error('createPhotoAsset failed, message = ' + err);
}
// Sleep 1s.
if (count > 0) {
console.info('onDemo success');
} else {
console.error('onDemo fail');
}
mgr.off('imageChange', () => {
// Unsubscription succeeds.
});
}
```
### off
off(type: ChangeEvent, callback?: Callback&lt;void&gt;): void
Unsubscribes from changes of the file management library. This API uses a callback to return the result.
This API will be deprecated. Use [off<sup>10+</sup>](#off10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core
**Parameters**
| Name | Type | Mandatory| Description |
| -------- | -------------------- | ---- | ------------------------------------------------------------ |
| type | [ChangeEvent](#changeevent) | Yes | Type of event to subscribe to.<br>**deviceChange** indicates the device change.<br>**albumChange** indicates the album change.<br>**imageChange** indicates the image change.<br>**audioChange** indicates the audio file change.<br>**videoChange** indicates the video file change.<br>**remoteFileChange** indicates the change of the file on a registered device.|
| callback | Callback&lt;void&gt; | No | Callback that returns no value. |
**Example**
```ts
async function example() {
console.info('offDemo');
let count = 0;
mgr.on('imageChange', () => {
count++;
// Image file changed. Do something.
});
mgr.off('imageChange', () => {
// Unsubscription succeeds.
});
try {
let testFileName = 'testFile' + Date.now() + '.jpg';
let fileAsset = await mgr.createPhotoAsset(testFileName);
console.info('createPhotoAsset file displayName' + fileAsset.displayName);
console.info('createPhotoAsset successfully');
} catch (err) {
console.error('createPhotoAsset failed, message = ' + err);
}
// Sleep 1s.
if (count == 0) {
console.info('offDemo success');
} else {
console.error('offDemo fail');
}
}
```
## FileAsset ## FileAsset
Provides APIs for encapsulating file asset attributes. Provides APIs for encapsulating file asset attributes.
...@@ -1818,7 +1825,7 @@ Commits the modification on the file metadata to the database. This API uses a p ...@@ -1818,7 +1825,7 @@ Commits the modification on the file metadata to the database. This API uses a p
| ------------------- | ---------- | | ------------------- | ---------- |
| Promise&lt;void&gt; | Promise that returns no value.| | Promise&lt;void&gt; | Promise that returns no value.|
**Example** **Example**
```ts ```ts
import dataSharePredicates from '@ohos.data.dataSharePredicates'; import dataSharePredicates from '@ohos.data.dataSharePredicates';
...@@ -3488,6 +3495,8 @@ async function example() { ...@@ -3488,6 +3495,8 @@ async function example() {
Provides APIs for managing the system albums. Provides APIs for managing the system albums.
This API will be discarded. Use [Album](#album) instead.
### Attributes ### Attributes
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -3506,6 +3515,8 @@ getPhotoAssets(options: FetchOptions, callback: AsyncCallback&lt;FetchResult&lt; ...@@ -3506,6 +3515,8 @@ getPhotoAssets(options: FetchOptions, callback: AsyncCallback&lt;FetchResult&lt;
Obtains image and video assets from a system album. This API uses an asynchronous callback to return the result. Obtains image and video assets from a system album. This API uses an asynchronous callback to return the result.
This API will be deprecated. Use [Album.getPhotoAssets](#getphotoassets-2) instead.
**Required permissions**: ohos.permission.READ_IMAGEVIDEO **Required permissions**: ohos.permission.READ_IMAGEVIDEO
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -3557,6 +3568,8 @@ getPhotoAssets(options: FetchOptions): Promise&lt;FetchResult&lt;FileAsset&gt;&g ...@@ -3557,6 +3568,8 @@ getPhotoAssets(options: FetchOptions): Promise&lt;FetchResult&lt;FileAsset&gt;&g
Obtains image and video assets from a system album. This API uses a promise to return the result. Obtains image and video assets from a system album. This API uses a promise to return the result.
This API will be deprecated. Use [Album.getPhotoAssets](#getphotoassets-3) instead.
**Required permissions**: ohos.permission.READ_IMAGEVIDEO **Required permissions**: ohos.permission.READ_IMAGEVIDEO
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -3607,6 +3620,8 @@ delete(uri: string, callback: AsyncCallback&lt;void&gt;): void; ...@@ -3607,6 +3620,8 @@ delete(uri: string, callback: AsyncCallback&lt;void&gt;): void;
Deletes files from a system album. Deletes files from a system album.
This API will be deprecated. Use [Album.deletePhotoAssets](#deletephotoassets10) instead.
**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO **Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -3651,6 +3666,8 @@ delete(uri: string): Promise&lt;void&gt;; ...@@ -3651,6 +3666,8 @@ delete(uri: string): Promise&lt;void&gt;;
Deletes files from a system album. Deletes files from a system album.
This API will be deprecated. Use [Album.deletePhotoAssets](#deletephotoassets10) instead.
**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO **Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -3689,7 +3706,7 @@ async function example() { ...@@ -3689,7 +3706,7 @@ async function example() {
}).catch((err) => { }).catch((err) => {
console.error('trashAlbum.delete failed, message = ', err); console.error('trashAlbum.delete failed, message = ', err);
}); });
} }
``` ```
### recover ### recover
...@@ -3698,6 +3715,8 @@ recover(uri: string, callback: AsyncCallback&lt;void&gt;): void; ...@@ -3698,6 +3715,8 @@ recover(uri: string, callback: AsyncCallback&lt;void&gt;): void;
Recovers files in a system album. Recovers files in a system album.
This API will be deprecated. Use [Album.recoverPhotoAssets](#recoverphotoassets10) instead.
**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO **Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -3742,6 +3761,8 @@ recover(uri: string): Promise&lt;void&gt;; ...@@ -3742,6 +3761,8 @@ recover(uri: string): Promise&lt;void&gt;;
Recovers files in a system album. Recovers files in a system album.
This API will be deprecated. Use [Album.recoverPhotoAssets](#recoverphotoassets10) instead.
**Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO **Required permissions**: ohos.permission.READ_IMAGEVIDEO, ohos.permission.WRITE_IMAGEVIDEO or ohos.permission.READ_AUDIO, and ohos.permission.WRITE_AUDIO
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
...@@ -3890,6 +3911,8 @@ Enumerate the album subtypes. ...@@ -3890,6 +3911,8 @@ Enumerate the album subtypes.
Enumerates the system album types. Enumerates the system album types.
This API will be deprecated. Use [AlbumType](#albumtype10) and [AlbumSubType](#albumsubtype10) instead.
**System capability**: SystemCapability.FileManagement.UserFileManager.Core **System capability**: SystemCapability.FileManagement.UserFileManager.Core
| Name | Value| Description | | Name | Value| Description |
...@@ -3938,6 +3961,7 @@ Defines the key information about an image or video file. ...@@ -3938,6 +3961,7 @@ Defines the key information about an image or video file.
| POSITION<sup>10+</sup> | position | File location type. | | POSITION<sup>10+</sup> | position | File location type. |
| DATE_TRASHED<sup>10+</sup> | date_trashed | Date when the file was deleted. The value is the number of seconds between the time when the file is deleted and January 1, 1970. | | DATE_TRASHED<sup>10+</sup> | date_trashed | Date when the file was deleted. The value is the number of seconds between the time when the file is deleted and January 1, 1970. |
| HIDDEN<sup>10+</sup> | hidden | Whether the file is hidden. | | HIDDEN<sup>10+</sup> | hidden | Whether the file is hidden. |
| CAMERA_SHOT_KEY<sup>10+</sup> | camera_shot_key | Key for the Untra Snamshot feature, which allows the camera to take photos or record videos with the screen off. (This parameter is available only for the system camera, and the key value is defined by the system camera.) |
## AlbumKey ## AlbumKey
...@@ -3962,6 +3986,7 @@ Options for creating an image or video asset. ...@@ -3962,6 +3986,7 @@ Options for creating an image or video asset.
| Name | Type | Mandatory| Description | | Name | Type | Mandatory| Description |
| ---------------------- | ------------------- | ---- | ------------------------------------------------ | | ---------------------- | ------------------- | ---- | ------------------------------------------------ |
| subType | [PhotoSubType](#photosubtype10) | No | Subtype of the image or video. | | subType | [PhotoSubType](#photosubtype10) | No | Subtype of the image or video. |
| cameraShotKey | string | No | Key for the Untra Snamshot feature, which allows the camera to take photos or record videos with the screen off. (This parameter is available only for the system camera, and the key value is defined by the system camera.) |
## FetchOptions ## FetchOptions
......
...@@ -100,6 +100,18 @@ Allows an application to read telephony information. ...@@ -100,6 +100,18 @@ Allows an application to read telephony information.
**Start version**: 8 **Start version**: 8
## ohos.permission.GET_PHONE_NUMBERS
Allows an application to obtain the phone numbers of the device.
**Permission level**: system_basic
**Authorization mode**: system_grant
**Enable via ACL**: TRUE
**Start version**: 10
## ohos.permission.REQUIRE_FORM ## ohos.permission.REQUIRE_FORM
Allows an application to obtain the Ability Form. Allows an application to obtain the Ability Form.
...@@ -776,7 +788,7 @@ Allows an application to listen for input events. Only the system signed applica ...@@ -776,7 +788,7 @@ Allows an application to listen for input events. Only the system signed applica
## ohos.permission.MANAGE_MISSIONS ## ohos.permission.MANAGE_MISSIONS
Allows an application to manage ability mission stacks. Allows an application to manage missions in the system.
**Permission level**: system_core **Permission level**: system_core
...@@ -860,7 +872,7 @@ Allows an SA to call the network management, Wi-Fi, network adapter listening, a ...@@ -860,7 +872,7 @@ Allows an SA to call the network management, Wi-Fi, network adapter listening, a
## ohos.permission.SET_ABILITY_CONTROLLER ## ohos.permission.SET_ABILITY_CONTROLLER
Allows an application to set the start and stop of an ability. Allows an application to intercept the startup of the Ability component. This permission is used for testing, such as the stability test.
**Permission level**: system_basic **Permission level**: system_basic
...@@ -956,7 +968,7 @@ Allows an application to clear application data. ...@@ -956,7 +968,7 @@ Allows an application to clear application data.
## ohos.permission.RUNNING_STATE_OBSERVER ## ohos.permission.RUNNING_STATE_OBSERVER
Allows an application to observe the application status. Allows an application to listen for its status.
**Permission level**: system_basic **Permission level**: system_basic
...@@ -1004,7 +1016,7 @@ Allows a system application to obtain Wi-Fi parameters. ...@@ -1004,7 +1016,7 @@ Allows a system application to obtain Wi-Fi parameters.
## ohos.permission.SET_WIFI_INFO ## ohos.permission.SET_WIFI_INFO
Allows an application to set Wi-Fi devices. Allows an application to set a Wi-Fi device.
**Permission level**: normal **Permission level**: normal
...@@ -1280,7 +1292,7 @@ Allows a device administrator application to set the screen-off time. ...@@ -1280,7 +1292,7 @@ Allows a device administrator application to set the screen-off time.
## ohos.permission.ENTERPRISE_INSTALL_BUNDLE ## ohos.permission.ENTERPRISE_INSTALL_BUNDLE
Allows a device administrator application to install and uninstall bundles. Allows a device administrator application to install and uninstall applications.
**Permission level**: system_core **Permission level**: system_core
...@@ -1656,7 +1668,7 @@ Allows an application to access geographical locations in the user's media file. ...@@ -1656,7 +1668,7 @@ Allows an application to access geographical locations in the user's media file.
## ohos.permission.CAMERA ## ohos.permission.CAMERA
Allows an application to use the camera to take photos and record videos. Allows an application to use the camera.
**Permission level**: normal **Permission level**: normal
...@@ -2683,3 +2695,39 @@ Allows an application to listen for the card running status. ...@@ -2683,3 +2695,39 @@ Allows an application to listen for the card running status.
**Enable via ACL**: TRUE **Enable via ACL**: TRUE
**Start version**: 10 **Start version**: 10
## ohos.permission.MANAGE_DEVICE_AUTH_CRED
Allows an application to call interfaces of the DeviceAuthCredMgr application.
**Permission level**: system_basic
**Authorization mode**: system_grant
**Enable ACL**: FALSE
**Start version**: 10
## ohos.permission.UNINSTALL_BUNDLE
Allows an application to uninstall applications.
**Permission level**: system_core
**Authorization mode**: system_grant
**Enable via ACL**: TRUE
**Start version**: 10
## ohos.permission.RECOVER_BUNDLE
Allows an application to restore pre-installed applications.
**Permission level**: system_core
**Authorization mode**: system_grant
**Enable via ACL**: TRUE
**Start version**: 10
...@@ -22,8 +22,8 @@ New IP provides at least 1% higher payload transmission efficiency than IPv4 and ...@@ -22,8 +22,8 @@ New IP provides at least 1% higher payload transmission efficiency than IPv4 and
| Scenario | Header Overhead (Bytes) | Payload Transmission Efficiency<br>(Wi-Fi MTU = 1500 Bytes, BT MTU = 255 Bytes)| | Scenario | Header Overhead (Bytes) | Payload Transmission Efficiency<br>(Wi-Fi MTU = 1500 Bytes, BT MTU = 255 Bytes)|
| --------------- | ------------ | ------------------------------------------- | | --------------- | ------------ | ------------------------------------------- |
| IPv4 for Wi-Fi | 30 + 8 + 20 = 58 | (1500 - 58)/1500 = 96.13% | | IPv4 for Wi-Fi | 30 + 8 + 20 = 58 | (1500 - 58)/1500 = 96.13% |
| IPv6 for Wi-Fi | 30 + 8 + 40 = 78 | (1500 - 78)/1500 = 94.8% | | IPv6 for Wi-Fi | 30 + 8 + 40 = 78 | (1500 - 78)/1500 = 94.8% |
| New IP for Wi-Fi | 30 + 8 + 5 = 43 | (1500 - 43)/1500 = 97.13% | | New IP for Wi-Fi | 30 + 8 + 5 = 43 | (1500 - 43)/1500 = 97.13% |
## Variable-Length Header Format ## Variable-Length Header Format
...@@ -97,7 +97,7 @@ Only the Linux 5.10 kernel of the RK3568 development board supports the New IP k ...@@ -97,7 +97,7 @@ Only the Linux 5.10 kernel of the RK3568 development board supports the New IP k
# kernel/linux/config/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig # kernel/linux/config/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig
CONFIG_NEWIP=y // Enable the New IP kernel protocol stack. CONFIG_NEWIP=y // Enable the New IP kernel protocol stack.
CONFIG_NEWIP_HOOKS=y // Enable New IP stub functions to be dynamically registered non-disruptively. This feature must be enabled when New IP is enabled. CONFIG_NEWIP_HOOKS=y // Enable New IP stub functions to be dynamically registered non-disruptively. This feature must be enabled when New IP is enabled.
VENDOR_HOOKS=y // Enable the basic kernel instrumentation framework. New IP depends on this setting. It is enabled by default for the RK3568 development board. HCK_VENDOR_HOOKS=y // Enable the basic kernel instrumentation framework. New IP depends on this framework. It is enabled by default on the RK3568 development board.
``` ```
Run the following command to check whether the New IP protocol stack is successfully enabled: Run the following command to check whether the New IP protocol stack is successfully enabled:
...@@ -119,8 +119,18 @@ out/kernel/OBJ/linux-5.10/net/newip/tcp_nip_output.o ...@@ -119,8 +119,18 @@ out/kernel/OBJ/linux-5.10/net/newip/tcp_nip_output.o
```c ```c
/* Register the New IP ehash function with the kernel. */ /* Register the New IP ehash function with the kernel. */
register_trace_ninet_ehashfn_hook(&ninet_ehashfn_hook, NULL); /* Call the newip hook function in sk_ehashfn function (net\ipv4\inet_hashtables.c):
*/
void nip_ninet_ehashfn(const struct sock *sk, u32 *ret)
{
*ret = ninet_ehashfn(sock_net(sk), &sk->SK_NIP_RCV_SADDR,
sk->sk_num, &sk->SK_NIP_DADDR, sk->sk_dport);
}
void nip_ninet_ehashfn_lhck_register(void)
{
REGISTER_HCK_LITE_HOOK(nip_ninet_ehashfn_lhck, nip_ninet_ehashfn);
}
/* Add the New IP stack processing to the general entry function of IPv4/IPv6 stacks. */ /* Add the New IP stack processing to the general entry function of IPv4/IPv6 stacks. */
static u32 sk_ehashfn(const struct sock *sk) static u32 sk_ehashfn(const struct sock *sk)
...@@ -134,14 +144,12 @@ static u32 sk_ehashfn(const struct sock *sk) ...@@ -134,14 +144,12 @@ static u32 sk_ehashfn(const struct sock *sk)
&sk->sk_v6_daddr, sk->sk_dport); &sk->sk_v6_daddr, sk->sk_dport);
#endif #endif
if (trace_vendor_ninet_ehashfn_enabled()) { if (sk->sk_family == AF_NINET) {
if (sk->sk_family == AF_NINET) { u32 ret = 0;
u32 ret = 0;
/* Register the New IP ehash function. */ /* Register the New IP ehash function. */
trace_vendor_ninet_ehashfn(sk, &ret); CALL_HCK_LITE_HOOK(nip_ninet_ehashfn_lhck, sk, &ret);
return ret; return ret;
}
} }
/* IPv4 */ /* IPv4 */
return inet_ehashfn(sock_net(sk), return inet_ehashfn(sock_net(sk),
...@@ -166,8 +174,8 @@ The user-mode application calls **socket()** to create a New IP socket and uses ...@@ -166,8 +174,8 @@ The user-mode application calls **socket()** to create a New IP socket and uses
| API | Input | Output | Return Value | Description | | API | Input | Output | Return Value | Description |
| -------- | ------------------------------------------------------------ | ---------------------------------------------- | ---------------- | ------------------------------------------------------------ | | -------- | ------------------------------------------------------------ | ---------------------------------------------- | ---------------- | ------------------------------------------------------------ |
| socket | int **domain**, int type, int **protocol** | NA | Socket handle **sockfd**.| Creates a New IP socket. <br>**domain** must be **AF_NINET**, which indicates a New IP socket.<br>**protocol** can be **IPPROTO_TCP** or **IPPROTO_UDP**.<br>This API returns the handle of the **socket** instance created.| | socket | int **domain**, int type, int **protocol** | NA | Socket handle **sockfd**.| Creates a New IP socket. <br>**domain** must be **AF_NINET**, which indicates a New IP socket.<br>**protocol** can be **IPPROTO_TCP** or **IPPROTO_UDP**.<br>This API returns the handle of the **socket** instance created. |
| bind | int sockfd, const **struct sockaddr_nin** *myaddr, socklen_t addrlen | NA | Error code, which is an integer. | Binds the **socket** instance to the specified IP address and port.<br> **myaddr->sin_family** must be **AF_NINET**.| | bind | int sockfd, const **struct sockaddr_nin** *myaddr, socklen_t addrlen | NA | Error code, which is an integer. | Binds the **socket** instance to the specified IP address and port.<br>**myaddr->sin_family** must be **AF_NINET**. |
| listen | int socket, int backlog | NA | Error code, which is an integer. | Listens for the New IP address and port from the server. | | listen | int socket, int backlog | NA | Error code, which is an integer. | Listens for the New IP address and port from the server. |
| connect | int sockfd, const **struct sockaddr_nin** *addr, aocklen_t addrlen | NA | Error code, which is an integer. | Sets up a connection between the client and the server. | | connect | int sockfd, const **struct sockaddr_nin** *addr, aocklen_t addrlen | NA | Error code, which is an integer. | Sets up a connection between the client and the server. |
| accept | int sockfd, **struct sockaddr_nin** *address, socklen_t *address_len | NA | **sockfd**. | Accepts the connection request from the client. | | accept | int sockfd, **struct sockaddr_nin** *address, socklen_t *address_len | NA | **sockfd**. | Accepts the connection request from the client. |
......
...@@ -441,3 +441,9 @@ export default class MySequenceable { ...@@ -441,3 +441,9 @@ export default class MySequenceable {
private str; private str;
} }
``` ```
## 相关实例
针对IDL的使用,有以下相关实例可供参考:
- [Ability与ServiceExtensionAbility通信(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/IDL/AbilityConnectServiceExtension)
\ No newline at end of file
...@@ -138,5 +138,4 @@ onAccessibilityEvent(accessibilityEvent) { ...@@ -138,5 +138,4 @@ onAccessibilityEvent(accessibilityEvent) {
针对AccessibilityExtensionAbility开发,有以下相关实例可供参考: 针对AccessibilityExtensionAbility开发,有以下相关实例可供参考:
[AccessibilityExtAbility的创建和使用(ArkTS)(API 9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/AccessibilityExtAbility) - [无障碍扩展(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/AccessibilityExtAbility)
...@@ -219,3 +219,9 @@ ...@@ -219,3 +219,9 @@
## 数据提供方开发步骤 ## 数据提供方开发步骤
参考[数据管理](../database/share-data-by-silent-access.md)开发指南。 参考[数据管理](../database/share-data-by-silent-access.md)开发指南。
## 相关实例
针对卡片代理开发,有以下相关实例可供参考:
- [应用主动添加数据代理卡片到桌面(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/RequestAddForm)
\ No newline at end of file
...@@ -60,3 +60,11 @@ ArkTS卡片相较于JS卡片具备了更加丰富的能力,但也增加了使 ...@@ -60,3 +60,11 @@ ArkTS卡片相较于JS卡片具备了更加丰富的能力,但也增加了使
- 暂不支持Hot Reload热重载。 - 暂不支持Hot Reload热重载。
- 暂不支持setTimeOut。 - 暂不支持setTimeOut。
## 相关实例
针对ArkTS卡片开发,有以下相关实例可供参考:
- [Stage模型卡片(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/FormExtAbility)
- [Stage模型卡片JS与C++通信(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/FormGame)
\ No newline at end of file
...@@ -118,5 +118,5 @@ ...@@ -118,5 +118,5 @@
针对StaticSubscriberExtensionAbility开发,可参考如下实例: 针对StaticSubscriberExtensionAbility开发,可参考如下实例:
- [StaticSubscriber:静态订阅(ArkTS)(API9)(Full SDK](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/StaticSubscriber) - [静态订阅(ArkTS)(Full SDK)(API10](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/StaticSubscriber)
...@@ -103,11 +103,8 @@ export default class EnterpriseAdminAbility extends EnterpriseAdminExtensionAbil ...@@ -103,11 +103,8 @@ export default class EnterpriseAdminAbility extends EnterpriseAdminExtensionAbil
} }
``` ```
## 相关实例 ## 相关实例
针对EnterpriseAdminExtensionAbility开发,有以下相关示例可供参考: 针对EnterpriseAdminExtensionAbility开发,有以下相关示例可供参考:
[EnterpriseAdminExtensionAbility:EnterpriseAdminExtensionAbility的创建与使用(ArkTS) (API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/EnterpriseAdminExtensionAbility) - [企业设备管理扩展(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/EnterpriseAdminExtensionAbility)
...@@ -616,6 +616,8 @@ onUpdateForm(formId) { ...@@ -616,6 +616,8 @@ onUpdateForm(formId) {
针对卡片开发,有以下相关实例可供参考: 针对卡片开发,有以下相关实例可供参考:
- [JS多设备自适应服务卡片(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/AdaptiveServiceWidget)
- [电影卡片(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Card/MovieCard) - [电影卡片(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Card/MovieCard)
- [计步器卡片(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Card/StepsCardJS) - [计步器卡片(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Card/StepsCardJS)
\ No newline at end of file
...@@ -126,4 +126,8 @@ ...@@ -126,4 +126,8 @@
}) })
``` ```
## 相关实例
针对任务管理开发,有以下相关实例可供参考:
- [任务管理(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/MissionManager)
...@@ -60,11 +60,12 @@ ArkTS卡片与JS卡片具备不同的实现原理及特征,在场景能力上 ...@@ -60,11 +60,12 @@ ArkTS卡片与JS卡片具备不同的实现原理及特征,在场景能力上
针对Stage模型卡片提供方的开发,有以下相关实例可供参考: 针对Stage模型卡片提供方的开发,有以下相关实例可供参考:
- [ArkTS音乐卡片(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/ArkTSCard/MusicControl)
- [基于Stage模型的JS卡片(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/FormExtAbility) - [Stage模型卡片(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/FormExtAbility)
- [基于Stage模型的JS卡片(成语接龙小游戏)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/FormGame) - [Stage模型卡片JS与C++通信(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/FormGame)
- [基于Stage模型的ArkTS卡片(Canvas绘制实现的五子棋游戏卡片)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/ArkTSCard/CanvasGame) - [ArkTS卡片Canvas小游戏(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/ArkTSCard/CanvasGame)
- [基于Stage模型的ArkTS卡片(逻辑代码执行实现的计算器卡片)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/ArkTSCard/Calculator) - [ArkTS卡片计算器(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/Widget/ArkTSCard/Calculator)
...@@ -453,5 +453,8 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap ...@@ -453,5 +453,8 @@ ServiceExtensionAbility服务组件在[onConnect()](../reference/apis/js-apis-ap
针对ServiceExtensionAbility开发,有以下相关实例可供参考: 针对ServiceExtensionAbility开发,有以下相关实例可供参考:
- [`AbilityConnectServiceExtension`:Ability与ServiceExtensionAbility通信(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/IDL/AbilityConnectServiceExtension) - [跨任务链返回(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/ApplicationModels/TestRely/LauncherTest/CrossChainBack)
- [`StageModel`:Stage模型(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/ApplicationModels/StageModel)
- [Ability与ServiceExtensionAbility通信(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/IDL/AbilityConnectServiceExtension)
- [Stage模型(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/ApplicationModels/StageModel)
...@@ -41,3 +41,9 @@ ...@@ -41,3 +41,9 @@
| 了解线程模型 | 本章节介绍了Stage模型的线程模型以及几种常用的线程间通信方式。 | -&nbsp;[Emitter](itc-with-emitter.md)<br/>-&nbsp;[Worker](itc-with-worker.md) | | 了解线程模型 | 本章节介绍了Stage模型的线程模型以及几种常用的线程间通信方式。 | -&nbsp;[Emitter](itc-with-emitter.md)<br/>-&nbsp;[Worker](itc-with-worker.md) |
| 任务管理 | 本章节介绍了Stage模型中任务管理的基本概念和典型场景。 | -&nbsp;[任务管理场景介绍](mission-management-overview.md)<br/>-&nbsp;[任务管理与启动模式](mission-management-launch-type.md)<br/>-&nbsp;[页面栈和任务链](page-mission-stack.md) | | 任务管理 | 本章节介绍了Stage模型中任务管理的基本概念和典型场景。 | -&nbsp;[任务管理场景介绍](mission-management-overview.md)<br/>-&nbsp;[任务管理与启动模式](mission-management-launch-type.md)<br/>-&nbsp;[页面栈和任务链](page-mission-stack.md) |
| 应用配置文件 | 本章节介绍Stage模型中应用配置文件的开发要求。 | [Stage模型应用配置文件](config-file-stage.md) | | 应用配置文件 | 本章节介绍Stage模型中应用配置文件的开发要求。 | [Stage模型应用配置文件](config-file-stage.md) |
## 相关实例
针对Stage模型开发,有以下相关实例可供参考:
- [Stage模型(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/ApplicationModels/StageModel)
\ No newline at end of file
...@@ -151,3 +151,9 @@ specified启动模式为指定实例模式,针对一些特殊场景使用( ...@@ -151,3 +151,9 @@ specified启动模式为指定实例模式,针对一些特殊场景使用(
2. 在最近任务列表中关闭`文件A`的任务进程,此时`UIAbility实例1`被销毁,回到桌面,再次打开`文件A`,此时对应启动一个新的UIAbility实例,例如启动`UIAbility实例2` 2. 在最近任务列表中关闭`文件A`的任务进程,此时`UIAbility实例1`被销毁,回到桌面,再次打开`文件A`,此时对应启动一个新的UIAbility实例,例如启动`UIAbility实例2`
3. 回到桌面,打开`文件B`,此时对应启动一个新的UIAbility实例,例如启动`UIAbility实例3` 3. 回到桌面,打开`文件B`,此时对应启动一个新的UIAbility实例,例如启动`UIAbility实例3`
4. 回到桌面,再次打开`文件A`,此时仍然启动之前的`UIAbility实例2`,因为系统会自动匹配UIAbility实例的Key值,如果存在与之匹配的Key,则会启动与之绑定的UIAbility实例。在此例中,之前启动的`UIAbility实例2``文件A`绑定的Key是相同的,因此系统会拉回`UIAbility实例2`并让其获焦,而不会创建新的实例。 4. 回到桌面,再次打开`文件A`,此时仍然启动之前的`UIAbility实例2`,因为系统会自动匹配UIAbility实例的Key值,如果存在与之匹配的Key,则会启动与之绑定的UIAbility实例。在此例中,之前启动的`UIAbility实例2``文件A`绑定的Key是相同的,因此系统会拉回`UIAbility实例2`并让其获焦,而不会创建新的实例。
## 相关实例
针对UIAbility组件启动模式,有以下相关实例可供参考:
- [Ability的启动模式(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/ApplicationModels/AbilityStartMode)
\ No newline at end of file
...@@ -116,4 +116,4 @@ struct Index { ...@@ -116,4 +116,4 @@ struct Index {
针对WindowExtensionAbility开发,有以下相关实例可供参考: 针对WindowExtensionAbility开发,有以下相关实例可供参考:
- [`WindowExtAbility`:WindowExtAbility的创建与使用(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/WindowManagement/WindowExtAbility) - [窗口扩展应用(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/WindowManagement/WindowExtAbility)
...@@ -36,4 +36,4 @@ ArkTS语言基础类库是OpenHarmony系统上为应用开发者提供的常用 ...@@ -36,4 +36,4 @@ ArkTS语言基础类库是OpenHarmony系统上为应用开发者提供的常用
针对语言基础类库的开发,有以下相关实例可供参考: 针对语言基础类库的开发,有以下相关实例可供参考:
- [LanguageBaseClassLibrary:语言基础类库](https://gitee.com/openharmony/applications_app_samples/tree/master/code/LaunguageBaseClassLibrary/LanguageBaseClassLibrary) - [语言基础类库(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/LaunguageBaseClassLibrary/LanguageBaseClassLibrary)
...@@ -57,4 +57,4 @@ ArkTS提供了TaskPool和Worker两种并发能力供开发者选择,其具体 ...@@ -57,4 +57,4 @@ ArkTS提供了TaskPool和Worker两种并发能力供开发者选择,其具体
针对多线程开发,有以下相关实例可供参考: 针对多线程开发,有以下相关实例可供参考:
- [ConcurrentModule:多线程任务](https://gitee.com/openharmony/applications_app_samples/tree/master/code/LaunguageBaseClassLibrary/ConcurrentModule) - [多线程任务(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/LaunguageBaseClassLibrary/ConcurrentModule)
...@@ -166,5 +166,8 @@ httpRequest.requestInStream( ...@@ -166,5 +166,8 @@ httpRequest.requestInStream(
针对HTTP数据请求,有以下相关实例可供参考: 针对HTTP数据请求,有以下相关实例可供参考:
- [`Http:`数据请求(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/Http) - [上传和下载(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Connectivity/Upload)
- [Http(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/Http)
- [新闻数据加载(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/NetworkManagement/NewsDataArkTS) - [新闻数据加载(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/NetworkManagement/NewsDataArkTS)
\ No newline at end of file
...@@ -355,3 +355,8 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信, ...@@ -355,3 +355,8 @@ IPC/RPC的主要工作是让运行在不同进程的Proxy和Stub互相通信,
globalThis.context.disconnectServiceExtensionAbility(connectId); globalThis.context.disconnectServiceExtensionAbility(connectId);
``` ```
## 相关实例
针对IPC与RPC通信开发,有以下相关实例可供参考:
- [RPC通信(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/RPC)
...@@ -409,4 +409,4 @@ tlsTwoWay.close((err) => { ...@@ -409,4 +409,4 @@ tlsTwoWay.close((err) => {
针对Socket连接开发,有以下相关实例可供参考: 针对Socket连接开发,有以下相关实例可供参考:
- [`Socket`:Socket 连接(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/Socket) - [网络管理-Socket连接(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/Socket)
\ No newline at end of file \ No newline at end of file
...@@ -85,4 +85,4 @@ ws.connect(defaultIpAddress, (err, value) => { ...@@ -85,4 +85,4 @@ ws.connect(defaultIpAddress, (err, value) => {
针对WebSocket连接的开发,有以下相关实例可供参考: 针对WebSocket连接的开发,有以下相关实例可供参考:
- [`WebSocket`:WebSocket(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/WebSocket) - [WebSocket(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/WebSocket)
\ No newline at end of file \ No newline at end of file
...@@ -226,7 +226,11 @@ ...@@ -226,7 +226,11 @@
针对用户首选项开发,有以下相关实例可供参考: 针对用户首选项开发,有以下相关实例可供参考:
- [`Preferences`:首选项(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DataManagement/Preferences) - [游戏2048(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Game/Game2048)
- [图案密码锁(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Tools/PatternLock)
- [首选项(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DataManagement/Preferences)
- [首选项(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Data/Preferences) - [首选项(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Data/Preferences)
......
...@@ -304,4 +304,12 @@ ...@@ -304,4 +304,12 @@
localObject.setSessionId(() => { localObject.setSessionId(() => {
console.info('leave all lession.'); console.info('leave all lession.');
}); });
``` ```
\ No newline at end of file
## 相关实例
针对分布式数据对象开发,有以下相关实例可供参考:
- [分布式组网认证(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedAuthentication)
- [分布式对象(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedNote)
\ No newline at end of file
...@@ -281,4 +281,18 @@ ...@@ -281,4 +281,18 @@
针对键值型数据库开发,有以下相关实例可供参考: 针对键值型数据库开发,有以下相关实例可供参考:
- [分布式组网认证(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedAuthentication)
- [分布式数据管理(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/Kvstore)
- [分布式音乐播放(JS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/JsDistributedMusicPlayer)
- [分布式音乐播放(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/ArkTSDistributedMusicPlayer)
- [分布式计算器(JS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributeCalc)
- [分布式计算器(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/ArkTSDistributedCalc)
- [分布式五子棋(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Game/DistributedDataGobang)
- [分布式手写板(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/codelabs/tree/master/Distributed/DistributeDraw) - [分布式手写板(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/codelabs/tree/master/Distributed/DistributeDraw)
\ No newline at end of file
...@@ -171,3 +171,13 @@ ...@@ -171,3 +171,13 @@
) )
}) })
``` ```
## 相关实例
针对关系型数据库开发,有以下相关实例可供参考:
- [分布式组网认证(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedAuthentication)
-[分布式关系型数据库(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedRdb)
- [分布式帐号(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedAccount)
\ No newline at end of file
...@@ -243,4 +243,4 @@ ...@@ -243,4 +243,4 @@
针对数据共享开发,有以下相关实例可供参考: 针对数据共享开发,有以下相关实例可供参考:
- [`CrossAppDataShare`:系统应用跨应用数据共享(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/DataManagement/CrossAppDataShare) - [系统应用跨应用数据共享(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/DataManagement/CrossAppDataShare)
\ No newline at end of file \ No newline at end of file
...@@ -37,3 +37,9 @@ ...@@ -37,3 +37,9 @@
## 跨设备同步访问控制机制 ## 跨设备同步访问控制机制
数据跨设备同步时,数据管理基于设备等级和数据安全标签进行访问控制,具体可见[跨设备同步访问控制机制](access-control-by-device-and-data-level.md#跨设备同步访问控制机制) 数据跨设备同步时,数据管理基于设备等级和数据安全标签进行访问控制,具体可见[跨设备同步访问控制机制](access-control-by-device-and-data-level.md#跨设备同步访问控制机制)
## 相关实例
针对分布式开发,有以下相关实例可供参考:
- [分布式组网认证(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedAuthentication)
\ No newline at end of file
...@@ -538,5 +538,8 @@ import usageStatistics from '@ohos.resourceschedule.usageStatistics'; ...@@ -538,5 +538,8 @@ import usageStatistics from '@ohos.resourceschedule.usageStatistics';
针对设备使用信息统计,有以下相关实例可供参考: 针对设备使用信息统计,有以下相关实例可供参考:
- [`DeviceUsageStatistics`:设备使用信息统计(ArkTS)(API9)(Full SDK)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceUsageStatistics/DeviceUsageStatistics) - [存储空间统计(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/DeviceManagement/StorageStatistic)
- [设备使用信息统计(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceUsageStatistics/DeviceUsageStatistics)
...@@ -406,4 +406,10 @@ ...@@ -406,4 +406,10 @@
}); });
``` ```
5. 当设备进入或者退出该围栏时,系统会自动触发WantAgent的动作。 5. 当设备进入或者退出该围栏时,系统会自动触发WantAgent的动作。
\ No newline at end of file
## 相关实例
针对位置开发,有以下相关实例可供参考:
- [位置服务(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Location)
\ No newline at end of file
...@@ -270,5 +270,6 @@ async function playCustomHaptic(fileName) { ...@@ -270,5 +270,6 @@ async function playCustomHaptic(fileName) {
针对振动开发,有以下相关实例可供参考: 针对振动开发,有以下相关实例可供参考:
- [`Vibrator`:振动(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/BasicVibration) - [振动(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/BasicVibration)
- [`CustomHaptic`:自定义振动(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/CustomHaptic)
- [自定义振动(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DeviceManagement/Vibrator/CustomHaptic)
...@@ -193,3 +193,9 @@ APP_LIFECYCLE_TIMEOUT: ...@@ -193,3 +193,9 @@ APP_LIFECYCLE_TIMEOUT:
![appfreeze_20230310105874](figures/appfreeze_20230310105874.png) ![appfreeze_20230310105874](figures/appfreeze_20230310105874.png)
其他的日志信息可以参考[通用日志信息](#日志主干通用信息)进行分析。需要特别说明的是,一般情况下生命周期切换大概率主线程也会卡死。可以结合两个日志的三个堆栈、两个BinderCatcher信息,进行对比查看。 其他的日志信息可以参考[通用日志信息](#日志主干通用信息)进行分析。需要特别说明的是,一般情况下生命周期切换大概率主线程也会卡死。可以结合两个日志的三个堆栈、两个BinderCatcher信息,进行对比查看。
## 相关实例
针对故障日志获取,有以下相关实力可供参考:
- [故障日志获取(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DFX/FaultLogger)
\ No newline at end of file
...@@ -105,3 +105,9 @@ Thread name:crasher <- 异常线程名 ...@@ -105,3 +105,9 @@ Thread name:crasher <- 异常线程名
范例中的崩溃故障是由赋值给一块不可写的区域导致的,代码行为dfx_crasher.c文件的57行,修改后可以避免发生此崩溃。\ 范例中的崩溃故障是由赋值给一块不可写的区域导致的,代码行为dfx_crasher.c文件的57行,修改后可以避免发生此崩溃。\
另外,使用addr2line后,如果得出的行号看起来不是很正确,可以考虑对地址进行微调(如减1),或者考虑关闭一些编译优化,已知使用LTO的二进制可能无法正确获得行号。 另外,使用addr2line后,如果得出的行号看起来不是很正确,可以考虑对地址进行微调(如减1),或者考虑关闭一些编译优化,已知使用LTO的二进制可能无法正确获得行号。
## 相关实例
针对故障日志获取,有以下相关实力可供参考:
- [故障日志获取(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DFX/FaultLogger)
\ No newline at end of file
...@@ -151,4 +151,6 @@ HiAppEvent是在系统层面为应用开发者提供的一种事件打点机制 ...@@ -151,4 +151,6 @@ HiAppEvent是在系统层面为应用开发者提供的一种事件打点机制
针对应用事件开发,有以下相关实例可供参考: 针对应用事件开发,有以下相关实例可供参考:
- [`DotTest`:测试打点(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DFX/DotTest) - [测试打点(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DFX/DotTest)
\ No newline at end of file
- [日志打印(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/DFX/Logger)
\ No newline at end of file
...@@ -78,3 +78,9 @@ BackupExtensionAbility,是[Stage模型](../../application-dev/application-mode ...@@ -78,3 +78,9 @@ BackupExtensionAbility,是[Stage模型](../../application-dev/application-mode
] ]
} }
``` ```
## 相关实例
针对应用接入数据的备份与恢复,有以下相关实例可供参考:
- [应用接入数据备份恢复(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/FileManagement/FileBackupExtension)
\ No newline at end of file
...@@ -23,3 +23,9 @@ ...@@ -23,3 +23,9 @@
**图1** 文件分类模型示意图 **图1** 文件分类模型示意图
![File classification model](figures/file-classification-model.png) ![File classification model](figures/file-classification-model.png)
## 相关实例
针对文件管理开发,有以下相关实例可供参考:
- [文件管理(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/FileManagement/FileManager)
\ No newline at end of file
...@@ -731,4 +731,12 @@ try { ...@@ -731,4 +731,12 @@ try {
```js ```js
let order = I18n.I18NUtil.getDateOrder("zh-CN"); // order = "y-L-d",表示中文中年月日的顺序为年-月-日。 let order = I18n.I18NUtil.getDateOrder("zh-CN"); // order = "y-L-d",表示中文中年月日的顺序为年-月-日。
``` ```
\ No newline at end of file
## 相关实例
针对I18n开发,有以下相关实例可供参考:
- [时区和语言设置(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Internationalnation/International)
- [国际化(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/International/International)
\ No newline at end of file
...@@ -272,7 +272,7 @@ export default struct Home { ...@@ -272,7 +272,7 @@ export default struct Home {
针对应用市场应用开发,有以下相关实例可以参考: 针对应用市场应用开发,有以下相关实例可以参考:
应用市场开发:[一多应用市场首页应用示例](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/AppMarket) - 应用市场开发:[典型页面场景:应用市场首页(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/AppMarket)
......
...@@ -247,5 +247,5 @@ struct Index { ...@@ -247,5 +247,5 @@ struct Index {
针对音乐专辑应用,有以下相关实例可供参考: 针对音乐专辑应用,有以下相关实例可供参考:
音乐专辑应用:[音乐专辑页应用示例](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/MusicAlbum) - [典型页面场景:音乐专辑页(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/MusicAlbum)
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
| [应用市场首页](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/AppMarket) | 声明式开发范式 | 本章配套的示例代码,以应用市场首页为例,演示如何使用一多能力适配多设备(或多窗口尺寸)。 | | [应用市场首页](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/AppMarket) | 声明式开发范式 | 本章配套的示例代码,以应用市场首页为例,演示如何使用一多能力适配多设备(或多窗口尺寸)。 |
| [音乐专辑页](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/MusicAlbum) | 声明式开发范式 | 本章配套的示例代码,以音乐专辑页为例,演示如何使用一多能力适配多设备(或多窗口尺寸)。 | | [音乐专辑页](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/MusicAlbum) | 声明式开发范式 | 本章配套的示例代码,以音乐专辑页为例,演示如何使用一多能力适配多设备(或多窗口尺寸)。 |
| [设置应用页面](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/Settings) | 声明式开发范式 | 本章配套的示例代码,以设置应用页面为例,演示如何使用一多能力适配多设备(或多窗口尺寸)。 | | [设置应用页面](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/Settings) | 声明式开发范式 | 本章配套的示例代码,以设置应用页面为例,演示如何使用一多能力适配多设备(或多窗口尺寸)。 |
| [分栏控件](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/MultiColumns) | 声明式开发范式 | 本示例分别展示了多场景下,一多分栏控件的响应式变化效果。 |
| [音乐专辑页](https://gitee.com/openharmony/codelabs/tree/master/ExcellentCase/MultiDeviceMusic) | 声明式开发范式 | 基于自适应和响应式布局,实现一次开发、多端部署音乐专辑页面。 | | [音乐专辑页](https://gitee.com/openharmony/codelabs/tree/master/ExcellentCase/MultiDeviceMusic) | 声明式开发范式 | 基于自适应和响应式布局,实现一次开发、多端部署音乐专辑页面。 |
| [视频应用](https://gitee.com/openharmony/codelabs/tree/master/ExcellentCase/Multi_device_V2) | 声明式开发范式 | 基于自适应布局和响应式布局能力,实现了常见的视频播放应用的主界面。 | | [视频应用](https://gitee.com/openharmony/codelabs/tree/master/ExcellentCase/Multi_device_V2) | 声明式开发范式 | 基于自适应布局和响应式布局能力,实现了常见的视频播放应用的主界面。 |
...@@ -168,4 +168,4 @@ Navigation组件支持自动切换单栏和双栏的显示效果,同时可以 ...@@ -168,4 +168,4 @@ Navigation组件支持自动切换单栏和双栏的显示效果,同时可以
针对“设置”应用页面,有以下相关实例可以参考: 针对“设置”应用页面,有以下相关实例可以参考:
设置:[设置应用示例](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/Settings) - [典型页面场景:设置应用页面(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/Settings)
...@@ -257,3 +257,9 @@ export default class VoiceCallDemoForAudioCapturer { ...@@ -257,3 +257,9 @@ export default class VoiceCallDemoForAudioCapturer {
} }
} }
``` ```
## 相关实例
针对音频通话开发,有以下相关实例可供参考:
- [音频通话示例(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/VoiceCallDemo)
\ No newline at end of file
...@@ -63,3 +63,11 @@ audio模块下的接口支持PCM编码,包括AudioRenderer、AudioCapturer、T ...@@ -63,3 +63,11 @@ audio模块下的接口支持PCM编码,包括AudioRenderer、AudioCapturer、T
小尾数指的是小端模式,即数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。这种存储模式将地址的高低和数据的位权有效结合起来,高地址部分权值高,低地址部分权值低。 小尾数指的是小端模式,即数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。这种存储模式将地址的高低和数据的位权有效结合起来,高地址部分权值高,低地址部分权值低。
media模块下的接口支持的音视频格式将在[AVPlayer和AVRecorder](avplayer-avrecorder-overview.md)的介绍中承载。 media模块下的接口支持的音视频格式将在[AVPlayer和AVRecorder](avplayer-avrecorder-overview.md)的介绍中承载。
## 相关实例
针对音视频开发,有以下相关实例可供参考:
- [音视频录制(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/AVRecorder)
- [音频管理(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/Audio)
\ No newline at end of file
...@@ -25,3 +25,9 @@ ...@@ -25,3 +25,9 @@
相机应用通过控制相机,实现图像显示(预览)、照片保存(拍照)、视频录制(录像)等基础操作。在实现基本操作过程中,相机服务会控制相机设备采集和输出数据,采集的图像数据在相机底层的设备硬件接口(HDI,Hardware Device Interfaces),直接通过BufferQueue传递到具体的功能模块进行处理。BufferQueue在应用开发中无需关注,用于将底层处理的数据及时送到上层进行图像显示。 相机应用通过控制相机,实现图像显示(预览)、照片保存(拍照)、视频录制(录像)等基础操作。在实现基本操作过程中,相机服务会控制相机设备采集和输出数据,采集的图像数据在相机底层的设备硬件接口(HDI,Hardware Device Interfaces),直接通过BufferQueue传递到具体的功能模块进行处理。BufferQueue在应用开发中无需关注,用于将底层处理的数据及时送到上层进行图像显示。
以视频录制为例进行说明,相机应用在录制视频过程中,媒体录制服务先创建一个视频Surface用于传递数据,并提供给相机服务,相机服务可控制相机设备采集视频数据,生成视频流。采集的数据通过底层相机HDI处理后,通过Surface将视频流传递给媒体录制服务,媒体录制服务对视频数据进行处理后,保存为视频文件,完成视频录制。 以视频录制为例进行说明,相机应用在录制视频过程中,媒体录制服务先创建一个视频Surface用于传递数据,并提供给相机服务,相机服务可控制相机设备采集视频数据,生成视频流。采集的数据通过底层相机HDI处理后,通过Surface将视频流传递给媒体录制服务,媒体录制服务对视频数据进行处理后,保存为视频文件,完成视频录制。
## 相关实例
针对相机开发,有以下相关实例可供参考:
- [相机和媒体库(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Media/Camera)
...@@ -36,3 +36,13 @@ ...@@ -36,3 +36,13 @@
5. [图片编码](image-encoding.md):使用图片打包器类ImagePacker,将PixelMap或ImageSource进行压缩编码,生成一张新的图片。 5. [图片编码](image-encoding.md):使用图片打包器类ImagePacker,将PixelMap或ImageSource进行压缩编码,生成一张新的图片。
除上述基本图片开发能力外,OpenHarmony还提供常用[图片工具](image-tool.md),供开发者选择使用。 除上述基本图片开发能力外,OpenHarmony还提供常用[图片工具](image-tool.md),供开发者选择使用。
## 相关实例
针对图片开发,有以下相关实例可供参考:
- [图片显示及处理(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/Image)
- [图片显示(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/ImageShow)
- [图片裁剪与分割(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/GamePuzzle)
\ No newline at end of file
...@@ -17,3 +17,13 @@ ...@@ -17,3 +17,13 @@
- 相机(camera):提供精确控制相机镜头,采集视觉信息的接口与服务。 - 相机(camera):提供精确控制相机镜头,采集视觉信息的接口与服务。
- 图片(image):提供图片编解码、图片处理接口与服务。 - 图片(image):提供图片编解码、图片处理接口与服务。
## 相关实例
针对媒体开发,有以下相关实例可供参考:
- [媒体管理合集(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/FileManagement/MediaCollections)
- [相机和媒体库(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Media/MultiMedia)
- [二维码扫描(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/QRCodeScan)
\ No newline at end of file
...@@ -331,3 +331,9 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频 ...@@ -331,3 +331,9 @@ OpenHarmony系统预置的播控中心,作为媒体会话控制方与音视频
}); });
} }
``` ```
## 相关实例
针对媒体会话控制方开发,有以下相关实例可供参考:
- [媒体会话——控制方(仅对系统应用开放)(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/AVSession/MediaController)
\ No newline at end of file
...@@ -357,3 +357,9 @@ ...@@ -357,3 +357,9 @@
}); });
} }
``` ```
## 相关实例
针对媒体会话提供方开发,有以下相关实例可供参考:
- [媒体会话——提供方(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/AVSession/MediaProvider)
\ No newline at end of file
...@@ -264,4 +264,6 @@ export class AVPlayerDemo { ...@@ -264,4 +264,6 @@ export class AVPlayerDemo {
针对视频播放,有以下相关实例可供参考: 针对视频播放,有以下相关实例可供参考:
- [`VideoPlayer`:视频播放器(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/VideoPlayer) - [视频播放(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/VideoPlay)
\ No newline at end of file
- [视频播放器(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/VideoPlayer)
\ No newline at end of file
...@@ -380,5 +380,7 @@ ...@@ -380,5 +380,7 @@
``` ```
## 相关实例 ## 相关实例
- [`NdkRawfile`:获取Rawfile资源](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Native/NdkRawfile)
针对资源管理Rawfile开发,有以下相关实例可供参考:
- [获取Rawfile资源(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Native/NdkRawfile)
...@@ -899,4 +899,4 @@ XComponent({ id: 'xcomponentId1', type: 'surface', libraryname: 'nativerender' } ...@@ -899,4 +899,4 @@ XComponent({ id: 'xcomponentId1', type: 'surface', libraryname: 'nativerender' }
针对Native XComponent的使用,有以下相关实例可供参考: 针对Native XComponent的使用,有以下相关实例可供参考:
- [使用Native XComponent接口绘制图形](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Native/NdkXComponent) - [Native XComponent(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Native/NdkXComponent)
...@@ -31,4 +31,12 @@ OpenHarmony通过ANS(Advanced Notification Service,通知系统服务)对 ...@@ -31,4 +31,12 @@ OpenHarmony通过ANS(Advanced Notification Service,通知系统服务)对
基于通知的开发,有以下相关实例可供参考: 基于通知的开发,有以下相关实例可供参考:
- [`CustomNotification`:自定义通知(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Notification/CustomNotification) - [公共事件的订阅和发布(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Notification/CustomCommonEvent)
\ No newline at end of file
- [自定义通知推送(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Notification/CustomNotificationPush)
- [自定义通知角标(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Notification/CustomNotificationBadge)
- [自定义通知(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Notification/CustomNotification)
- [自定义Emitter(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Notification/CustomEmitter)
\ No newline at end of file
...@@ -132,4 +132,6 @@ $$运算符:给内置组件提供TS变量的引用,使得TS变量和内置 ...@@ -132,4 +132,6 @@ $$运算符:给内置组件提供TS变量的引用,使得TS变量和内置
针对页面状态管理,有以下相关实例可供参考: 针对页面状态管理,有以下相关实例可供参考:
- [状态管理(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/StateManagement)
- [目标管理(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/TargetManagement) - [目标管理(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/TargetManagement)
\ No newline at end of file
...@@ -5,4 +5,10 @@ ...@@ -5,4 +5,10 @@
- 方便开发者将多HAP合理地组合并部署到不同的设备上。例如应用程序包含一个Entry包和两个Featrue包(Feature1和Feature2)。其中Entry包可以部署到设备A和设备B,Feature1只能部署到设备A,Feature2包只部署到设备B上,那么开发者就可以方便的组合Entry和Feature1部署到设备A上,组合Entry和Feature2部署到设备B上。 - 方便开发者将多HAP合理地组合并部署到不同的设备上。例如应用程序包含一个Entry包和两个Featrue包(Feature1和Feature2)。其中Entry包可以部署到设备A和设备B,Feature1只能部署到设备A,Feature2包只部署到设备B上,那么开发者就可以方便的组合Entry和Feature1部署到设备A上,组合Entry和Feature2部署到设备B上。
- 方便开发者按需加载所需模块,减少包大小。开发者可以将一个应用的某些HAP配置成按需加载。应用在启动阶段初始用不到的特性,可以配置暂不加载,当用户用到这些特性的时候,可由应用自动下载这些特性HAP,一定程度上减少应用包的大小。 - 方便开发者按需加载所需模块,减少包大小。开发者可以将一个应用的某些HAP配置成按需加载。应用在启动阶段初始用不到的特性,可以配置暂不加载,当用户用到这些特性的时候,可由应用自动下载这些特性HAP,一定程度上减少应用包的大小。
\ No newline at end of file
## 相关实例
针对多HAP开发,有以下相关实例可供参考:
- [多HAP(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Project/ApplicationHap/MultiHap)
\ No newline at end of file
...@@ -317,4 +317,4 @@ Image($r('sys.media.ohos_app_icon')) ...@@ -317,4 +317,4 @@ Image($r('sys.media.ohos_app_icon'))
针对访问应用资源,有以下相关实例可供参考: 针对访问应用资源,有以下相关实例可供参考:
- [`ResourceManager`:资源管理器(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/blob/master/code/BasicFeature/Resource/ResourceManager/README_zh.md) - [资源管理(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Resource/ResourceManager)
...@@ -98,11 +98,15 @@ install(hapFilePaths: Array&lt;string&gt;, installParam: InstallParam, callback: ...@@ -98,11 +98,15 @@ install(hapFilePaths: Array&lt;string&gt;, installParam: InstallParam, callback:
**系统接口:** 此接口为系统接口。 **系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE<sup>10+</sup> **需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE<sup>10+</sup> 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE<sup>10+</sup> 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE<sup>10+</sup>
> **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限调用此接口。 > **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限调用此接口。
> >
> 安装企业应用需要ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限 > 安装企业应用需要ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限
> >
> 安装企业NORMAL应用需要ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE或ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限
>
> 安装企业MDM应用需要ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限
>
> 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限 > 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core **系统能力:** SystemCapability.BundleManager.BundleFramework.Core
...@@ -138,6 +142,7 @@ install(hapFilePaths: Array&lt;string&gt;, installParam: InstallParam, callback: ...@@ -138,6 +142,7 @@ install(hapFilePaths: Array&lt;string&gt;, installParam: InstallParam, callback:
| 17700044 | Failed to install the HAP because the isolationMode configured is not supported. | | 17700044 | Failed to install the HAP because the isolationMode configured is not supported. |
| 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. | | 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. |
| 17700048 | Failed to install the HAP because the code signature verification is failed. | | 17700048 | Failed to install the HAP because the code signature verification is failed. |
| 17700050 | Failed to install the HAP because enterprise normal/MDM bundle cannot be installed on non-enterprise device. |
**示例:** **示例:**
...@@ -173,11 +178,15 @@ install(hapFilePaths: Array&lt;string&gt;, callback: AsyncCallback&lt;void&gt;): ...@@ -173,11 +178,15 @@ install(hapFilePaths: Array&lt;string&gt;, callback: AsyncCallback&lt;void&gt;):
**系统接口:** 此接口为系统接口。 **系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE<sup>10+</sup> **需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE<sup>10+</sup> 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE<sup>10+</sup> 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE<sup>10+</sup>
> **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限调用此接口。 > **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限调用此接口。
> >
> 安装企业应用需要ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限 > 安装企业应用需要ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限
> >
> 安装企业NORMAL应用需要ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE或ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限
>
> 安装企业MDM应用需要ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限
>
> 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限 > 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core **系统能力:** SystemCapability.BundleManager.BundleFramework.Core
...@@ -211,6 +220,7 @@ install(hapFilePaths: Array&lt;string&gt;, callback: AsyncCallback&lt;void&gt;): ...@@ -211,6 +220,7 @@ install(hapFilePaths: Array&lt;string&gt;, callback: AsyncCallback&lt;void&gt;):
| 17700044 | Failed to install the HAP because the isolationMode configured is not supported. | | 17700044 | Failed to install the HAP because the isolationMode configured is not supported. |
| 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. | | 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. |
| 17700048 | Failed to install the HAP because the code signature verification is failed. | | 17700048 | Failed to install the HAP because the code signature verification is failed. |
| 17700050 | Failed to install the HAP because enterprise normal/MDM bundle cannot be installed on non-enterprise device. |
**示例:** **示例:**
...@@ -243,11 +253,15 @@ install(hapFilePaths: Array\<string\>, installParam?: InstallParam) : Promise\<v ...@@ -243,11 +253,15 @@ install(hapFilePaths: Array\<string\>, installParam?: InstallParam) : Promise\<v
**系统接口:** 此接口为系统接口。 **系统接口:** 此接口为系统接口。
**需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE<sup>10+</sup> **需要权限:** ohos.permission.INSTALL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_BUNDLE<sup>10+</sup> 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE<sup>10+</sup> 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE<sup>10+</sup>
> **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限调用此接口。 > **说明:** 从API version 10起,可通过ohos.permission.INSTALL_ENTERPRISE_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE 或 ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限调用此接口。
> >
> 安装企业应用需要ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限 > 安装企业应用需要ohos.permission.INSTALL_ENTERPRISE_BUNDLE权限
> >
> 安装企业NORMAL应用需要ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE或ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限
>
> 安装企业MDM应用需要ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE权限
>
> 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限 > 安装普通应用需要ohos.permission.INSTALL_BUNDLE权限
**系统能力:** SystemCapability.BundleManager.BundleFramework.Core **系统能力:** SystemCapability.BundleManager.BundleFramework.Core
...@@ -288,6 +302,7 @@ install(hapFilePaths: Array\<string\>, installParam?: InstallParam) : Promise\<v ...@@ -288,6 +302,7 @@ install(hapFilePaths: Array\<string\>, installParam?: InstallParam) : Promise\<v
| 17700044 | Failed to install the HAP because the isolationMode configured is not supported. | | 17700044 | Failed to install the HAP because the isolationMode configured is not supported. |
| 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. | | 17700047 | Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode. |
| 17700048 | Failed to install the HAP because the code signature verification is failed. | | 17700048 | Failed to install the HAP because the code signature verification is failed. |
| 17700050 | Failed to install the HAP because enterprise normal/MDM bundle cannot be installed on non-enterprise device. |
**示例:** **示例:**
......
...@@ -659,6 +659,20 @@ Failed to install the HAP because the bundleName is different from the bundleNam ...@@ -659,6 +659,20 @@ Failed to install the HAP because the bundleName is different from the bundleNam
**处理步骤**<br/> **处理步骤**<br/>
1. 检查要安装的hap或hsp是否属于当前应用。 1. 检查要安装的hap或hsp是否属于当前应用。
## 17700050 企业设备校验失败
**错误信息**<br/>
Failed to install the HAP because enterprise normal/MDM bundle cannot be installed on non-enterprise device.
**错误描述**<br/>
安装应用时,企业normal应用或企业mdm应用无法在非企业设备上安装。
**可能原因**<br/>
1. 安装设备不是企业设备。
**处理步骤**<br/>
1. 检查安装设备是否为企业设备。
2. 检查设备参数const.bms.allowenterprisebundle是否为true
## 17700051 应用自升级时安装的应用与调用方包名不同 ## 17700051 应用自升级时安装的应用与调用方包名不同
**错误信息**<br/> **错误信息**<br/>
Failed to install the HAP because the distribution type of caller application is not enterprise_mdm. Failed to install the HAP because the distribution type of caller application is not enterprise_mdm.
...@@ -670,4 +684,4 @@ Failed to install the HAP because the distribution type of caller application is ...@@ -670,4 +684,4 @@ Failed to install the HAP because the distribution type of caller application is
1. 调用方的分发类型不是企业mdm。 1. 调用方的分发类型不是企业mdm。
**处理步骤**<br/> **处理步骤**<br/>
1. 检查应用的签名文件是否正确配置。 1. 检查应用的签名文件是否正确配置。
\ No newline at end of file
...@@ -367,6 +367,6 @@ user_grant权限可以通过预授权方式请求权限。预授权方式需要 ...@@ -367,6 +367,6 @@ user_grant权限可以通过预授权方式请求权限。预授权方式需要
针对访问控制,有以下相关实例可供参考: 针对访问控制,有以下相关实例可供参考:
- [AbilityAccessCtrl:访问权限控制(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Security/AbilityAccessCtrl) - [访问权限控制(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Security/AbilityAccessCtrl)
- [为应用添加运行时权限(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Security/AccessPermission) - [为应用添加运行时权限(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Security/AccessPermission)
...@@ -573,3 +573,9 @@ function crlEntrySample() { ...@@ -573,3 +573,9 @@ function crlEntrySample() {
}); });
} }
``` ```
## 相关实例
针对证书开发,有以下相关实例可供参考:
- [证书算法库框架(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Security/CertificateFramework)
\ No newline at end of file
...@@ -2571,4 +2571,10 @@ function doRandBySync() { ...@@ -2571,4 +2571,10 @@ function doRandBySync() {
针对加解密算法开发,有以下相关实例可供参考: 针对加解密算法开发,有以下相关实例可供参考:
- [支付(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Security/PaySecurely)
- [通用密钥库系统(cryptoFramework)(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Security/CryptoFramework)
- [加解密(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Security/Cipher)
- [字符串加解密(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Security/StringCipherArkTS) - [字符串加解密(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Security/StringCipherArkTS)
...@@ -194,4 +194,8 @@ ...@@ -194,4 +194,8 @@
基于代理提醒,有以下相关实例可供参考: 基于代理提醒,有以下相关实例可供参考:
- [后台代理提醒(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/ReminderAgentManager)
- [翻页闹钟(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Tools/FlipClock)
- [闹钟(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/CommonEventAndNotification/AlarmClock) - [闹钟(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/CommonEventAndNotification/AlarmClock)
\ No newline at end of file
...@@ -475,4 +475,4 @@ ...@@ -475,4 +475,4 @@
针对长时任务开发,有以下相关实例可供参考: 针对长时任务开发,有以下相关实例可供参考:
- [ContinuousTask:长时任务(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/ContinuousTask) - [长时任务(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/ContinuousTask)
\ No newline at end of file \ No newline at end of file
...@@ -97,4 +97,4 @@ ...@@ -97,4 +97,4 @@
针对短时任务开发,有以下相关实例可供参考: 针对短时任务开发,有以下相关实例可供参考:
- [短时任务(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/TransientTask) - [短时任务(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/TransientTask)
\ No newline at end of file \ No newline at end of file
...@@ -210,4 +210,4 @@ WorkInfo参数用于设置应用条件,参数设置时需遵循以下规则: ...@@ -210,4 +210,4 @@ WorkInfo参数用于设置应用条件,参数设置时需遵循以下规则:
针对延迟任务调度的开发,有以下相关示例可供参考: 针对延迟任务调度的开发,有以下相关示例可供参考:
- [WorkScheduler的创建与使用(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/WorkScheduler) - [延迟任务调度(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/TaskManagement/WorkScheduler)
\ No newline at end of file \ No newline at end of file
...@@ -111,6 +111,6 @@ observer模块为开发者提供订阅和取消订阅通话业务状态的功能 ...@@ -111,6 +111,6 @@ observer模块为开发者提供订阅和取消订阅通话业务状态的功能
## 相关实例 ## 相关实例
拨打电话有以下相关实例可供参考: 针对拨打电话,有以下相关实例可供参考:
- [拨打电话](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Telephony/Call) - [拨打电话(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Telephony/Call)
...@@ -115,4 +115,5 @@ ...@@ -115,4 +115,5 @@
## 相关实例 ## 相关实例
针对短信的使用,有以下相关实例可供参考: 针对短信的使用,有以下相关实例可供参考:
- [短信服务](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Telephony/Message)
- [短信服务(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Telephony/Message)
...@@ -271,4 +271,6 @@ Video组件已经封装好了视频播放的基础能力,开发者无需进行 ...@@ -271,4 +271,6 @@ Video组件已经封装好了视频播放的基础能力,开发者无需进行
针对Video组件开发,有以下相关实例可供参考: 针对Video组件开发,有以下相关实例可供参考:
- [视频播放(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Media/VideoShow)
- [简易视频播放器(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/SimpleVideo) - [简易视频播放器(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/SimpleVideo)
\ No newline at end of file
...@@ -306,3 +306,9 @@ struct TouchExample { ...@@ -306,3 +306,9 @@ struct TouchExample {
![zh-cn_image_0000001511900468](figures/zh-cn_image_0000001511900468.gif) ![zh-cn_image_0000001511900468](figures/zh-cn_image_0000001511900468.gif)
## 相关实例
针对触屏事件开发,有以下相关实例可供参考:
- [拖拽事件(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/Drag)
\ No newline at end of file
...@@ -346,6 +346,12 @@ OffscreenCanvasRenderingContext2D对象和CanvasRenderingContext2D对象提供 ...@@ -346,6 +346,12 @@ OffscreenCanvasRenderingContext2D对象和CanvasRenderingContext2D对象提供
使用画布绘制自定义图形,有以下相关实例可供参考: 使用画布绘制自定义图形,有以下相关实例可供参考:
- [画布组件(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/Canvas)
- [分布式五子棋(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Game/DistributedDataGobang)
- [ArkTS时钟(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Tools/ArkTSClock)
- [Lottie动画](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Game/Lottie) - [Lottie动画](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Game/Lottie)
- [自定义抽奖转盘(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/CanvasComponent) - [自定义抽奖转盘(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/CanvasComponent)
\ No newline at end of file
...@@ -334,6 +334,8 @@ Grid() { ...@@ -334,6 +334,8 @@ Grid() {
## 相关实例 ## 相关实例
如需详细了解网格布局的实现,请参考以下示例: 针对网格开发,有以下相关实例可供参考:
- [游戏2048(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/Solutions/Game/Game2048)
- [分布式计算器](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/ArkTSDistributedCalc) - [分布式计算器](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/DistributedAppDev/ArkTSDistributedCalc)
...@@ -258,6 +258,6 @@ struct MediaQueryExample { ...@@ -258,6 +258,6 @@ struct MediaQueryExample {
## 相关实例 ## 相关实例
基于媒体查询,可参考以下实例 针对媒体查询开发,有以下相关实例可供参考
[媒体查询](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/MediaQuery):使用媒体查询,完成在不同设备上显示不同的界面效果。 - [横竖屏切换(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/MediaQuery)
...@@ -82,6 +82,8 @@ position、offset等属性影响了布局容器相对于自身或其他组件的 ...@@ -82,6 +82,8 @@ position、offset等属性影响了布局容器相对于自身或其他组件的
针对布局开发,有以下相关实例可供参考: 针对布局开发,有以下相关实例可供参考:
- [页面布局和连接(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/DefiningPageLayoutAndConnection)
- [ArkUI常用布局容器对齐方式(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/OHLayoutAlign) - [ArkUI常用布局容器对齐方式(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/OHLayoutAlign)
- [常用组件与布局(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/ArkTSComponents) - [常用组件与布局(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/ArkTSComponents)
\ No newline at end of file
...@@ -384,3 +384,8 @@ struct Index { ...@@ -384,3 +384,8 @@ struct Index {
} }
``` ```
## 相关实例
针对页面路由开发,有以下相关实例可供参考:
- [页面布局和连接(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/DefiningPageLayoutAndConnection)
\ No newline at end of file
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
基于ArkTS的声明式开发范式,可参考以下实例: 基于ArkTS的声明式开发范式,可参考以下实例:
- [ArkTS组件集](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/ComponentCollection):组件、通用方法、动画、全局方法的集合。 - [ArkTS组件集(ArkTS)(Full SDK)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/ArkTsComponentCollection/ComponentCollection)
- [像素转换(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/PixelConversion) - [像素转换(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/ETSUI/PixelConversion)
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
针对组件开发,有以下相关实例可供参考: 针对组件开发,有以下相关实例可供参考:
- [`JsComponentCollection`:组件集合(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection) - [JS组件集(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection)
- [rating组件的使用(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/RatingApplication) - [rating组件的使用(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/RatingApplication)
......
...@@ -146,7 +146,7 @@ export default { ...@@ -146,7 +146,7 @@ export default {
针对Canvas开发,有以下相关实例可供参考: 针对Canvas开发,有以下相关实例可供参考:
- [`JsComponentCollection`:JS组件集合(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection) - [JS组件集(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection)
- [自定义抽奖转盘(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/JSCanvasComponent) - [自定义抽奖转盘(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/JSCanvasComponent)
......
...@@ -217,7 +217,7 @@ export default{ ...@@ -217,7 +217,7 @@ export default{
针对slider开发,有以下相关实例可供参考: 针对slider开发,有以下相关实例可供参考:
- [`JsComponentCollection`:JS组件集合(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection) - [JS组件集(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection)
- [slider组件的使用(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/SliderApplication) - [slider组件的使用(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/JSUI/SliderApplication)
......
...@@ -370,6 +370,6 @@ export default { ...@@ -370,6 +370,6 @@ export default {
针对swiper开发,有以下相关实例可供参考: 针对swiper开发,有以下相关实例可供参考:
- [`JsComponentCollection`:JS组件集合(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection) - [JS组件集(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection)
- [简易视频播放器(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/VideoOpenHarmony) - [简易视频播放器(JS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Media/VideoOpenHarmony)
...@@ -28,11 +28,3 @@ ...@@ -28,11 +28,3 @@
- **Porting Layer** - **Porting Layer**
适配层主要完成对平台层进行抽象,提供抽象接口,可以对接到系统平台。比如:事件对接、渲染管线对接和系统生命周期对接等。 适配层主要完成对平台层进行抽象,提供抽象接口,可以对接到系统平台。比如:事件对接、渲染管线对接和系统生命周期对接等。
## 相关实例
兼容JS的类Web开发范式的方舟开发框架,有以下相关实例可供参考:
- [`JsComponentCollection`:JS组件集合(JS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/JsComponentCollection/JsComponentCollection)
...@@ -46,3 +46,9 @@ ...@@ -46,3 +46,9 @@
} }
} }
``` ```
## 相关实例
针对Web组件开发,有以下相关实例可供参考:
- [JS注入与执行(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Web/RunJsInWeb)
\ No newline at end of file
...@@ -138,3 +138,9 @@ struct WebComponent { ...@@ -138,3 +138,9 @@ struct WebComponent {
} }
} }
``` ```
## 相关实例
针对Web组件开发,有以下相关实例可供参考:
- [浏览器(ArkTS)(Full SDK)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Web/Browser)
\ No newline at end of file
...@@ -372,4 +372,6 @@ export default class EntryAbility extends UIAbility { ...@@ -372,4 +372,6 @@ export default class EntryAbility extends UIAbility {
- [`Window`:一多设置典型页面(Settings)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/Settings) - [`Window`:一多设置典型页面(Settings)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/SuperFeature/MultiDeviceAppDev/Settings)
- [`WindowManage`:窗口管理(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/WindowManagement/WindowManage) - [窗口管理(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/WindowManagement/WindowManage)
\ No newline at end of file
- [窗口(ArkTS)(API10)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/WindowManagement/WindowRatio)
\ No newline at end of file
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
- [列表上拉加载更多内容](list-pullup-loading-data.md) - [列表上拉加载更多内容](list-pullup-loading-data.md)
- [如何删除多选框选项](delete-checkboxgroup-items.md) - [如何删除多选框选项](delete-checkboxgroup-items.md)
- [像素单位转换](pixel-format-transfer.md) - [像素单位转换](pixel-format-transfer.md)
- [如何在UIAbility间进行跳转](jump-between-UIAbilities.md)
- [转场动画](transition-animation.md)
### 装饰器 ### 装饰器
- [控制页面刷新范围](overall-and-part-refresh.md) - [控制页面刷新范围](overall-and-part-refresh.md)
...@@ -40,6 +42,7 @@ ...@@ -40,6 +42,7 @@
- [如何实现沉浸模式](immersion-mode.md) - [如何实现沉浸模式](immersion-mode.md)
- [如何创建悬浮窗](float-window.md) - [如何创建悬浮窗](float-window.md)
- [保持屏幕常亮](keep-screen-on.md) - [保持屏幕常亮](keep-screen-on.md)
- [如何创建子窗口并与主窗口通信](subwindow-mainwindow-communication.md)
### 数据管理 ### 数据管理
- [用户首选项的基本使用](preferences-data-process.md) - [用户首选项的基本使用](preferences-data-process.md)
......
# UIAbility内和UIAbility间页面的跳转
## 场景介绍
UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。例如,在支付应用中,可以将入口功能和收付款功能分别配置为独立的UIAbility。
对于开发者而言,可以根据具体场景选择单个还是多个UIAbility,划分建议如下:
* 如果希望在任务视图中看到一个任务,则建议使用一个UIAbility,多个页面的方式。
* 如果希望在任务视图中看到多个任务,或者需要同时开启多个窗口,则建议使用多个UIAbility开发不同的模块功能。
本例即为大家介绍如何基于Stage模型下的UIAbility开发,实现UIAbility内和UIAbility间页面的跳转与数据传递的功能。
## 效果呈现
本例最终效果如下:
![UIAbility](figures/UIAbility.gif)
## 运行环境
本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
- IDE: DevEco Studio 4.0 Beta1
- SDK: Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)
## 实现思路
本篇案例是基于Stage模型下的UIAbility开发,实现UIAbility内和UIAbility间页面的跳转。
* UIAbility内页面的跳转:
entry模块中,通过添加页面路由router来实现,页面路由router根据页面url找到目标页面,从而实现跳转。
* UIAbility间页面的跳转--跳转到指定UIAbility的首页:
实现UIAbility间页面的跳转,需要启动另外一个UIAbility,可以通过UIAbilityContext的startAbility的方法来完成。
* UIAbility间页面的跳转--跳转到指定UIAbility的指定页面(非首页):
实现跳转到指定UIAbility的指定页面(非首页),就需要在跳转到指定UIAbility的首页的基础上,新建一个Second页面,使用UIAbilityContext.startAbilityForResult来实现。
## 开发步骤
由于本例重点介绍UIAbility之间的跳转,所以开发步骤会着重讲解相关实现,不相关的内容不做介绍,全量代码可参考完整代码章节。
1. 从实现效果看,UIAbility之间的跳转,都是通过点击每个页面的button后实现的,因此我们可以先构建一个按钮点击后调用的方法类:ButtonClickMethod。
具体代码如下:
```ts
// entry/src/main/ets/model/ButtonClickMethod.ets
...
// 按钮点击后调用的方法类
Class ButtonClickMethod{
...
}
export default new ButtonClickMethod();
```
2. UIAbility内页面的跳转。
* 实现UIAbility内页面的跳转,首先构建Index页面,Index页面由一个Image组件、两个Text组件、三个Button组件组成。
具体代码如下:
```ts
// entry/src/main/ets/pages/Index.ets
@Entry
@Component
struct Index {
@State text: string = '';
build() {
Column() {
Image($r('app.media.right'))
...
Text($r('app.string.main_index_page_name'))
...
// 条件渲染:当text的值不为空时,显示该组件
if (this.text !== '') {
Text(this.text)
...
}
// 导航到EntryAbility的Second Page按钮
Button($r('app.string.to_main_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
// 导航到SecondAbility的Index Page按钮
Button($r('app.string.to_second_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
// 导航到SecondAbility的Index Page按钮
Button($r('app.string.to_second_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
}
...
}
}
```
* 构建Second页面,该页面由一个Image组件、两个Text组件、一个Button组件组成。
具体代码如下:
```ts
// entry/src/main/ets/pages/Second.ets
@Entry
@Component
struct Second {
...
build() {
Column() {
Image($r('app.media.left'))
...
Text($r('app.string.main_second_page_name'))
...
Text(`${this.src}${this.count}`)
...
// 返回到EntryAbility的Index Page按钮
Button($r('app.string.back_main_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
}
...
}
}
```
* entry模块的Index和Second页面之间的跳转以及数据的传递,需要通过router来实现。
* 从EntryAbility首页跳转到Second页面:
1. 导入router模块, 向按钮点击后调用的方法类ButtonClickMethod中添加toEntryAbilitySecond方法,使用router.pushUrl实现跳转,同时通过params来向新页面传入参数。
具体代码如下:
```ts
// entry/src/main/ets/model/ButtonClickMethod.ets
import router from '@ohos.router';
// 按钮点击后调用的方法类
Class ButtonClickMethod{
// 导航entry模块的Second页面
toEntryAbilitySecond() {
router.pushUrl({
url: 'pages/Second',
params: {
src: textMessage,
count: CommonConstants.NUM_VALUES[0]
}
});
}
...
}
export default new ButtonClickMethod();
```
2. 点击“导航到EntryAbility的Second Page”按钮后,调用ButtonClickMethod类中的toEntryAbilitySecond方法,跳转到EntryAbility的Second页面。
具体代码如下:
```ts
// entry/src/main/ets/pages/Index.ets
...
@Entry
@Component
struct Index {
@State text: string = '';
@State bottomMargin: string = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
build() {
Column() {
Image($r('app.media.right'))
...
Text($r('app.string.main_index_page_name'))
...
// 条件渲染:当text的值不为空时,显示该组件
if (this.text !== '') {
Text(this.text)
...
}
Button($r('app.string.to_main_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
.onClick(() => {
// 导航到EntryAbility的Second Page
ButtonClickMethod.toSecondAbilityIndex(context);
this.text = '';
this.bottomMargin = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
})
Button($r('app.string.to_second_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
Button($r('app.string.to_second_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
}
...
}
}
```
* 从entry模块的EntryAbility的Second页面返回至EntryAbility首页:
向EntryAbility的Second页面导入router模块,同时给button添加oncClick事件,使用router.back实现返回至EntryAbility的index页面。
具体代码如下:
```ts
// entry/src/main/ets/pages/Second.ets
import router from '@ohos.router';
@Entry
@Component
struct Second {
...
build() {
Column() {
Image($r('app.media.left'))
...
Text($r('app.string.main_second_page_name'))
...
Text(`${this.src}${this.count}`)
...
Button($r('app.string.back_main_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
.onClick(() => {
// 返回到EntryAbility的Index Page
router.back();
})
}
...
}
}
```
3. 跳转到指定的UIAbility的首页。
* 实现跳转到指定UIAbility的首页,先构建另外一个模块,方法如下:
在“Project”窗口,右键点击“entry 文件夹”,选择“New > Module > Empty Ability > Next”,在“Module name”中给新建的模块命名为“device”,点击“Next”,在“Ability name”中给新建模块的Ability命名为“SecondAbility”,点击“Finish”。可以看到文件目录结构如下:
![device-modules](figures/device-module.png)
* 构建device模块下SecondAbility的Index页面,该页面由一个Image组件、两个Text组件、一个Button组件组成。
具体代码如下:
```ts
// device/src/main/ets/pages/Index.ets
@Entry
@Component
struct Index {
...
build() {
Column() {
Image($r('app.media.left'))
...
Text($r('app.string.second_index_page_name'))
...
Text(`${this.src}${this.count}`)
...
// 停止SecondAbility自身按钮
Button($r('app.string.terminate_second_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
}
...
}
}
```
* 从entry模块的EntryAbility首页跳转至device模块的SecondAbility首页:需要通过UIAbilityContext的startAbility方法来实现。
1. 在EntryAbility的Index页面获取UIAbilityContext。
> 使用UIAbilityContext中的方法,需要在对应的页面获取相应的UIAbilityContext。
具体代码如下:
```ts
// entry/src/main/ets/pages/Index.ets
...
// 获取UIAbilityContext
let context = getContext(this);
...
```
2. 在EntryAbility的Index页面中,点击“导航到SecondAbility的Index Page”按钮后,调用ButtonClickMethod类中的toSecondAbilityIndex方法,拉起SecondAbility的Index页面,同时通过params来向新页面传入参数。
* 向ButtonClickMethod类中添加toSecondAbilityIndex方法。
具体代码如下:
```ts
// entry/src/main/ets/model/ButtonClickMethod.ets
import router from '@ohos.router';
import Logger from '../common/utils/Logger';
// 按钮点击后调用的方法类
Class ButtonClickMethod{
...
// 导航device模块的Index页面
toSecondAbilityIndex(context) {
let want = {
'deviceId': '',
'bundleName': 'com.example.uiability',
'abilityName': 'SecondAbility',
'moduleName':'device',
'parameters': {
src: textMessage,
count: 45
}
};
context.startAbility(want).then(() => {
Logger.info(CommonConstants.TAG, `start second ability index page succeed with ${JSON.stringify(want)}`);
}).catch((error) => {
Logger.error(CommonConstants.TAG, `start second ability index page failedwith ${error.code}`);
});
}
...
}
export default new ButtonClickMethod();
```
* 在EntryAbility的Index页面中,给“导航到SecondAbility的Index Page”按钮添加onClick事件,调用ButtonClickMethod类中的toSecondAbilityIndex方法,实现到SecondAbility首页的跳转。
具体代码如下:
```ts
// entry/src/main/ets/pages/Index.ets
...
// 获取UIAbilityContext
let context = getContext(this);
@Entry
@Component
struct Index {
@State text: string = '';
@State bottomMargin: string = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
build() {
Column() {
Image($r('app.media.right'))
...
Text($r('app.string.main_index_page_name'))
...
// 条件渲染:当text的值不为空时,显示该组件
if (this.text !== '') {
Text(this.text)
...
}
Button($r('app.string.to_main_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
Button($r('app.string.to_second_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
.onClick(() => {
// 导航到SecondAbility的Index页面
ButtonClickMethod.toSecondAbilityIndex(context);
this.text = '';
this.bottomMargin = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
})
Button($r('app.string.to_second_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
}
...
}
}
```
* 在SecondAbility的Index页面,获取从EntryAbility的Index页面传递过来的自定义参数,并用一个Text文本展示从Index页面传递过来的数据。
具体代码如下:
```ts
// device/src/main/ets/pages/Index.ets
...
@Entry
@Component
struct Index {
// 获取从EntryAbility的Index页面传递过来的自定义参数
@State src: string = globalThis?.secondAbilityWant?.parameters?.src ?? '-';
@State count: number = globalThis?.secondAbilityWant?.parameters?.count ?? 0;
build() {
Column() {
Image($r('app.media.left'))
...
Text($r('app.string.second_index_page_name'))
...
// 用一个Text文本展示从Index页面传递过来的数据
Text(`${this.src}:${this.count}`)
...
// 停止SecondAbility自身按钮
Button($r('app.string.terminate_second_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
}
...
}
}
```
* 从device模块的SecondAbility首页返回到entry模块的EntryAbility首页:通过点击device模块的Index页面的“停止SecondAbility自身”按钮,使用UIAbilityContext.terminateSelf方法手动销毁Ability。
1. 给ButtonClickMethod类中添加toSecondAbilityIndex方法。
具体代码如下:
```ts
// entry/src/main/ets/model/ButtonClickMethod.ets
import router from '@ohos.router';
import Logger from '../common/utils/Logger';
// 按钮点击后调用的方法类
Class ButtonClickMethod{
...
// 停止SecondAbility自身
terminateSecondAbility(context) {
context.terminateSelf().then(() => {
Logger.info(CommonConstants.TAG, 'terminate second ability self succeed');
}).catch((error) => {
Logger.error(CommonConstants.TAG, `terminate second ability self failed with ${error.code}`);
});
}
...
}
export default new ButtonClickMethod();
```
2. 在SecondAbility的Index页面中,给“停止SecondAbility自身”按钮添加onClick事件,调用ButtonClickMethod类中的terminateSecondAbility方法,使用UIAbilityContext.terminateSelf方法手动销毁Ability,从而实现从SecondAbility的Index页面返回至entry的Index页面。
具体代码如下:
```ts
// device/src/main/ets/model/Index.ets
let context = getContext(this);
...
@Entry
@Component
struct Index {
// 获取从EntryAbility的Index页面传递过来的自定义参数
@State src: string = globalThis?.secondAbilityWant?.parameters?.src ?? '-';
@State count: number = globalThis?.secondAbilityWant?.parameters?.count ?? 0;
build() {
Column() {
Image($r('app.media.left'))
...
Text($r('app.string.second_index_page_name'))
...
// 用一个Text文本展示从EntryAbility的Index页面传递过来的数据
Text(`${this.src}:${this.count}`)
...
Button($r('app.string.terminate_second_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
.onClick(() => {
// 停止SecondAbility自身
ButtonClickMethod.terminateSecondAbility(context);
})
}
...
}
}
```
4. 跳转到指定UIAbility的指定页面(非首页)。
* 构建device模块下SecondAbility的Second页面。该页面由一个Image组件、两个Text组件、一个Button组件组成。
具体代码如下:
```ts
// device/src/main/ets/pages/Second.ets
@Entry
@Component
struct Index {
...
build() {
Column() {
Image($r('app.media.left'))
...
Text($r('app.string.second_second_page_name'))
...
// 用一个Text文本展示从EntryAbility的Index页面传递过来的数据
Text(`${this.src}${this.count}`)
...
// 停止SecondAbility自身且返回结果按钮
Button($r('app.string.terminate_second_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
}
...
}
}
```
* 从entry模块的EntryAbility的首页跳转至device模块的SecondAbility的Second页面:通过点击“导航到SecondAbility的Second Page”按钮后,调用ButtonClickMethod类中的toSecondAbilitySecond方法,拉起SecondAbility的Second页面。
1. 给ButtonClickMethod类中添加toSecondAbilitySecond方法,该方法中使用UIAbilityContext.startAbilityForResult来实现,并获取被拉起侧销毁后的返回结果。可以通过parameters来向被拉起方传递参数。
具体代码如下:
```ts
// entry/src/main/ets/model/ButtonClickMethod.ets
import router from '@ohos.router';
import Logger from '../common/utils/Logger';
let currentContext = getContext(this);
// 按钮点击后调用的方法类
Class ButtonClickMethod{
...
// 导航到SecondAbility的Second页面
toSecondAbilitySecond(context, callback) {
let want = {
'deviceId': '',
'bundleName': 'com.example.uiability',
'abilityName': 'SecondAbility',
'moduleName':'device',
'parameters': {
url: 'pages/Second',
src: textMessage,
count: 78
}
};
// 被拉起侧销毁后,在startAbilityForResult回调中可以获取到被拉起侧销毁时传递过来的AbilityResult
context.startAbilityForResult(want).then((result) => {
callback(result);
Logger.info(CommonConstants.TAG, `start second ability second page succeed with ${JSON.stringify(want)}`);
}).catch((error) => {
Logger.error(CommonConstants.TAG, `start second ability second page failed with ${error.code}`);
});
}
...
}
export default new ButtonClickMethod();
```
2. 在EntryAbility的Index页面中,给“导航到SecondAbility的Second Page”按钮添加onClick事件,调用ButtonClickMethod类中的toSecondAbilityIndex方法,实现到SecondAbility首页的跳转。
具体代码如下:
```ts
// entry/src/main/ets/pages/Index.ets
...
// 获取UIAbilityContext
let context = getContext(this);
@Entry
@Component
struct Index {
@State text: string = '';
@State bottomMargin: string = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
build() {
Column() {
Image($r('app.media.right'))
...
Text($r('app.string.main_index_page_name'))
...
// 条件渲染:当text的值不为空时,显示该组件
if (this.text !== '') {
Text(this.text)
...
}
Button($r('app.string.to_main_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
Button($r('app.string.to_second_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
Button($r('app.string.to_second_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
.onClick(() => {
this.text = '';
this.bottomMargin = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
// 导航到SecondAbility的Second页面
ButtonClickMethod.toSecondAbilitySecond(context, (abilityResult) => {
// 获取SecondAbility被销毁时传递的abilityResult
if (abilityResult.resultCode === CommonConstants.RESULT_CODE) {
let src: string = abilityResult?.want?.parameters?.src ?? '-';
let count: number = abilityResult?.want?.parameters?.count ?? 0;
this.text = `${src}${count}`;
this.bottomMargin = StyleConstants.BUTTON_MARGIN_BOTTOM;
}
});
})
}
...
}
}
```
* 从device模块的SecondAbility的Second页面,返回至entry模块的EntryAbility首页:通过点击“停止SecondAbility自身并返回结果”按钮,调用ButtonClickMethod类中的terminateSecondAbilityForResult方法,使用UIAbilityContext.terminateSelfWithResult方法,同时传入不同的resultCode和want,手动销毁Ability,成功后拉起侧会收到abilityResult的值, 通过Text的方式显示在界面上,从而实现从SecondAbility的Second页面返回至entry的Index页面。
1. 给ButtonClickMethod类中添加terminateSecondAbilityForResult方法。
具体代码如下:
```ts
// entry/src/main/ets/model/ButtonClickMethod.ets
import router from '@ohos.router';
import Logger from '../common/utils/Logger';
// 按钮点击后调用的方法类
Class ButtonClickMethod{
...
// 停止SecondAbility自身
terminateSecondAbilityForResult(context) {
let abilityResult = {
resultCode: CommonConstants.RESULT_CODE,
want: {
'parameters': {
src: returnMessage,
count: 99
}
}
};
// 停止SecondAbility自身,并将abilityResult返回给startAbilityForResult接口调用方
context.terminateSelfWithResult(abilityResult).then(() => {
Logger.info(CommonConstants.TAG, `terminate second ability self succeed with ${JSON.stringify(abilityResult)}`);
}).catch((error) => {
Logger.error(CommonConstants.TAG, `terminate second ability self failed with ${error.code}`);
});
}
...
}
export default new ButtonClickMethod();
```
2. 在SecondAbility的Index页面中,给“停止SecondAbility自身并返回结果”按钮添加onClick事件,调用ButtonClickMethod类中的terminateSecondAbilityForResult方法,手动销毁自身Ability。
具体代码如下:
```ts
// device/src/main/ets/pages/Second.ets
let context = getContext(this);
@Entry
@Component
struct Second {
// 用来接收parameters参数传过来的值
@State src: string = globalThis?.secondAbilityWant?.parameters?.src ?? '-';
@State count: number = globalThis?.secondAbilityWant?.parameters?.count ?? 0;
build() {
Column() {
Image($r('app.media.left'))
...
Text($r('app.string.second_second_page_name'))
...
Text(`${this.src}${this.count}`)
..
// 停止SecondAbility自身且返回结果按钮
Button($r('app.string.terminate_second_for_result_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
...
.onClick(() => {
// 停止SecondAbility自身且返回结果.
ButtonClickMethod.terminateSecondAbilityForResult(context);
})
}
...
}
}
```
## 完整代码
本例完整代码如下:
1. entry模块的代码:
* 公共常量类:entry/src/main/ets/common/constants/CommonConstants.ets
具体代码如下:
```ts
class CommonConstants {
TAG = '[ButtonClickMethod.ts]';
RESULT_CODE = 100;
}
export default new CommonConstants();
```
* 样式常量类:entry/src/main/ets/common/constants/StyleConstants.ets
具体代码如下:
```ts
class StyleConstants {
IMAGE_WIDTH = '78%';
IMAGE_HEIGHT = '25%';
IMAGE_MARGIN_TOP = '140vp';
IMAGE_MARGIN_BOTTOM = '55vp';
MAIN_INDEX_TEXT_MARGIN_BOTTOM = '148vp';
BUTTON_WIDTH = '87%';
BUTTON_HEIGHT = '5%';
BUTTON_MARGIN_BOTTOM = '12vp';
MAIN_INDEX_BUTTON_MARGIN_BOTTOM = '179vp';
TEXT_MARGIN_BOTTOM = '250vp';
FULL_PERCENT = '100%';
FONT_SIZE_BIG = 20;
FONT_WEIGHT = 500;
FONT_SIZE_SMALL = 16;
OPACITY = 0.6;
}
export default new StyleConstants();
```
* 按钮点击后调用的方法类:entry/src/main/ets/model/ButtonClickMethod.ets
具体代码如下:
```ts
import router from '@ohos.router';
import Logger from '../common/utils/Logger';
import CommonConstants from '../common/constants/CommonConstants';
let currentContext = getContext(this);
let textMessage: string = currentContext.resourceManager.getStringSync($r('app.string.text_message'));
let returnMessage: string = currentContext.resourceManager.getStringSync($r('app.string.return_message'));
// 按钮点击后调用的方法类
class ButtonClickMethod {
// 导航entry模块的Second页面
toEntryAbilitySecond() {
router.pushUrl({
url: 'pages/Second',
params: {
src: textMessage,
count: 12
}
});
}
// 导航device模块的Index页面
toSecondAbilityIndex(context) {
let want = {
'deviceId': '',
'bundleName': 'com.example.uiability',
'abilityName': 'SecondAbility',
'moduleName':'device',
'parameters': {
src: textMessage,
count: 45
}
};
context.startAbility(want).then(() => {
Logger.info(CommonConstants.TAG, `start second ability index page succeed with ${JSON.stringify(want)}`);
}).catch((error) => {
Logger.error(CommonConstants.TAG, `start second ability index page failedwith ${error.code}`);
});
}
// 导航到SecondAbility的Second页面
toSecondAbilitySecond(context, callback) {
let want = {
'deviceId': '',
'bundleName': 'com.example.uiability',
'abilityName': 'SecondAbility',
'moduleName':'device',
'parameters': {
url: 'pages/Second',
src: textMessage,
count: 78
}
};
// 被拉起侧销毁后,在startAbilityForResult回调中可以获取到被拉起侧销毁时传递过来的AbilityResult
context.startAbilityForResult(want).then((result) => {
callback(result);
Logger.info(CommonConstants.TAG, `start second ability second page succeed with ${JSON.stringify(want)}`);
}).catch((error) => {
Logger.error(CommonConstants.TAG, `start second ability second page failed with ${error.code}`);
});
}
// 停止SecondAbility自身
terminateSecondAbility(context) {
context.terminateSelf().then(() => {
Logger.info(CommonConstants.TAG, 'terminate second ability self succeed');
}).catch((error) => {
Logger.error(CommonConstants.TAG, `terminate second ability self failed with ${error.code}`);
});
}
// 停止SecondAbility自身并返回结果
terminateSecondAbilityForResult(context) {
let abilityResult = {
resultCode: CommonConstants.RESULT_CODE,
want: {
'parameters': {
src: returnMessage,
count: 99
}
}
};
// 停止SecondAbility自身,并将abilityResult返回给startAbilityForResult接口调用方
context.terminateSelfWithResult(abilityResult).then(() => {
Logger.info(CommonConstants.TAG, `terminate second ability self succeed with ${JSON.stringify(abilityResult)}`);
}).catch((error) => {
Logger.error(CommonConstants.TAG, `terminate second ability self failed with ${error.code}`);
});
}
}
export default new ButtonClickMethod();
```
* EntryAbility的Index页面:entry/src/main/ets/pages/Index.ets
具体代码如下:
```ts
import ButtonClickMethod from '../model/ButtonClickMethod';
import StyleConstants from '../common/constants/StyleConstants';
import CommonConstants from '../common/constants/CommonConstants';
// 获取EntryAbility的UIAbilityContext
let context = getContext(this);
@Entry
@Component
struct Index {
@State text: string = '';
@State bottomMargin: string = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
build() {
Column() {
Image($r('app.media.right'))
.objectFit(ImageFit.Contain)
.width(StyleConstants.IMAGE_WIDTH)
.height(StyleConstants.IMAGE_HEIGHT)
.margin({
top: StyleConstants.IMAGE_MARGIN_TOP,
bottom: StyleConstants.IMAGE_MARGIN_BOTTOM
})
Text($r('app.string.main_index_page_name'))
.fontColor('#000')
.fontSize(StyleConstants.FONT_SIZE_BIG)
.fontWeight(StyleConstants.FONT_WEIGHT)
.margin({ bottom: this.bottomMargin })
// 条件渲染:当text的值不为空时,显示该组件
if (this.text !== '') {
Text(this.text)
.fontColor('#000')
.fontSize(StyleConstants.FONT_SIZE_SMALL)
.opacity(StyleConstants.OPACITY)
.margin({ bottom: StyleConstants.MAIN_INDEX_TEXT_MARGIN_BOTTOM })
}
// 导航到EntryAbility的Second Page按钮
Button($r('app.string.to_main_second_page_btn_text'),{ type: ButtonType.Capsule, stateEffect: true })
.backgroundColor($r('app.color.button_background_color'))
.width(StyleConstants.BUTTON_WIDTH)
.height(StyleConstants.BUTTON_HEIGHT)
.margin({ bottom: StyleConstants.BUTTON_MARGIN_BOTTOM })
.onClick(() => {
// 导航到EntryAbility的Second page
ButtonClickMethod.toEntryAbilitySecond();
this.text = '';
this.bottomMargin = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
})
// 导航到SecondAbility的Index Page按钮
Button($r('app.string.to_second_index_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
.backgroundColor($r('app.color.button_background_color'))
.width(StyleConstants.BUTTON_WIDTH)
.height(StyleConstants.BUTTON_HEIGHT)
.margin({ bottom: StyleConstants.BUTTON_MARGIN_BOTTOM })
.onClick(() => {
// 导航到SecondAbility的Index Page
ButtonClickMethod.toSecondAbilityIndex(context);
this.text = '';
this.bottomMargin = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
})
// 导航到SecondAbility的Index Page按钮
Button($r('app.string.to_second_second_page_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
.backgroundColor($r('app.color.button_background_color'))
.width(StyleConstants.BUTTON_WIDTH)
.height(StyleConstants.BUTTON_HEIGHT)
.onClick(() => {
this.text = '';
this.bottomMargin = StyleConstants.MAIN_INDEX_BUTTON_MARGIN_BOTTOM;
// 导航到SecondAbility的Second Page
ButtonClickMethod.toSecondAbilitySecond(context, (abilityResult) => {
// 获取SecondAbility被销毁时传递的abilityResult
if (abilityResult.resultCode === CommonConstants.RESULT_CODE) {
let src: string = abilityResult?.want?.parameters?.src ?? '-';
let count: number = abilityResult?.want?.parameters?.count ?? 0;
this.text = `${src}${count}`;
this.bottomMargin = StyleConstants.BUTTON_MARGIN_BOTTOM;
}
});
})
}
.width(StyleConstants.FULL_PERCENT)
.height(StyleConstants.FULL_PERCENT)
.backgroundColor($r('app.color.background_color'))
}
}
```
* EntryAbility的Second页面:entry/src/main/ets/pages/Second.ets
具体代码如下:
```ts
import router from '@ohos.router';
import StyleConstants from '../common/constants/StyleConstants';
@Entry
@Component
struct Second {
@State src: string = router?.getParams()?.['src'] ?? '-';
@State count: number = router?.getParams()?.['count'] ?? 0;
build() {
Column() {
Image($r('app.media.left'))
.objectFit(ImageFit.Contain)
.width(StyleConstants.IMAGE_WIDTH)
.height(StyleConstants.IMAGE_HEIGHT)
.margin({
top: StyleConstants.IMAGE_MARGIN_TOP,
bottom: StyleConstants.IMAGE_MARGIN_BOTTOM
})
Text($r('app.string.main_second_page_name'))
.fontColor('#000')
.fontSize(StyleConstants.FONT_SIZE_BIG)
.fontWeight(StyleConstants.FONT_WEIGHT)
.margin({ bottom: StyleConstants.BUTTON_MARGIN_BOTTOM })
// 用一个Text文本展示从EntryAbility的Index页面传递过来的数据
Text(`${this.src}${this.count}`)
.fontColor('ccc')
.fontSize(StyleConstants.FONT_SIZE_SMALL)
.opacity(StyleConstants.OPACITY)
.margin({ bottom: StyleConstants.TEXT_MARGIN_BOTTOM })
// 返回到EntryAbility的Index Page按钮
Button($r('app.string.back_main_index_page_btn_text'),{ type: ButtonType.Capsule, stateEffect: true })
.backgroundColor($r('app.color.button_background_color'))
.width(StyleConstants.BUTTON_WIDTH)
.height(StyleConstants.BUTTON_HEIGHT)
.onClick(() => {
// 返回到EntryAbility的Index Page
router.back();
})
}
.width(StyleConstants.FULL_PERCENT)
.height(StyleConstants.FULL_PERCENT)
.backgroundColor($r('app.color.background_color'))
}
}
```
2. device模块的代码:
* SecondAbility的Index页面:device/src/main/ets/pages/Index.ets
具体代码如下:
```ts
import ButtonClickMethod from '../../../../../entry/src/main/ets/model/ButtonClickMethod';
import StyleConstants from '../../../../../entry/src/main/ets/common/constants/StyleConstants';
// 获取SecondAbility的UIAbilityContext
let context = getContext(this);
@Entry
@Component
struct Index {
// 获取从EntryAbility的Index页面传递过来的自定义参数
@State src: string = globalThis?.secondAbilityWant?.parameters?.src ?? '-';
@State count: number = globalThis?.secondAbilityWant?.parameters?.count ?? 0;
build() {
Column() {
Image($r('app.media.left'))
.objectFit(ImageFit.Contain)
.width(StyleConstants.IMAGE_WIDTH)
.height(StyleConstants.IMAGE_HEIGHT)
.margin({
top: StyleConstants.IMAGE_MARGIN_TOP,
bottom: StyleConstants.IMAGE_MARGIN_BOTTOM
})
// 用一个Text文本展示从EntryAbility的Index页面传递过来的数据
Text($r('app.string.second_index_page_name'))
.fontColor('#000')
.fontSize(StyleConstants.FONT_SIZE_BIG)
.fontWeight(StyleConstants.FONT_WEIGHT)
.margin({ bottom: StyleConstants.BUTTON_MARGIN_BOTTOM })
// 用一个Text文本展示从Index页面传递过来的数据
Text(`${this.src}${this.count}`)
.fontColor('#000')
.fontSize(StyleConstants.FONT_SIZE_SMALL)
.opacity(StyleConstants.OPACITY)
.margin({ bottom: StyleConstants.TEXT_MARGIN_BOTTOM })
// 停止SecondAbility自身按钮
Button($r('app.string.terminate_second_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
.backgroundColor($r('app.color.button_background_color'))
.width(StyleConstants.BUTTON_WIDTH)
.height(StyleConstants.BUTTON_HEIGHT)
.onClick(() => {
// 停止SecondAbility自身
ButtonClickMethod.terminateSecondAbility(context);
})
}
.width(StyleConstants.FULL_PERCENT)
.height(StyleConstants.FULL_PERCENT)
.backgroundColor($r('app.color.background_color'))
}
}
```
* SecondAbility的Second页面:device/src/main/ets/pages/Second.ets
具体代码如下:
```ts
import ButtonClickMethod from '../../../../../entry/src/main/ets/model/ButtonClickMethod';
import StyleConstants from '../../../../../entry/src/main/ets/common/constants/StyleConstants';
let context = getContext(this);
@Entry
@Component
struct Second {
// 用来接收parameters参数传过来的值
@State src: string = globalThis?.secondAbilityWant?.parameters?.src ?? '-';
@State count: number = globalThis?.secondAbilityWant?.parameters?.count ?? 0;
build() {
Column() {
Image($r('app.media.left'))
.objectFit(ImageFit.Contain)
.width(StyleConstants.IMAGE_WIDTH)
.height(StyleConstants.IMAGE_HEIGHT)
.margin({
top: StyleConstants.IMAGE_MARGIN_TOP,
bottom: StyleConstants.IMAGE_MARGIN_BOTTOM
})
Text($r('app.string.second_second_page_name'))
.fontColor('#000')
.fontSize(StyleConstants.FONT_SIZE_BIG)
.fontWeight(StyleConstants.FONT_WEIGHT)
.margin({ bottom: StyleConstants.BUTTON_MARGIN_BOTTOM })
// 用一个Text文本展示从EntryAbility的Index页面传递过来的数据
Text(`${this.src}${this.count}`)
.fontColor('#000')
.fontSize(StyleConstants.FONT_SIZE_SMALL)
.opacity(StyleConstants.OPACITY)
.margin({ bottom: StyleConstants.TEXT_MARGIN_BOTTOM })
// 停止SecondAbility自身且返回结果按钮
Button($r('app.string.terminate_second_for_result_btn_text'), { type: ButtonType.Capsule, stateEffect: true })
.backgroundColor($r('app.color.button_background_color'))
.width(StyleConstants.BUTTON_WIDTH)
.height(StyleConstants.BUTTON_HEIGHT)
.onClick(() => {
// 停止SecondAbility自身且返回结果
ButtonClickMethod.terminateSecondAbilityForResult(context);
})
}
.width(StyleConstants.FULL_PERCENT)
.height(StyleConstants.FULL_PERCENT)
.backgroundColor($r('app.color.background_color'))
}
}
```
## 参考
- [UIAbility组件概述](../application-dev/application-models/uiability-overview.md)
- [UIAbility组件使用指导](../application-dev/reference/apis/js-apis-app-ability-uiAbility.md)
- [UIAbilityContext使用指导](../application-dev/reference/apis/js-apis-inner-application-uiAbilityContext.md)
- [router (页面路由)使用指导](../application-dev/reference/apis/js-apis-router.md)
- [Want使用指导](../application-dev/reference/apis/js-apis-application-want.md)
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
为便于理解,通过以下例子具体说明单层和多层状态变化: 为便于理解,通过以下例子具体说明单层和多层状态变化:
```ts ```ts
class ClassA { class ClassB {
public c: number; public c: number;
constructor(c: number) { constructor(c: number) {
...@@ -24,20 +24,20 @@ class ClassA { ...@@ -24,20 +24,20 @@ class ClassA {
} }
} }
class ClassB { class ClassA {
// ClassB成员变量的类型为ClassA,ClassA为被嵌套类 // ClassA成员变量的类型为ClassB,ClassB为被嵌套类
public a: ClassA; public b: ClassB;
constructor(a: ClassA) { constructor(b: ClassB) {
this.a = a; this.b = b;
} }
} }
b: ClassB a: ClassA
// 变量a为ClassB的成员变量,为第一层变量,所以变量a的状态变化即为第一层状态变化 // 变量b为ClassA的成员变量,为第一层变量,所以变量b的状态变化即为第一层状态变化
this.b.a = new ClassA(0) this.a.b = new ClassB(0)
// 变量c为被嵌套类ClassA的成员变量,变量c的状态变化即为第二层状态变化 // 变量c为被嵌套类ClassB的成员变量,变量c的状态变化即为第二层状态变化
this.b.a.c = 5 this.a.b.c = 5
``` ```
## 监听第一层状态变化 ## 监听第一层状态变化
......
...@@ -128,6 +128,7 @@ ...@@ -128,6 +128,7 @@
}); });
}; };
} }
export default new PreferenceModel();
``` ```
2. UI中主要包含两大部分:文本和输入框,按钮。将这两部分分别抽取为子组件,在主页中进行调用。具体代码如下: 2. UI中主要包含两大部分:文本和输入框,按钮。将这两部分分别抽取为子组件,在主页中进行调用。具体代码如下:
文本和输入框子组件: 文本和输入框子组件:
......
# 如何创建子窗口并与主窗口通信
## 场景介绍
应用开发过程中,经常需要创建弹窗(子窗口)用来承载跟当前内容相关的业务,比如电话应用的拨号弹窗;阅读应用中长按当前内容触发的编辑弹窗;购物应用经常出现的抽奖活动弹窗等。
本文为大家介绍如何创建子窗口并实现子窗口与主窗口的数据通信。
## 效果呈现
本例最终效果如下:
![subwindow-mainwindow-communication](figures/subwindow-mainwindow-communication.gif)
## 环境要求
本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
- IDE: DevEco Studio 4.0 Beta1
- SDK: Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)
## 实现思路
本例关键特性及实现方案如下:
- 点击“创建子窗口”按钮创建子窗口:使用window模块的createSubWindow方法创建子窗口,在创建时设置子窗口的大小、位置、内容等。
- 子窗口可以拖拽:通过gesture属性为子窗口绑定PanGesture拖拽事件,使用moveWindowTo方法将窗口移动到拖拽位置,呈现拖拽效果。
- 点击主窗口的“子窗口数据+1”按钮,子窗口中的数据加1,反之亦然,即实现主窗口和子窗口间的数据通信:将数据变量存储在AppStorage中,在主窗口和子窗口中引用该数据,并通过@StorageLink与AppStorage中的数据进行双向绑定,从而实现主窗口和子窗口之间的数据联动。
> ![icon-note.gif](../device-dev/public_sys-resources/icon-note.gif) **说明:**
> 本文使用AppStorage实现主窗口和子窗口之间的数据传递,除此之外,Emitter和EventHub等方式也可以实现,开发者可以根据实际业务需要进行选择。
## 开发步骤
由于本例重点讲解子窗口的创建以及主窗口和子窗口之间的通信,所以开发步骤会着重讲解相关内容的开发,其余内容不做赘述,全量代码可参考完整代码章节。
1. 创建子窗口。
使用createSubWindow方法创建名为“hiSubWindow”的子窗口,并设置窗口的位置、大小、显示内容。将创建子窗口的动作放在自定义成员方法showSubWindow()中,方便后续绑定到按钮上。具体代码如下:
```ts
showSubWindow() {
// 创建应用子窗口。
this.windowStage.createSubWindow("hiSubWindow", (err, data) => {
if (err.code) {
console.error('Failed to create the subwindow. Cause: ' + JSON.stringify(err));
return;
}
this.sub_windowClass = data;
console.info('Succeeded in creating the subwindow. Data: ' + JSON.stringify(data));
// 子窗口创建成功后,设置子窗口的位置
this.sub_windowClass.moveWindowTo(300, 300, (err) => {
if (err.code) {
console.error('Failed to move the window. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in moving the window.');
});
// 设置子窗口的大小
this.sub_windowClass.resize(350, 350, (err) => {
if (err.code) {
console.error('Failed to change the window size. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in changing the window size.');
});
// 为子窗口加载对应的目标页面。
this.sub_windowClass.setUIContent("pages/SubWindow",(err) => {
if (err.code) {
console.error('Failed to load the content. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in loading the content.');
// 显示子窗口。
this.sub_windowClass.showWindow((err) => {
if (err.code) {
console.error('Failed to show the window. Cause: ' + JSON.stringify(err));
return;
}
console.info('Succeeded in showing the window.');
});
this.sub_windowClass.setWindowBackgroundColor('#E8A027')
});
})
}
```
2. 实现子窗口可拖拽。
为页面内容绑定PanGesture拖拽事件,拖拽事件发生时获取到触摸点的位置信息,使用@Watch监听到位置变量的变化,然后调用窗口的moveWindowTo方法将窗口移动到对应位置,从而实现拖拽效果。
具体代码如下:
```ts
import window from '@ohos.window';
interface Position {
x: number,
y: number
}
@Entry
@Component
struct SubWindow{
...
// 创建位置变量,并使用@Watch监听,变量发生变化调用moveWindow方法移动窗口
@State @Watch("moveWindow") windowPosition: Position = { x: 0, y: 0 };
private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All });
private subWindow: window.Window
// 通过悬浮窗名称“hiSubWindow”获取到创建的悬浮窗
aboutToAppear() {
this.subWindow = window.findWindow("hiSubWindow")
}
// 将悬浮窗移动到指定位置
moveWindow() {
this.subWindow.moveWindowTo(this.windowPosition.x, this.windowPosition.y);
}
build(){
Column(){
Text(`AppStorage保存的数据:${this.storData}`)
.fontSize(12)
.margin({bottom:10})
Button('主窗口数据+1')
.fontSize(12)
.backgroundColor('#A4AE77')
.onClick(()=>{
this.storData += 1
})
}
.height('100%')
.width('100%')
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.gesture(
PanGesture(this.panOption)
.onActionStart((event: GestureEvent) => {
console.info('Pan start');
})
// 发生拖拽时,获取到触摸点的位置,并将位置信息传递给windowPosition
.onActionUpdate((event: GestureEvent) => {
this.windowPosition.x += event.offsetX;
this.windowPosition.y += event.offsetY;
})
.onActionEnd(() => {
console.info('Pan end');
})
)
}
}
```
3. 实现主窗口和子窗口间的数据通信。本例中即实现点击主窗口的“子窗口数据+1”按钮,子窗口中的数据加1,反之亦然。本例使用应用全局UI状态存储AppStorage来实现对应效果。
- 在创建窗口时触发的onWindowStageCreate回调中将自定义数据变量“data”存入AppStorage。
```ts
onWindowStageCreate(windowStage: window.WindowStage) {
// 将自定义数据变量“data”存入AppStorage
AppStorage.SetOrCreate('data', 1);
...
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
```
- 在主窗口中定义变量“storData”,并使用@StorageLink将其与AppStorage中的变量“data”进行双向绑定,这样一来,“mainData”的变化可以传导至“data”,并且该变化可以被UI框架监听到,从而完成UI状态刷新。
```ts
...
// 使用@StorageLink将"mainData"与AppStorage中的变量"data"进行双向绑定
@StorageLink('data') mainData: number = 1;
...
build() {
Row() {
Column() {
Text(`AppStorage保存的数据:${this.mainData}`)
.margin({bottom:30})
Button('子窗口数据+1')
.backgroundColor('#A4AE77')
.margin({bottom:30})
.onClick(()=>{
// 点击,storData的值加1
this.mainData += 1
})
...
}
.width('100%')
}
.height('100%')
}
```
- 在主窗口中定义变量“subData”,并使用@StorageLink将其与AppStorage中的变量“data”进行双向绑定。由于主窗口的“mainData”也与“data”进行了绑定,因此,“mainData”的值可以通过“data”传递给“subData”,反之亦然。这样就实现了主窗口和子窗口之间的数据同步。
```ts
...
// 使用@StorageLink将"subData"与AppStorage中的变量"data"进行双向绑定
@StorageLink('data') subData: number = 1;
...
build(){
Column(){
Text(`AppStorage保存的数据:${this.subData}`)
.fontSize(12)
.margin({bottom:10})
Button('主窗口数据+1')
.fontSize(12)
.backgroundColor('#A4AE77')
.onClick(()=>{
// 点击,subData的值加1
this.subData += 1
})
}
...
}
```
## 完整代码
本例完整代码如下:
EntryAbility文件代码:
```ts
// EntryAbility.ts
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import hilog from '@ohos.hilog';
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
let sub_windowClass = null;
export default class EntryAbility extends UIAbility {
destroySubWindow() {
// 销毁子窗口。当不再需要子窗口时,可根据具体实现逻辑,使用destroy对其进行销毁。
sub_windowClass.destroyWindow((err) => {
if (err.code) {
console.error('Failed to destroy the window. Cause: ' + JSON.stringify(err));
return;
}
console.info('Succeeded in destroying the window.');
});
}
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
}
onDestroy() {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage) {
// 将自定义数据变量“data”存入AppStorage
AppStorage.SetOrCreate('data', 1);
AppStorage.SetOrCreate('window', windowStage);
// 为主窗口添加加载页面
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
onWindowStageDestroy() {
this.destroySubWindow();
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground() {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground() {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
}
}
```
主窗口代码:
```ts
// Index.ets
import window from '@ohos.window';
@Entry
@Component
struct Index {
// 使用@StorageLink将"mainData"与AppStorage中的变量"data"进行双向绑定
@StorageLink('data') mainData: number = 1;
@StorageLink('window') storWindow:window.WindowStage = null
private windowStage = this.storWindow
private sub_windowClass = null
showSubWindow() {
// 创建应用子窗口。
this.windowStage.createSubWindow("hiSubWindow", (err, data) => {
if (err.code) {
console.error('Failed to create the subwindow. Cause: ' + JSON.stringify(err));
return;
}
this.sub_windowClass = data;
console.info('Succeeded in creating the subwindow. Data: ' + JSON.stringify(data));
// 子窗口创建成功后,设置子窗口的位置、大小及相关属性等。
this.sub_windowClass.moveWindowTo(300, 300, (err) => {
if (err.code) {
console.error('Failed to move the window. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in moving the window.');
});
this.sub_windowClass.resize(350, 350, (err) => {
if (err.code) {
console.error('Failed to change the window size. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in changing the window size.');
});
// 为子窗口加载对应的目标页面。
this.sub_windowClass.setUIContent("pages/SubWindow",(err) => {
if (err.code) {
console.error('Failed to load the content. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in loading the content.');
// 显示子窗口。
this.sub_windowClass.showWindow((err) => {
if (err.code) {
console.error('Failed to show the window. Cause: ' + JSON.stringify(err));
return;
}
console.info('Succeeded in showing the window.');
});
this.sub_windowClass.setWindowBackgroundColor('#E8A027')
});
})
}
build() {
Row() {
Column() {
Text(`AppStorage保存的数据:${this.mainData}`)
.margin({bottom:30})
Button('子窗口数据+1')
.backgroundColor('#A4AE77')
.margin({bottom:30})
.onClick(()=>{
// 点击,storData的值加1
this.mainData += 1
})
Button('创建子窗口')
.backgroundColor('#A4AE77')
.onClick(()=>{
// 点击弹出子窗口
this.showSubWindow()
})
}
.width('100%')
}
.height('100%')
}
}
```
子窗口代码:
```ts
// SubWindow.ets
import window from '@ohos.window';
interface Position {
x: number,
y: number
}
@Entry
@Component
struct SubWindow{
// 使用@StorageLink将"subData"与AppStorage中的变量"data"进行双向绑定
@StorageLink('data') subData: number = 1;
// 创建位置变量,并使用@Watch监听,变量发生变化调用moveWindow方法移动窗口
@State @Watch("moveWindow") windowPosition: Position = { x: 0, y: 0 };
private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All });
private subWindow: window.Window
// 通过悬浮窗名称“hiSubWindow”获取到创建的悬浮窗
aboutToAppear() {
this.subWindow = window.findWindow("hiSubWindow")
}
// 将悬浮窗移动到指定位置
moveWindow() {
this.subWindow.moveWindowTo(this.windowPosition.x, this.windowPosition.y);
}
build(){
Column(){
Text(`AppStorage保存的数据:${this.subData}`)
.fontSize(12)
.margin({bottom:10})
Button('主窗口数据+1')
.fontSize(12)
.backgroundColor('#A4AE77')
.onClick(()=>{
// 点击,subData的值加1
this.subData += 1
})
}
.height('100%')
.width('100%')
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.gesture(
PanGesture(this.panOption)
.onActionStart((event: GestureEvent) => {
console.info('Pan start');
})
// 发生拖拽时,获取到触摸点的位置,并将位置信息传递给windowPosition
.onActionUpdate((event: GestureEvent) => {
this.windowPosition.x += event.offsetX;
this.windowPosition.y += event.offsetY;
})
.onActionEnd(() => {
console.info('Pan end');
})
)
}
}
```
## 参考
- [窗口开发](../application-dev/windowmanager/application-window-stage.md)
- [AppStorage:应用全局的UI状态存储](../application-dev/quick-start/arkts-appstorage.md)
\ No newline at end of file
# 转场动画的使用(ArkTs)
## 场景介绍
日常在应用时,经常需要衔接两个场景,或者两个镜头画面之间进行切换,切换时需要呈现一种平滑过渡效果。
本例将为大家介绍下如何通过转场动画实现上述过渡效果。
## 效果呈现
本例最终效果如下:
| 场景 | 效果图 |
| ---------------------------------- | ----------------------------------------------------- |
| 页面间转场--底部滑入转场 | ![BottomTransition.gif](figures/BottomTransition.gif) |
| 页面间转场--自定义1:缩放动画转场 | ![](figures/CustomTransition.gif) |
| 页面间转场---自定义2:旋转动画转场 | ![](figures/FullCustomTransition.gif) |
| 组件内转场 | ![](figures/ComponentTransition.gif) |
| 共享元素转场 | ![](figures/SharePage.gif) |
## 运行环境
本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发:
- IDE: DevEco Studio 4.0 Beta1
- SDK: Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)
## 实现思路
* 构建应用首页,主要由5个相同样式的功能菜单组成,通过添加路由实现主页面与对应功能页面的链接跳转。
* 功能页面的实现
* 页面间转场
* 底部滑入转场
通过给pageTransition()方法定义入场效果PageTransitionEnter以及出场效果PageTransitionExit,同时通过设置slide属性为SlideEffect.Bottom来实现从底部滑入动效。
* 缩放动画转场
通过设置pageTransition方法,配置进行配置转场参数。
* 旋转动画转场
在FullCustomTransition.ets的Column组件中添加TransitionElement组件,并且定义pageTransition方法。给Clomn组件添加opacity、scale、rotate属性,定义变量animValue用来控制Clomn组件的动效,在PageTransitionEnter和PageTransitionExit组件中动态改变myProgress的值,从而控制动画效果。
* 组件间转场
* 通过Image、Column、Text、Button等组件构建ComponentTransition.ets页面。
* 新建一个Image组件,并且添加两个transition属性,分别用于定义组件的插入动效和移除动效,从而实现组件间的转场。
* 设置变量isShow,用来控制上述步骤中Image组件的添加和移除,同时向Button组件的onClick添加animateTo方法,来使ComponentItem子组件动效生效。
* isShow默认状态为false,删除隐藏Image组件,同时删除动效生效。
* 当isShow状态更新为true时,插入Image组件,同时插入动效生效。
* 共享转场
通过给两个页面“SharedItem”和“SharePage” 的Image组件设置sharedTransition属性来实现,两个页面的组件配置为同一个id,则转场过程中会执行共享元素转场效果。
## 开发步骤
1. 创建主界面。
添加媒体资源至resources > base > media目录下。
![Transition-animation-tree.png](figures/Transition-animation-tree.png)
首页Index.ets引入首页列表常量数据:INDEX_ANIMATION_MODE(imgRes:设置按钮的背景图片,url:设置页面路由的地址),通过ForEach方法循环渲染列表常量数据。
具体代码如下:
```ts
// entry/src/main/ets/pages/Index.ets
// 引入列表常量数据INDEX_ANIMATION_MODE
export const INDEX_ANIMATION_MODE = [
{ imgRes: $r('app.media.bg_bottom_anim_transition'), url: 'pages/BottomTransition' },
{ imgRes: $r('app.media.bg_custom1_anim_transition'), url: 'pages/CustomTransition' },
{ imgRes: $r('app.media.bg_custom2_anim_transition'), url: 'pages/FullCustomTransition' },
{ imgRes: $r('app.media.bg_element_anim_transition'), url: 'pages/ComponentTransition' },
{ imgRes: $r('app.media.bg_share_anim_transition'), url: 'pages/ShareItem' }
];
...
Column() {
// ForEach循环渲染
ForEach(INDEX_ANIMATION_MODE, ({ imgRes , url }) => {
Row()
.backgroundImage(imgRes)
.backgroundImageSize(ImageSize.Cover)
.backgroundColor('#00000000')
.height(130)
.margin({ bottom: 30 })
.width('100%')
.borderRadius(32)
.onClick(() => {
router.pushUrl({ url: url })
})
}, item => JSON.stringify(item))
}
```
添加其它组件,以及样式,完成UI构建。
具体代码如下:
```ts
// entry/src/main/ets/pages/Index.ets
import router from '@ohos.router';
import hilog from '@ohos.hilog';
@Entry
@Component
struct Index {
build() {
Column() {
Text($r('app.string.main_page_title'))
.fontSize(30)
.fontWeight(FontWeight.Regular)
.width('100%')
.margin({ top: 13, bottom: 27,left: 24})
Scroll() {
Column() {
ForEach(INDEX_ANIMATION_MODE, ({ imgRes , url }) => {
Row()
.backgroundImage(imgRes)
.backgroundImageSize(ImageSize.Cover)
.backgroundColor('#00000000')
.height(130)
.margin({ bottom: 30 })
.width('100%')
.borderRadius(32)
.onClick(() => {
router.pushUrl({ url: url })
.catch(err => {
hilog.error(0xff00, '[ReadingRecorder]', `%{public}s, %{public}s`, err);
});
})
}, item => JSON.stringify(item))
}
}
.align(Alignment.Top)
.layoutWeight(1)
.scrollBar(BarState.Off)
}
.height('100%')
.backgroundColor('#F1F3F5')
.padding({left:12 , right:12})
}
}
```
2. 实现页面间转场。
* 效果1:底部滑入。
该效果的实现,主要是通过在BottomTransition.ets中设置全局pageTransition()方法,该方法中自定义入场效果PageTransitionEnter以及出场效果PageTransitionExit,同时通过设置slide属性为SlideEffect.Bottom来实现从底部滑入动效。
具体代码如下:
```ts
// entry/src/main/ets/pages/BottomTransition.ets
@Entry
@Component
struct BottomTransition {
private imgRes: string | Resource = $r('app.media.bg_transition');
private imgFit: ImageFit = ImageFit.Fill;
build() {
Column() {
Image(this.imgRes)
.objectFit(this.imgFit)
.width('100%')
.height('100%')
}
}
// 页面转场通过全局pageTransition方法进行配置转场参数
pageTransition() {
// PageTransitionEnter自定义入场效果:设置slide属性为SlideEffect.Bottom 表示入场时从屏幕下方滑入。
PageTransitionEnter({ duration: 600, curve: Curve.Smooth }).slide(SlideEffect.Bottom);
// PageTransitionExit自定义出场效果:设置slide属性为SlideEffect.Bottom 退场时从屏幕下方滑出。
PageTransitionExit({ duration: 600, curve: Curve.Smooth }).slide(SlideEffect.Bottom);
}
}
```
* 效果2:页面入场时淡入和放大,退场时从右下角滑出。
* 在CustomTransition.ets中设置全局pageTransition()方法。
* pageTransition方法中自定义入场效果PageTransitionEnter:透明度设置从0.2到1;x、y轴缩放从0变化到1。
* pageTransition方法中自定义出场效果PageTransitionExit: x、y轴的偏移量为500。
具体代码如下:
```ts
// entry/src/main/ets/pages/CustomTransition.ets
@Entry
@Component
struct CustomTransition {
private imgRes: string | Resource = $r('app.media.bg_transition');
private imgFit: ImageFit = ImageFit.Fill;
build() {
Column() {
Image(this.imgRes)
.objectFit(this.imgFit)
.width('100%')
.height('100%')
}
}
// 页面转场通过全局pageTransition方法进行配置转场参数
pageTransition() {
// 进场时透明度设置从0.2到1;x、y轴缩放从0变化到1
PageTransitionEnter({ duration: 600, curve: Curve.Smooth }).opacity(0.2).scale({ x: 0, y: 0 })
// 退场时x、y轴的偏移量为500
PageTransitionExit({ duration: 600, curve: Curve.Smooth }).translate({ x: 500, y: 500 })
}
}
```
* 效果3:页面入场时淡入和放大,同时顺时针旋转;退场时淡出和缩小,同时逆时针旋转。
* 在FullCustomTransition.ets中添加Column组件。
* 向Column组件添加属性:opacity、scale、rotate,来控制动效的淡入淡出、缩放以及旋转效果。
* 定义变量animValue用来,通过animValue值得变化来控制Column组件的动效。
* 在FullCustomTransition.ets中定义全局pageTransition()方法。
* pageTransition方法中自定义入场效果PageTransitionEnter。
​ animValue值实时变化,0 --> 1,从而渲染 入场时淡入、放大以及顺时针旋转效果。
* pageTransition方法中自定义出场效果PageTransitionExit。
​ animValue值实时变化,1 --> 0,从而渲染 出场时淡出、缩小以及逆时针旋转效果。
具体代码如下:
```ts
// entry/src/main/ets/pages/FullCustomTransition.ets
@Entry
@Component
struct FullCustomTransition {
@State animValue: number = 1;
private imgRes: string | Resource = $r('app.media.bg_transition');
private imgFit: ImageFit = ImageFit.Fill;
build() {
Column() {
Image(this.imgRes)
.objectFit(this.imgFit)
.width('100%')
.height('100%')
}
// 设置淡入、淡出效果
.opacity(this.animValue)
// 设置缩放
.scale({ x: this.animValue, y: this.animValue })
// 设置旋转角度
.rotate({
z: 1,
angle: 360 * this.animValue
})
}
// 页面转场通过全局pageTransition方法进行配置转场参数
pageTransition() {
PageTransitionEnter({ duration: 600, curve: Curve.Smooth })
// 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0 - 1)
.onEnter((type: RouteType, progress: number) => {
// 入场动效过程中,实时更新this.animValue的值
this.animValue = progress
});
PageTransitionExit({ duration: 600, curve: Curve.Smooth })
// 出场过程中会逐帧触发onExit回调,入参为动效的归一化进度(0 - 1)
.onExit((type: RouteType, progress: number) => {
// 入场动效过程中,实时更新this.animValue的值
this.animValue = 1 - progress
});
}
}
```
3. 实现组件内转场。
* 通过Image、Column、Text、Button等组件构建ComponentTransition.ets页面。
具体代码如下:
```ts
// entry/src/main/ets/pages/ComponentTransition.ets
@Entry
@Component
struct ComponentTransition {
build() {
Column() {
Row() {
Image($r('app.media.ic_public_back'))
.width(20)
.height(20)
.responseRegion({width:'100%',height: '100%'})
.onClick(() => {
router.back();
})
Text($r('app.string.Component_transition_header'))
.fontColor(Color.Black)
.fontWeight(FontWeight.Regular)
.fontSize(25)
.margin({left:18,right:18})
}
.height(30)
.width('100%')
.margin({ top: 20, bottom: 27,left: 24})
Image($r('app.media.bg_element'))
.objectFit(ImageFit.Fill)
.borderRadius(20)
.margin({ bottom: 20 })
.width('100%')
.height(300)
Button($r('app.string.Component_transition_toggle'))
.height(40)
.width(120)
.fontColor(Color.White)
.backgroundColor($r('app.color.light_blue'))
}
.padding({left:20,right:20})
.height('100%')
.width('100%')
}
}
```
* 新建一个Image组件,并且添加两个transition属性,分别用于定义组件的插入动效和移除动效,来实现组件转场间。
具体代码如下:
```ts
// entry/src/main/ets/pages/ComponentTransition.ets
...
Image($r('app.media.bg_share'))
.objectFit(ImageFit.Fill)
.borderRadius(20)
.margin({ bottom: 20 })
.height(300)
.width('100%')
// 插入动效
.transition({
type: TransitionType.Insert,
scale: { x: 0.5, y: 0.5 },
opacity: 0
})
// 删除隐藏动效
.transition({
type: TransitionType.Delete,
rotate: { x: 0, y: 1, z: 0, angle: 360 },
opacity: 0
})
```
- 设置变量isShow,用来控制上述步骤中Image组件的添加和移除,同时向Button组件的onClick添加animateTo方法,来使ComponentItem子组件动效生效。
* isShow默认状态为false,删除隐藏Image组件,同时删除动效生效。
* 当isShow状态更新为true时,插入Image组件,同时插入动效生效。
具体代码如下:
```ts
// entry/src/main/ets/pages/ComponentTransition.ets
...
@State isShow: boolean = false;
...
// isShow为True,插入Image组件,同时插入动效生效;isShow为False,删除隐藏Image组件,同时删除动效生效
if (this.isShow) {
Image($r('app.media.bg_share'))
.objectFit(ImageFit.Fill)
.borderRadius(20)
.margin({ bottom: 20 })
.height(300)
.width('100%')
// 插入动效
.transition({
type: TransitionType.Insert,
scale: { x: 0.5, y: 0.5 },
opacity: 0
})
// 删除隐藏动效
.transition({
type: TransitionType.Delete,
rotate: { x: 0, y: 1, z: 0, angle: 360 },
opacity: 0
})
}
...
Button($r('app.string.Component_transition_toggle'))
...
.onClick(() => {
animateTo({ duration: 600 }, () => {
this.isShow = !this.isShow;
})
})
```
ComponentTransition.ets的完整代码如下:
```ts
// entry/src/main/ets/pages/ComponentTransition.ets
import router from '@ohos.router';
@Entry
@Component
struct ComponentTransition {
@State isShow: boolean = false;
build() {
Column() {
// 页面title区域,含返回功能以及title显示
Row() {
Image($r('app.media.ic_public_back'))
.width(20)
.height(20)
.responseRegion({
width:'100%',
height: '100%'
})
.onClick(() => {
router.back();
})
Text($r('app.string.Component_transition_header'))
.fontColor(Color.Black)
.fontWeight(FontWeight.Regular)
.fontSize(25)
.height(300)
.margin({ left:18, right:18 })
}
.height(30)
.width('100%')
.margin({ top: 20, bottom: 27,left: 24})
// 页面内容区域
// isShow为True,插入Image组件,同时插入动效生效;isShow为False,删除隐藏Image组件,同时删除动效生效
if (this.isShow) {
Image($r('app.media.bg_share'))
.objectFit(ImageFit.Fill)
.borderRadius(20)
.margin({ bottom: 20 })
.height(300)
.width('100%')
// 插入动效
.transition({
type: TransitionType.Insert,
scale: { x: 0.5, y: 0.5 },
opacity: 0
})
// 删除隐藏动效
.transition({
type: TransitionType.Delete,
rotate: { x: 0, y: 1, z: 0, angle: 360 },
opacity: 0
})
}
Image($r('app.media.bg_element'))
.objectFit(ImageFit.Fill)
.borderRadius(20)
.margin({ bottom: 20 })
.width('100%')
.height(300)
Button($r('app.string.Component_transition_toggle'))
.height(40)
.width(120)
.fontColor(Color.White)
.backgroundColor($r('app.color.light_blue'))
.onClick(() => {
animateTo({ duration: 600 }, () => {
console.log('console-- ' +this.isShow)
this.isShow = !this.isShow;
})
})
}
.padding({
left:(20),
right:(20)
})
.height('100%')
.width('100%')
}
}
```
4. 实现元素共享转场。
共享元素转场通过给组件设置sharedTransition属性来实现,两个页面的组件配置为同一个id,则转场过程中会执行共享元素转场效果。
* 通过Image、Column、Text等组件构建ShareItem.ets页面,给内容区域的Image组件设置sharedTransition属性标记该元素为共享元素,组件转场id设置为“shareID”, 同时设置共享元素转场效果。
具体代码如下:
```ts
// entry/src/main/ets/pages/ShareItem.ets
import hilog from '@ohos.hilog';
@Entry
@Component
struct ShareItem {
// 自定义页面内容区域
@Builder PreviewArea() {
Column() {
Image($r('app.media.bg_transition'))
.width('100%')
.height(300)
.borderRadius(24)
.margin({ bottom: 12 })
// 设置sharedTransition属性标记该元素为共享元素,转场id为“shareId”
.sharedTransition('shareId', {
duration: 600,
curve: Curve.Smooth,
delay: 100
})
.onClick(() => {
// 路由切换
router.pushUrl({ url: 'pages/SharePage' })
.catch(err => {
hilog.error(0xFF00, '[ReadingRecorder]', `%{public}s, %{public}s`, err);
});
})
Text($r('app.string.Share_Item_hint'))
.width('100%')
.textAlign(TextAlign.Center)
.fontSize(20)
.fontWeight(FontWeight.Regular)
.fontColor($r('app.color.share_item_content_font'))
}
.borderRadius(24)
.backgroundColor(Color.White)
.width('100%')
.padding({ top: 13, left: 12, right: 12,bottom:12})
}
build() {
Column() {
// 页面title区域,含返回功能以及title显示
Row() {
Image($r('app.media.ic_public_back'))
.width(20)
.height(20)
.responseRegion({
width:'100%',
height: '100%'
})
.onClick(() => {
router.back();
})
Text($r('app.string.Share_Item_header'))
.fontColor(Color.Black)
.fontWeight(FontWeight.Regular)
.fontSize(25)
.margin({ left:18, right:18 })
}
.height(30)
.width('100%')
.margin({ top: 20, bottom: 27,left: 24})
this.PreviewArea()
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.grey_light'))
.padding({left:12,right:12})
}
}
```
* pages/SharePage.ets页面中,给Image组件设置sharedTransition属性,同时组件转场id设置为“shareID”,从而可以共享上述步骤的转场动效。
具体代码如下:
```ts
// entry/src/main/ets/pages/SharePage.ets
@Entry
@Component
struct SharePage {
build() {
Column() {
Image($r('app.media.bg_transition'))
.objectFit(ImageFit.Fill)
.width('100%')
.height('100%')
.sharedTransition('shareId', {
duration: 600,
curve: Curve.Smooth,
delay: 100
})
}
}
}
```
## 完整代码
本例完整代码如下:
应用首页: /entry/src/main/ets/pages/Index.ets。
```ts
// entry/src/main/ets/pages/Index.ets
import router from '@ohos.router';
import hilog from '@ohos.hilog';
@Entry
@Component
struct Index {
build() {
Column() {
Text($r('app.string.main_page_title'))
.fontSize(30)
.fontWeight(FontWeight.Regular)
.width('100%')
.margin({ top: 13, bottom: 27,left: 24})
Scroll() {
Column() {
ForEach(INDEX_ANIMATION_MODE, ({ imgRes , url }) => {
Row()
.backgroundImage(imgRes)
.backgroundImageSize(ImageSize.Cover)
.backgroundColor('#00000000')
.height(130)
.margin({ bottom: 30 })
.width('100%')
.borderRadius(32)
.onClick(() => {
router.pushUrl({ url: url })
.catch(err => {
hilog.error(0xff00, '[ReadingRecorder]', `%{public}s, %{public}s`, err);
});
})
}, item => JSON.stringify(item))
}
}
.align(Alignment.Top)
.layoutWeight(1)
.scrollBar(BarState.Off)
}
.height('100%')
.backgroundColor('#F1F3F5')
.padding({left:12 , right:12})
}
}
```
底部滑出页面:/entry/src/main/ets/pages/BottomTransition.ets。
```ts
// entry/src/main/ets/pages/BottomTransition.ets
@Entry
@Component
struct BottomTransition {
private imgRes: string | Resource = $r('app.media.bg_transition');
private imgFit: ImageFit = ImageFit.Fill;
build() {
Column() {
Image(this.imgRes)
.objectFit(this.imgFit)
.width('100%')
.height('100%')
}
}
// 页面转场通过全局pageTransition方法进行配置转场参数
pageTransition() {
// PageTransitionEnter自定义入场效果:设置slide属性为SlideEffect.Bottom 表示入场时从屏幕下方滑入。
PageTransitionEnter({ duration: 600, curve: Curve.Smooth }).slide(SlideEffect.Bottom);
// PageTransitionExit自定义出场效果:设置slide属性为SlideEffect.Bottom 退场时从屏幕下方滑出。
PageTransitionExit({ duration: 600, curve: Curve.Smooth }).slide(SlideEffect.Bottom);
}
}
```
自定义1 缩放动画转场页面:/entry/src/main/ets/pages/CustomTransition.ets。
```ts
// entry/src/main/ets/pages/CustomTransition.ets
@Entry
@Component
struct CustomTransition {
private imgRes: string | Resource = $r('app.media.bg_transition');
private imgFit: ImageFit = ImageFit.Fill;
build() {
Column() {
Image(this.imgRes)
.objectFit(this.imgFit)
.width('100%')
.height('100%')
}
}
// 页面转场通过全局pageTransition方法进行配置转场参数
pageTransition() {
// 进场时透明度设置从0.2到1;x、y轴缩放从0变化到1
PageTransitionEnter({ duration: 600, curve: Curve.Smooth }).opacity(0.2).scale({ x: 0, y: 0 })
// 退场时x、y轴的偏移量为500
PageTransitionExit({ duration: 600, curve: Curve.Smooth }).translate({ x: 500, y: 500 })
}
}
```
自定义2 旋转动画转场: /entry/src/main/ets/pages/FullCustomTransition.ets。
```ts
@Entry
@Component
struct FullCustomTransition {
@State animValue: number = 1;
private imgRes: string | Resource = $r('app.media.bg_transition');
private imgFit: ImageFit = ImageFit.Fill;
build() {
Column() {
Image(this.imgRes)
.objectFit(this.imgFit)
.width('100%')
.height('100%')
}
// 设置淡入、淡出效果
.opacity(this.animValue)
// 设置缩放
.scale({ x: this.animValue, y: this.animValue })
// 设置旋转角度
.rotate({
z: 1,
angle: 360 * this.animValue
})
}
// 页面转场通过全局pageTransition方法进行配置转场参数
pageTransition() {
PageTransitionEnter({ duration: 600, curve: Curve.Smooth })
// 进场过程中会逐帧触发onEnter回调,入参为动效的归一化进度(0 - 1)
.onEnter((type: RouteType, progress: number) => {
// 入场动效过程中,实时更新this.animValue的值
this.animValue = progress
});
PageTransitionExit({ duration: 600, curve: Curve.Smooth })
// 出场过程中会逐帧触发onExit回调,入参为动效的归一化进度(0 - 1)
.onExit((type: RouteType, progress: number) => {
// 入场动效过程中,实时更新this.animValue的值
this.animValue = 1 - progress
});
}
}
```
组件内转场页面: /entry/src/main/ets/pages/ComponentTransition.ets。
```ts
import router from '@ohos.router';
@Entry
@Component
struct ComponentTransition {
@State isShow: boolean = false;
build() {
Column() {
// 页面title区域,含返回功能以及title显示
Row() {
Image($r('app.media.ic_public_back'))
.width(20)
.height(20)
.responseRegion({
width:'100%',
height: '100%'
})
.onClick(() => {
router.back();
})
Text($r('app.string.Component_transition_header'))
.fontColor(Color.Black)
.fontWeight(FontWeight.Regular)
.fontSize(25)
.margin({left:18, right:18})
}
.height(30)
.width('100%')
.margin({ top: 20, bottom: 27,left: 24})
// 页面内容区域
// isShow为True,插入Image组件,同时插入动效生效;isShow为False,删除隐藏Image组件,同时删除动效生效
if (this.isShow) {
Image($r('app.media.bg_share'))
.objectFit(ImageFit.Fill)
.borderRadius(20)
.margin({ bottom: 20 })
.height(300)
.width('100%')
// 插入动效
.transition({
type: TransitionType.Insert,
scale: { x: 0.5, y: 0.5 },
opacity: 0
})
// 删除隐藏动效
.transition({
type: TransitionType.Delete,
rotate: { x: 0, y: 1, z: 0, angle: 360 },
opacity: 0
})
}
Image($r('app.media.bg_element'))
.objectFit(ImageFit.Fill)
.borderRadius(20)
.margin({ bottom: 20 })
.width('100%')
.height(300)
Button($r('app.string.Component_transition_toggle'))
.height(40)
.width(120)
.fontColor(Color.White)
.backgroundColor($r('app.color.light_blue'))
.onClick(() => {
animateTo({ duration: 600 }, () => {
this.isShow = !this.isShow;
})
})
}
.padding({left:20,right:20})
.height('100%')
.width('100%')
}
}
```
共享元素转场部件:/entry/src/main/ets/pages/ShareItem.ets。
```ts
import hilog from '@ohos.hilog';
@Entry
@Component
struct ShareItem {
// 自定义页面内容区域
@Builder PreviewArea() {
Column() {
Image($r('app.media.bg_transition'))
.width('100%')
.height(300)
.borderRadius(24)
.margin({ bottom: 12 })
// 设置sharedTransition属性标记该元素为共享元素,转场id为“shareId”
.sharedTransition('shareId', {
duration: 600,
curve: Curve.Smooth,
delay: 100
})
.onClick(() => {
// 路由切换
router.pushUrl({ url: 'pages/SharePage' })
.catch(err => {
hilog.error(0xFF00, '[ReadingRecorder]', `%{public}s, %{public}s`, err);
});
})
Text($r('app.string.Share_Item_hint'))
.width('100%')
.textAlign(TextAlign.Center)
.fontSize(20)
.fontWeight(FontWeight.Regular)
.fontColor($r('app.color.share_item_content_font'))
}
.borderRadius(24)
.backgroundColor(Color.White)
.width('100%')
.padding({ top: 13, left: 12, right: 12,bottom:12})
}
build() {
Column() {
// 页面title区域,含返回功能以及title显示
Row() {
Image($r('app.media.ic_public_back'))
.width(20)
.height(20)
.responseRegion({
width:'100%',
height: '100%'
})
.onClick(() => {
router.back();
})
Text($r('app.string.Share_Item_header'))
.fontColor(Color.Black)
.fontWeight(FontWeight.Regular)
.fontSize(25)
.margin({ left:18, right:18 })
}
.height(30)
.width('100%')
.margin({ top: 20, bottom: 27,left: 24})
this.PreviewArea()
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.grey_light'))
.padding({left:12,right:12})
}
}
```
共享元素转场页面:/entry/src/main/ets/pages/SharePage.ets。
```ts
@Entry
@Component
struct SharePage {
build() {
Column() {
Image($r('app.media.bg_transition'))
.objectFit(ImageFit.Fill)
.width('100%')
.height('100%')
.sharedTransition('shareId', {
duration: 600,
curve: Curve.Smooth,
delay: 100
})
}
}
}
```
## 参考
- [图形变换](../application-dev/reference/arkui-ts/ts-universal-attributes-transformation.md)
- [页面间转场](../application-dev/reference/arkui-ts/ts-page-transition-animation.md)
- [组件内转场](../application-dev/ui/arkts-shared-element-transition.md)
- [共享元素转场](../application-dev/reference/arkui-ts/ts-transition-animation-shared-elements.md)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册