提交 e9202bc2 编写于 作者: L limeng

Merge remote-tracking branch 'upstream/master' into OffscreenCanvas

......@@ -17,7 +17,6 @@
- ExtensionAbility Component
- [ExtensionAbility Component Overview](extensionability-overview.md)
- [ServiceExtensionAbility](serviceextensionability.md)
- [DataShareExtensionAbility (for System Applications Only)](datashareextensionability.md)
- [AccessibilityExtensionAbility](accessibilityextensionability.md)
- [EnterpriseAdminExtensionAbility](enterprise-extensionAbility.md)
- [InputMethodExtensionAbility](inputmethodextentionability.md)
......@@ -37,9 +36,9 @@
- [Applying Custom Drawing in the Widget](arkts-ui-widget-page-custom-drawing.md)
- Widget Event Development
- [Widget Event Capability Overview](arkts-ui-widget-event-overview.md)
- [Redirecting to a Specified Page Through the Router Event](arkts-ui-widget-event-router.md)
- [Updating Widget Content Through FormExtensionAbility](arkts-ui-widget-event-formextensionability.md)
- [Updating Widget Content Through UIAbility](arkts-ui-widget-event-uiability.md)
- [Redirecting to a Specified Page Through the Router Event](arkts-ui-widget-event-router.md)
- Widget Data Interaction
- [Widget Data Interaction Overview](arkts-ui-widget-interaction-overview.md)
- [Configuring a Widget to Update Periodically](arkts-ui-widget-update-by-time.md)
......@@ -62,8 +61,8 @@
- [Cross-Device Migration (for System Applications Only)](hop-cross-device-migration.md)
- [Multi-device Collaboration (for System Applications Only)](hop-multi-device-collaboration.md)
- [Subscribing to System Environment Variable Changes](subscribe-system-environment-variable-changes.md)
- IPC
- [Process Model](process-model-stage.md)
- Process Model
- [Process Model Overview](process-model-stage.md)
- Common Events
- [Introduction to Common Events](common-event-overview.md)
- Common Event Subscription
......@@ -74,13 +73,13 @@
- [Publishing Common Events](common-event-publish.md)
- [Removing Sticky Common Events](common-event-remove-sticky.md)
- [Background Services](background-services.md)
- Inter-Thread Communication
- [Thread Model](thread-model-stage.md)
- Thread Model
- [Thread Model Overview](thread-model-stage.md)
- [Using Emitter for Inter-Thread Communication](itc-with-emitter.md)
- [Using Worker for Inter-Thread Communication](itc-with-worker.md)
- Mission Management
- [Mission Management Scenarios](mission-management-overview.md)
- [Mission Management and Launch Type](mission-management-launch-type.md)
- [Mission and Launch Type](mission-management-launch-type.md)
- [Page Stack and MissionList](page-mission-stack.md)
- [Setting the Icon and Name of a Mission Snapshot](mission-set-icon-name-for-task-snapshot.md)
- [Application Configuration File](config-file-stage.md)
......@@ -120,12 +119,12 @@
- [Context](application-context-fa.md)
- [Want](want-fa.md)
- [Component Startup Rules](component-startup-rules-fa.md)
- IPC
- [Process Model](process-model-fa.md)
- Process Model
- [Process Model Overview](process-model-fa.md)
- [Common Events](common-event-fa.md)
- [Background Services](rpc.md)
- Inter-Thread Communication
- [Thread Model](thread-model-fa.md)
- Thread Model
- [Thread Model Overview](thread-model-fa.md)
- [Inter-Thread Communication](itc-fa-overview.md)
- [Mission Management](mission-management-fa.md)
- [Application Configuration File](config-file-fa.md)
......
......@@ -4,7 +4,7 @@
Generally, local images or online images downloaded from the network need to be displayed on a widget. To obtain local and online images, use the FormExtensionAbility. The following exemplifies how to show local and online images on a widget.
1. Internet access is required for downloading online images. Therefore, you need to apply for the **ohos.permission.INTERNET** permission. For details, see[Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md).
1. Internet access is required for downloading online images. Therefore, you need to apply for the **ohos.permission.INTERNET** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md).
2. Update local files in the **onAddForm** lifecycle callback of the EntryFormAbility.
......
# DataShareExtensionAbility (for System Applications Only)
DataShareExtensionAbility provides the data sharing capability. System applications can implement a DataShareExtensionAbility or access an existing DataShareExtensionAbility in the system. Third-party applications can only access an existing DataShareExtensionAbility. For details, see [Cross-Application Data Sharing Overview](../database/share-device-data-across-apps-overview.md).
# Mission Management and Launch Type
# Mission and Launch Type
One UIAbility instance corresponds to one mission. The number of UIAbility instances is related to the UIAbility launch type, specified by **launchType**, which is configured in the **config.json** file in the FA model and the [module.json5](../quick-start/module-configuration-file.md) file in the stage model.
......@@ -11,13 +11,13 @@ The following describes how the mission list manager manages the UIAbility insta
![mission-and-singleton](figures/mission-and-singleton.png)
- **multiton**: Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, a **UIAbility** instance is created in the application process.
- **multiton**: Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, a UIAbility instance is created in the application process.
**Figure 2** Missions and multiton mode
![mission-and-multiton](figures/mission-and-multiton.png)
- **specified**: The ([onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)) method of [AbilityStage](abilitystage.md) determines whether to create an instance.
- **specified**: The ([onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant)) method of [AbilityStage](abilitystage.md) determines whether to create a UIAbility instance.
**Figure 3** Missions and specified mode
......
......@@ -4,7 +4,7 @@
Before getting started with the development of mission management, be familiar with the following concepts related to mission management:
- AbilityRecord: minimum unit for the system service to manage a UIAbility instance. It corresponds to a UIAbility component instance of an application.
- AbilityRecord: minimum unit for the system service to manage a UIAbility instance. It corresponds to a UIAbility component instance of an application. A maximum of 512 UIAbility instances can be managed on the system service side.
- MissionRecord: minimum unit for mission management. One MissionRecord has only one AbilityRecord. In other words, a UIAbility component instance corresponds to a mission.
......@@ -30,42 +30,42 @@ Missions are managed by system applications (such as home screen), rather than t
A UIAbility instance corresponds to an independent mission. Therefore, when an application calls [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to start a UIAbility, a mission is created.
To call [missionManager](../reference/apis/js-apis-application-missionManager.md) to manage missions, the home screen application must request the **ohos.permission.MANAGE_MISSIONS** permission. For details about the configuration, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
1. To call [missionManager](../reference/apis/js-apis-application-missionManager.md) to manage missions, the home screen application must request the **ohos.permission.MANAGE_MISSIONS** permission. For details about the configuration, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
You can use **missionManager** to manage missions, for example, listening for mission changes, obtaining mission information or snapshots, and clearing, locking, or unlocking missions.
2. You can use **missionManager** to manage missions, for example, listening for mission changes, obtaining mission information or snapshots, and clearing, locking, or unlocking missions.
```ts
import missionManager from '@ohos.app.ability.missionManager'
let listener = {
// Listen for mission creation.
onMissionCreated: function (mission) {
console.info("--------onMissionCreated-------")
},
// Listen for mission destruction.
onMissionDestroyed: function (mission) {
console.info("--------onMissionDestroyed-------")
},
// Listen for mission snapshot changes.
onMissionSnapshotChanged: function (mission) {
console.info("--------onMissionSnapshotChanged-------")
},
// Listen for switching the mission to the foreground.
onMissionMovedToFront: function (mission) {
console.info("--------onMissionMovedToFront-------")
},
// Listen for mission icon changes.
onMissionIconUpdated: function (mission, icon) {
console.info("--------onMissionIconUpdated-------")
},
// Listen for mission name changes.
onMissionLabelUpdated: function (mission) {
console.info("--------onMissionLabelUpdated-------")
},
// Listen for mission closure events.
onMissionClosed: function (mission) {
console.info("--------onMissionClosed-------")
}
// Listen for mission creation.
onMissionCreated: function (mission) {
console.info("--------onMissionCreated-------")
},
// Listen for mission destruction.
onMissionDestroyed: function (mission) {
console.info("--------onMissionDestroyed-------")
},
// Listen for mission snapshot changes.
onMissionSnapshotChanged: function (mission) {
console.info("--------onMissionSnapshotChanged-------")
},
// Listen for switching the mission to the foreground.
onMissionMovedToFront: function (mission) {
console.info("--------onMissionMovedToFront-------")
},
// Listen for mission icon changes.
onMissionIconUpdated: function (mission, icon) {
console.info("--------onMissionIconUpdated-------")
},
// Listen for mission name changes.
onMissionLabelUpdated: function (mission) {
console.info("--------onMissionLabelUpdated-------")
},
// Listen for mission closure events.
onMissionClosed: function (mission) {
console.info("--------onMissionClosed-------")
}
};
// 1. Register a mission change listener.
......@@ -73,56 +73,56 @@ You can use **missionManager** to manage missions, for example, listening for mi
// 2. Obtain the latest 20 missions in the system.
missionManager.getMissionInfos("", 20, (error, missions) => {
console.info("getMissionInfos is called, error.code = " + error.code);
console.info("size = " + missions.length);
console.info("missions = " + JSON.stringify(missions));
console.info("getMissionInfos is called, error.code = " + error.code);
console.info("size = " + missions.length);
console.info("missions = " + JSON.stringify(missions));
});
// 3. Obtain the detailed information about a mission.
let missionId = 11; // The mission ID 11 is only an example.
let mission = missionManager.getMissionInfo("", missionId).catch(function (err) {
console.info(err);
console.info(err);
});
// 4. Obtain the mission snapshot.
missionManager.getMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
console.info("getMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
})
// 5. Obtain the low-resolution mission snapshot.
missionManager.getLowResolutionMissionSnapShot("", missionId, (error, snapshot) => {
console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code);
console.info("bundleName = " + snapshot.ability.bundleName);
})
// 6. Lock or unlock the mission.
missionManager.lockMission(missionId).then(() => {
console.info("lockMission is called ");
console.info("lockMission is called ");
});
missionManager.unlockMission(missionId).then(() => {
console.info("unlockMission is called ");
console.info("unlockMission is called ");
});
// 7. Switch the mission to the foreground.
missionManager.moveMissionToFront(missionId).then(() => {
console.info("moveMissionToFront is called ");
console.info("moveMissionToFront is called ");
});
// 8. Clear a single mission.
missionManager.clearMission(missionId).then(() => {
console.info("clearMission is called ");
console.info("clearMission is called ");
});
// 9. Clear all missions.
missionManager.clearAllMissions().catch(function (err) {
console.info(err);
console.info(err);
});
// 10. Deregister the mission change listener.
missionManager.off('mission', listenerId, (error) => {
console.info("unregisterMissionListener");
console.info("unregisterMissionListener");
})
```
......
# Process Model (FA Model)
# Process Model Overview (FA Model)
The OpenHarmony process model is shown below.
......
# Process Model (Stage Model)
# Process Model Overview (Stage Model)
The OpenHarmony process model is shown below.
......
# Thread Model (FA Model)
# Thread Model Overview (FA Model)
There are three types of threads in the FA model:
- Main thread
Manages other threads.
Manages other threads.
- Ability thread
- One ability thread for each ability.
- Distributes input events.
......@@ -19,10 +17,8 @@ Manages other threads.
Performs time-consuming operations
Based on the OpenHarmony thread model, different services run on different threads. Service interaction requires inter-thread communication. Threads can communicate with each other in Emitter or Worker mode. Emitter is mainly used for event synchronization between threads, and Worker is mainly used to execute time-consuming tasks.
> **NOTE**
>
> The FA model provides an independent thread for each ability. Emitter is mainly used for event synchronization within the ability thread, between a pair of ability threads, or between the ability thread and worker thread.
# Thread Model (Stage Model)
# Thread Model Overview (Stage Model)
For an OpenHarmony application, each process has a main thread to provide the following functionalities:
......
......@@ -3,7 +3,7 @@
## When to Use
According to big data statistics, in a typical cross-application data access scenario, applications are started nearly 83 times on average in a day.
In a typical cross-application data access scenario, an application may be started multiple times.
To reduce the number of application startup times and improve the access speed, OpenHarmony provides the silent access feature, which allows direct access to the database without starting the data provider.
......
......@@ -37,15 +37,28 @@ The **FilePicker** provides the following interfaces by file type:
Use [PhotoSelectResult](../reference/apis/js-apis-file-picker.md#photoselectresult) to return a result set. Further operations on the selected files can be performed based on the file URIs in the result set.
```ts
let uri = null;
const photoPicker = new picker.PhotoViewPicker();
photoPicker.select(photoSelectOptions)
.then(async (photoSelectResult) => {
let uri = photoSelectResult.photoUris[0];
// Perform operations on the files based on the file URIs obtained.
})
.catch((err) => {
console.error(`Invoke documentPicker.select failed, code is ${err.code}, message is ${err.message}`);
})
photoPicker.select(photoSelectOptions).then((photoSelectResult) => {
uri = photoSelectResult.photoUris[0];
}).catch((err) => {
console.error(`Invoke photoPicker.select failed, code is ${err.code}, message is ${err.message}`);
})
```
5. After the GUI is returned from FilePicker, use [**fs.openSync**](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD.
```ts
let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
console.info('file fd: ' + file.fd);
```
6. Use [fs.writeSync](../reference/apis/js-apis-file-fs.md#writesync) to write data to the file based on the FD, and then close the FD.
```ts
let writeLen = fs.writeSync(file.fd, 'hello, world');
console.info('write data to file succeed and size is:' + writeLen);
fs.closeSync(file);
```
## Selecting Documents
......@@ -63,23 +76,69 @@ The **FilePicker** provides the following interfaces by file type:
```
3. Create a **documentViewPicker** instance, and call [**select()**](../reference/apis/js-apis-file-picker.md#select-3) to open the **FilePicker** page for the user to select documents.
After the documents are selected successfully, a result set containing the file URIs is returned. Further operations can be performed on the documents based on the file URIs.
For example, you can use [file management APIs](../reference/apis/js-apis-file-fs.md) to obtain file attribute information, such as the file size, access time, and last modification time, based on the URI. If you need to obtain the file name, use [startAbilityForResult](../../application-dev/application-models/uiability-intra-device-interaction.md).
> **NOTE**
>
> Currently, **DocumentSelectOptions** is not configurable. By default, all types of user files are selected.
```ts
let uri = null;
const documentViewPicker = new picker.DocumentViewPicker(); // Create a documentViewPicker instance.
documentViewPicker.select(documentSelectOptions)
.then((documentSelectResult) => {
let uri = documentSelectResult[0];
// Perform operations on the documents based on the file URIs.
})
.catch((err) => {
console.error(`Invoke documentPicker.select failed, code is ${err.code}, message is ${err.message}`);
})
documentViewPicker.select(documentSelectOptions).then((documentSelectResult) => {
uri = documentSelectResult[0];
}).catch((err) => {
console.error(`Invoke documentPicker.select failed, code is ${err.code}, message is ${err.message}`);
})
```
> **NOTE**
>
> Currently, **DocumentSelectOptions** does not provide the method for obtaining the file name. To obtain the file name, use **startAbilityForResult()**.
```ts
let config = {
action: 'ohos.want.action.OPEN_FILE',
parameters: {
startMode: 'choose',
}
}
try {
let result = await context.startAbilityForResult(config, {windowMode: 1});
if (result.resultCode !== 0) {
console.error(`DocumentPicker.select failed, code is ${result.resultCode}, message is ${result.want.parameters.message}`);
return;
}
// Obtain the URI of the document.
let select_item_list = result.want.parameters.select_item_list;
// Obtain the name of the document.
let file_name_list = result.want.parameters.file_name_list;
} catch (err) {
console.error(`Invoke documentPicker.select failed, code is ${err.code}, message is ${err.message}`);
}
```
4. After the GUI is returned from FilePicker, use [**fs.openSync**](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD.
```ts
let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
console.info('file fd: ' + file.fd);
```
5. Use [fs.readSync](../reference/apis/js-apis-file-fs.md#readsync) to read data from the file based on the FD, and then close the FD.
```ts
let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
let buf = new ArrayBuffer(4096);
let num = fs.readSync(file.fd, buf);
console.info('read data to file succeed and size is:' + num);
fs.closeSync(file);
```
## Selecting an Audio File
1. Import the **FilePicker** module.
......@@ -105,13 +164,26 @@ The **FilePicker** provides the following interfaces by file type:
> Currently, **AudioSelectOptions** is not configurable. By default, all types of user files are selected.
```ts
let uri = null;
const audioViewPicker = new picker.AudioViewPicker();
audioViewPicker.select(audioSelectOptions)
.then(audioSelectResult => {
let uri = audioSelectOptions[0];
// Perform operations on the audio files based on the file URIs.
})
.catch((err) => {
console.error(`Invoke audioPicker.select failed, code is ${err.code}, message is ${err.message}`);
})
audioViewPicker.select(audioSelectOptions).then(audioSelectResult => {
uri = audioSelectOptions[0];
}).catch((err) => {
console.error(`Invoke audioPicker.select failed, code is ${err.code}, message is ${err.message}`);
})
```
4. After the GUI is returned from FilePicker, use [**fs.openSync**](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD.
```ts
let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
console.info('file fd: ' + file.fd);
```
5. Use [fs.writeSync](../reference/apis/js-apis-file-fs.md#writesync) to write data to the file based on the FD, and then close the FD.
```ts
let writeLen = fs.writeSync(file.fd, 'hello, world');
console.info('write data to file succeed and size is:' + writeLen);
fs.closeSync(file);
```
......@@ -12,7 +12,7 @@ You can use the related APIs to [share a file with another application](#sharing
The file URIs are in the following format:
file://<bundleName>/<path>/\#networkid=<networkid>
file://<bundleName>/<path>
- **file**: indicates a file URI.
......@@ -20,8 +20,6 @@ The file URIs are in the following format:
- *path*: specifies the application sandbox path of the file.
- *networkid* (optional): specifies the device to which the file belongs in a distributed file system. Leave this parameter unspecified if the file location does not need to be set.
## Sharing a File with Another Application
Before sharing application files, you need to [obtain the application file path](../application-models/application-context-stage.md#obtaining-the-application-development-path).
......
......@@ -14,7 +14,7 @@ The audio interruption policy determines the operations (for example, pause, res
Two audio interruption modes, specified by [InterruptMode](../reference/apis/js-apis-audio.md#interruptmode9), are preset in the audio interruption policy:
- **SHARED_MODE**: Multiple audio streams created by an application share one audio focus. The concurrency rules between these audio streams are determined by the application, without the use of the audio interruption policy. However, if another application needs to play audio while one of these audio streams is being played, the audio interruption policy is triggered.
- **SHARE_MODE**: Multiple audio streams created by an application share one audio focus. The concurrency rules between these audio streams are determined by the application, without the use of the audio interruption policy. However, if another application needs to play audio while one of these audio streams is being played, the audio interruption policy is triggered.
- **INDEPENDENT_MODE**: Each audio stream created by an application has an independent audio focus. When multiple audio streams are played concurrently, the audio interruption policy is triggered.
......
......@@ -8,7 +8,7 @@ OpenHarmony provides multiple classes for you to develop audio playback applicat
- [AudioRenderer](using-audiorenderer-for-playback.md): provides ArkTS and JS API to implement audio output. It supports only the PCM format and requires applications to continuously write audio data. The applications can perform data preprocessing, for example, setting the sampling rate and bit width of audio files, before audio input. This class can be used to develop more professional and diverse playback applications. To use this class, you must have basic audio processing knowledge.
- [OpenSLES](using-opensl-es-for-playback.md): provides a set of standard, cross-platform, yet unique native audio APIs. It supports audio output in PCM format and is applicable to playback applications that are ported from other embedded platforms or that implements audio output at the native layer.
- [OpenSL ES](using-opensl-es-for-playback.md): provides a set of standard, cross-platform, yet unique native audio APIs. It supports audio output in PCM format and is applicable to playback applications that are ported from other embedded platforms or that implements audio output at the native layer.
- [TonePlayer](using-toneplayer-for-playback.md): provides ArkTS and JS API to implement the playback of dialing tones and ringback tones. It can be used to play the content selected from a fixed type range, without requiring the input of media assets or audio data. This class is application to specific scenarios where dialing tones and ringback tones are played. is available only to system applications.
......
......@@ -8,7 +8,7 @@ OpenHarmony provides multiple classes for you to develop audio recording applica
- [AudioCapturer](using-audiocapturer-for-recording.md): provides ArkTS and JS API to implement audio input. It supports only the PCM format and requires applications to continuously read audio data. The application can perform data processing after audio output. This class can be used to develop more professional and diverse recording applications. To use this class, you must have basic audio processing knowledge.
- [OpenSLES](using-opensl-es-for-recording.md): provides a set of standard, cross-platform, yet unique native audio APIs. It supports audio input in PCM format and is applicable to recording applications that are ported from other embedded platforms or that implements audio input at the native layer.
- [OpenSL ES](using-opensl-es-for-recording.md): provides a set of standard, cross-platform, yet unique native audio APIs. It supports audio input in PCM format and is applicable to recording applications that are ported from other embedded platforms or that implements audio input at the native layer.
## Precautions for Developing Audio Recording Applications
......
......@@ -59,6 +59,7 @@ The table below lists the supported protocols.
| -------- | -------- |
| Local VOD| The file descriptor is supported, but the file path is not.|
| Network VoD| HTTP, HTTPS, and HLS are supported.|
| Live webcasting| HLS is supported.|
The table below lists the supported audio playback formats.
......
......@@ -2,7 +2,7 @@
## Multimedia Subsystem Architecture
The multimedia subsystem provides the capability of processing users' visual and auditory information. For example, it can be used to collect, compress, store, decompress, and play audio and video information. Based on the type of media information to process, the media system is usually divided into four modules: audio, media, camera, and image.
The multimedia subsystem provides the capability of processing users' visual and auditory information. For example, it can be used to collect, compress, store, decompress, and play audio and video information. Based on the type of media information to process, the multimedia subsystem subsystem is usually divided into four modules: audio, media, camera, and image.
As shown in the figure below, the multimedia subsystem provides APIs for developing audio/video, camera, and gallery applications, and provides adaptation and acceleration for different hardware chips. In the middle part, it provides core media functionalities and management mechanisms in the form of services.
......
......@@ -151,9 +151,6 @@ export default class AudioRendererDemo {
console.info(`${TAG}: creating AudioRenderer success`);
this.renderModel = renderer;
this.renderModel.on('stateChange', (state) => { // Set the events to listen for. A callback is invoked when the AudioRenderer is switched to the specified state.
if (state == 1) {
console.info('audio renderer state is: STATE_PREPARED');
}
if (state == 2) {
console.info('audio renderer state is: STATE_RUNNING');
}
......
......@@ -12,7 +12,7 @@ During application development, you can use the **state** attribute of the AVPla
**Figure 1** Playback state transition
![Playback state change](figures/playback-status-change.png)
![Playback status change](figures/playback-status-change.png)
For details about the state, see [AVPlayerState](../reference/apis/js-apis-media.md#avplayerstate9). When the AVPlayer is in the **prepared**, **playing**, **paused**, or **completed** state, the playback engine is working and a large amount of RAM is occupied. If your application does not need to use the AVPlayer, call **reset()** or **release()** to release the instance.
......@@ -68,7 +68,9 @@ import common from '@ohos.app.ability.common';
export class AVPlayerDemo {
private avPlayer;
private count: number = 0;
private isSeek: boolean = true; // Specify whether the seek operation is supported.
private fileSize: number = -1;
private fd: number = 0;
// Set AVPlayer callback functions.
setAVPlayerCallback() {
// Callback function for the seek operation.
......@@ -102,8 +104,13 @@ export class AVPlayerDemo {
case 'playing': // This state is reported upon a successful callback of play().
console.info('AVPlayer state playing called.');
if (this.count !== 0) {
console.info('AVPlayer start to seek.');
this.avPlayer.seek (this.avPlayer.duration); // Call seek() to seek to the end of the audio clip.
if (this.isSeek) {
console.info('AVPlayer start to seek.');
this.avPlayer.seek (this.avPlayer.duration); // Call seek() to seek to the end of the audio clip.
} else {
// When the seek operation is not supported, the playback continues until it reaches the end.
console.info('AVPlayer wait to play end.');
}
} else {
this.avPlayer.pause(); // Call pause() to pause the playback.
}
......@@ -145,6 +152,7 @@ export class AVPlayerDemo {
// Open the corresponding file address to obtain the file descriptor and assign a value to the URL to trigger the reporting of the initialized state.
let file = await fs.open(path);
fdPath = fdPath + '' + file.fd;
this.isSeek = true; // The seek operation is supported.
this.avPlayer.url = fdPath;
}
......@@ -158,10 +166,85 @@ export class AVPlayerDemo {
// The return type is {fd,offset,length}, where fd indicates the file descriptor address of the HAP file, offset indicates the media asset offset, and length indicates the duration of the media asset to play.
let context = getContext(this) as common.UIAbilityContext;
let fileDescriptor = await context.resourceManager.getRawFd('01.mp3');
this.isSeek = true; // The seek operation is supported.
// Assign a value to fdSrc to trigger the reporting of the initialized state.
this.avPlayer.fdSrc = fileDescriptor;
}
// The following demo shows how to use the file system to open the sandbox address, obtain the media file address, and play the media file with the seek operation using the dataSrc attribute.
async avPlayerDataSrcSeekDemo() {
// Create an AVPlayer instance.
this.avPlayer = await media.createAVPlayer();
// Set a callback function for state changes.
this.setAVPlayerCallback();
// dataSrc indicates the playback source address. When the seek operation is supported, fileSize indicates the size of the file to be played. The following describes how to assign a value to fileSize.
let src = {
fileSize: -1,
callback: (buf, length, pos) => {
let num = 0;
if (buf == undefined || length == undefined || pos == undefined) {
return -1;
}
num = fs.readSync(this.fd, buf, { offset: pos, length: length });
if (num > 0 && (this.fileSize >= pos)) {
return num;
}
return -1;
}
}
let context = getContext(this) as common.UIAbilityContext;
// Obtain the sandbox address filesDir through UIAbilityContext. The stage model is used as an example.
let pathDir = context.filesDir;
let path = pathDir + '/01.mp3';
await fs.open(path).then((file) => {
this.fd = file.fd;
})
// Obtain the size of the file to be played.
this.fileSize = fs.statSync(path).size;
src.fileSize = this.fileSize;
this.isSeek = true; // The seek operation is supported.
this.avPlayer.dataSrc = src;
}
// The following demo shows how to use the file system to open the sandbox address, obtain the media file address, and play the media file without the seek operation using the dataSrc attribute.
async avPlayerDataSrcNoSeekDemo() {
// Create an AVPlayer instance.
this.avPlayer = await media.createAVPlayer();
// Set a callback function for state changes.
this.setAVPlayerCallback();
let context = getContext(this) as common.UIAbilityContext;
let src: object = {
fileSize: -1,
callback: (buf, length, pos) => {
let num = 0;
if (buf == undefined || length == undefined) {
return -1;
}
num = fs.readSync(this.fd, buf);
if (num > 0) {
return num;
}
return -1;
}
}
// Obtain the sandbox address filesDir through UIAbilityContext. The stage model is used as an example.
let pathDir = context.filesDir;
let path = pathDir + '/01.mp3';
await fs.open(path).then((file) => {
this.fd = file.fd;
})
this.isSeek = false; // The seek operation is not supported.
this.avPlayer.dataSrc = src;
}
// The following demo shows how to play live streams by setting the network address through the URL.
async avPlayerLiveDemo() {
// Create an AVPlayer instance.
this.avPlayer = await media.createAVPlayer();
// Set a callback function for state changes.
this.setAVPlayerCallback();
this.isSeek = false; // The seek operation is not supported.
this.avPlayer.url = 'http://xxx.xxx.xxx.xxx:xx/xx/index.m3u8';
}
}
```
<!--no_check-->
\ No newline at end of file
# AVSession Controller
Media Controller preset in OpenHarmony functions as the controller to interact with audio and video applications, for example, obtaining and displaying media information and delivering control commands.
Media Controller preset in OpenHarmony functions as the controller to interact with audio and video applications, for example, obtaining and displaying media information and delivering playback control commands.
You can develop a system application (for example, a new playback control center or voice assistant) as the controller to interact with audio and video applications in the system.
......@@ -8,24 +8,50 @@ You can develop a system application (for example, a new playback control center
- AVSessionDescriptor: session information, including the session ID, session type (audio/video), custom session name (**sessionTag**), information about the corresponding application (**elementName**), and whether the session is pined on top (isTopSession).
- Top session: session with the highest priority in the system, for example, a session that is being played. Generally, the controller must hold an **AVSessionController** object to communicate with a session. However, the controller can directly communicate with the top session, for example, directly sending a control command or key event, without holding an **AVSessionController** object.
- Top session: session with the highest priority in the system, for example, a session that is being played. Generally, the controller must hold an **AVSessionController** object to communicate with a session. However, the controller can directly communicate with the top session, for example, directly sending a playback control command or key event, without holding an **AVSessionController** object.
## Available APIs
The table below lists the key APIs used by the controller. The APIs use either a callback or promise to return the result. The APIs listed below use a callback. They provide the same functions as their counterparts that use a promise.
The key APIs used by the controller are classified into the following types:
1. APIs called by the **AVSessionManager** object, which is obtained by means of import. An example API is **AVSessionManager.createController(sessionId)**.
2. APIs called by the **AVSessionController** object. An example API is **controller.getAVPlaybackState()**.
Asynchronous JavaScript APIs use either a callback or promise to return the result. The APIs listed below use a callback. They provide the same functions as their counterparts that use a promise.
For details, see [AVSession Management](../reference/apis/js-apis-avsession.md).
| API| Description|
### APIs Called by the AVSessionManager Object
| API| Description|
| -------- | -------- |
| getAllSessionDescriptors(callback: AsyncCallback&lt;Array&lt;Readonly&lt;AVSessionDescriptor&gt;&gt;&gt;): void | Obtains the descriptors of all AVSessions in the system.|
| createController(sessionId: string, callback: AsyncCallback&lt;AVSessionController&gt;): void | Creates an AVSessionController.|
| getValidCommands(callback: AsyncCallback&lt;Array&lt;AVControlCommandType&gt;&gt;): void | Obtains valid commands supported by the AVSession.<br>Playback control commands listened by an audio and video application when it accesses the AVSession are considered as valid commands supported by the AVSession. For details, see [Provider of AVSession](using-avsession-developer.md).|
| getLaunchAbility(callback: AsyncCallback&lt;WantAgent&gt;): void | Obtains the UIAbility that is configured in the AVSession and can be started.<br>The UIAbility configured here is started when a user operates the UI of the controller, for example, clicking a widget in Media Controller.|
| sendAVKeyEvent(event: KeyEvent, callback: AsyncCallback&lt;void&gt;): void | Sends a key event to an AVSession through the AVSessionController object.|
| sendSystemAVKeyEvent(event: KeyEvent, callback: AsyncCallback&lt;void&gt;): void | Sends a key event to the top session.|
| sendControlCommand(command: AVControlCommand, callback: AsyncCallback&lt;void&gt;): void | Sends a playback control command to an AVSession through the AVSessionController object.|
| sendSystemControlCommand(command: AVControlCommand, callback: AsyncCallback&lt;void&gt;): void | Sends a playback control command to the top session.|
| getHistoricalSessionDescriptors(maxSize: number, callback: AsyncCallback\<Array\<Readonly\<AVSessionDescriptor>>>): void<sup>10+<sup> | Obtains the descriptors of historical sessions.|
### APIs Called by the AVSessionController Object
| API| Description|
| -------- | -------- |
| getAllSessionDescriptors(callback: AsyncCallback&lt;Array&lt;Readonly&lt;AVSessionDescriptor&gt;&gt;&gt;): void | Obtains the descriptors of all AVSessions in the system.|
| createController(sessionId: string, callback: AsyncCallback&lt;AVSessionController&gt;): void | Creates an AVSessionController.|
| getValidCommands(callback: AsyncCallback&lt;Array&lt;AVControlCommandType&gt;&gt;): void | Obtains valid commands supported by the AVSession.<br>Control commands listened by an audio and video application when it accesses the AVSession are considered as valid commands supported by the AVSession. For details, see [Provider of AVSession](using-avsession-developer.md).|
| getLaunchAbility(callback: AsyncCallback&lt;WantAgent&gt;): void | Obtains the UIAbility that is configured in the AVSession and can be started.<br>The UIAbility configured here is started when a user operates the UI of the controller, for example, clicking a widget in Media Controller.|
| sendAVKeyEvent(event: KeyEvent, callback: AsyncCallback&lt;void&gt;): void | Sends a key event to an AVSession through the AVSessionController object.|
| sendSystemAVKeyEvent(event: KeyEvent, callback: AsyncCallback&lt;void&gt;): void | Sends a key event to the top session.|
| sendControlCommand(command: AVControlCommand, callback: AsyncCallback&lt;void&gt;): void | Sends a control command to an AVSession through the AVSessionController object.|
| sendSystemControlCommand(command: AVControlCommand, callback: AsyncCallback&lt;void&gt;): void | Sends a control command to the top session.|
| getAVPlaybackState(callback: AsyncCallback&lt;AVPlaybackState&gt;): void | Obtains the information related to the playback state.|
| getAVMetadata(callback: AsyncCallback&lt;AVMetadata&gt;): void | Obtains the session metadata.|
| getOutputDevice(callback: AsyncCallback&lt;OutputDeviceInfo&gt;): void | Obtains the output device information.|
| sendAVKeyEvent(event: KeyEvent, callback: AsyncCallback&lt;void&gt;): void | Sends a key event to the session corresponding to this controller.|
| getLaunchAbility(callback: AsyncCallback&lt;WantAgent&gt;): void | Obtains the **WantAgent** object saved by the application in the session.|
| isActive(callback: AsyncCallback&lt;boolean&gt;): void | Checks whether the session is activated.|
| destroy(callback: AsyncCallback&lt;void&gt;): void | Destroys this controller. A controller can no longer be used after being destroyed.|
| getValidCommands(callback: AsyncCallback&lt;Array&lt;AVControlCommandType&gt;&gt;): void | Obtains valid commands supported by the session.|
| sendControlCommand(command: AVControlCommand, callback: AsyncCallback&lt;void&gt;): void | Sends a playback control command to the session through the controller.|
| sendCommonCommand(command: string, args: {[key: string]: Object}, callback: AsyncCallback&lt;void&gt;): void<sup>10+<sup> | Sends a custom playback control command to the session through the controller.|
| getAVQueueItems(callback: AsyncCallback&lt;Array&lt;AVQueueItem&gt;&gt;): void<sup>10+<sup> | Obtains the information related to the items in the playlist.|
| getAVQueueTitle(callback: AsyncCallback&lt;string&gt;): void<sup>10+<sup> | Obtains the name of the playlist.|
| skipToQueueItem(itemId: number, callback: AsyncCallback&lt;void&gt;): void<sup>10+<sup> | Sends the ID of an item in the playlist to the session for processing. The session can play the song.|
| getExtras(callback: AsyncCallback&lt;{[key: string]: Object}&gt;): void<sup>10+<sup> | Obtains the custom media packet set by the provider.|
## How to Develop
......@@ -48,13 +74,26 @@ To enable a system application to access the AVSession service as a controller,
AVSessionManager.createController(descriptor.sessionId).then((controller) => {
g_controller.push(controller);
}).catch((err) => {
console.error(`createController : ERROR : ${err.message}`);
console.error(`Failed to create controller. Code: ${err.code}, message: ${err.message}`);
});
});
}).catch((err) => {
console.error(`getAllSessionDescriptors : ERROR : ${err.message}`);
console.error(`Failed to get all session descriptors. Code: ${err.code}, message: ${err.message}`);
});
// Obtain the descriptors of historical sessions.
avSession.getHistoricalSessionDescriptors().then((descriptors) => {
console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors.length : ${descriptors.length}`);
if (descriptors.length > 0){
console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors[0].isActive : ${descriptors[0].isActive}`);
console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors[0].type : ${descriptors[0].type}`);
console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors[0].sessionTag : ${descriptors[0].sessionTag}`);
console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors[0].sessionId : ${descriptors[0].sessionId}`);
console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors[0].elementName.bundleName : ${descriptors[0].elementName.bundleName}`);
}
}).catch((err) => {
console.error(`Failed to get historical session descriptors, error code: ${err.code}, error message: ${err.message}`);
});
```
2. Listen for the session state and service state events.
......@@ -74,7 +113,7 @@ To enable a system application to access the AVSession service as a controller,
AVSessionManager.createController(session.sessionId).then((controller) => {
g_controller.push(controller);
}).catch((err) => {
console.info(`createController : ERROR : ${err.message}`);
console.error(`Failed to create controller. Code: ${err.code}, message: ${err.message}`);
});
});
......@@ -103,7 +142,7 @@ To enable a system application to access the AVSession service as a controller,
// Subscribe to the 'sessionServiceDie' event.
AVSessionManager.on('sessionServiceDie', () => {
// The server is abnormal, and the application clears resources.
console.info("Server exception.");
console.info(`Server exception.`);
})
```
......@@ -117,6 +156,10 @@ To enable a system application to access the AVSession service as a controller,
- **validCommandChange**: triggered when the valid commands supported by the session changes.
- **outputDeviceChange**: triggered when the output device changes.
- **sessionDestroy**: triggered when a session is destroyed.
- **sessionEvent**: triggered when the custom session event changes.
- **extrasChange**: triggered when the custom media packet of the session changes.
- **queueItemsChange**: triggered when one or more items in the custom playlist of the session changes.
- **queueTitleChange**: triggered when the custom playlist name of the session changes.
The controller can listen for events as required.
......@@ -124,18 +167,18 @@ To enable a system application to access the AVSession service as a controller,
// Subscribe to the 'activeStateChange' event.
controller.on('activeStateChange', (isActive) => {
if (isActive) {
console.info("The widget corresponding to the controller is highlighted.");
console.info(`The widget corresponding to the controller is highlighted.`);
} else {
console.info("The widget corresponding to the controller is invalid.");
console.info(`The widget corresponding to the controller is invalid.`);
}
});
// Subscribe to the 'sessionDestroy' event to enable the controller to get notified when the session dies.
controller.on('sessionDestroy', () => {
console.info('on sessionDestroy : SUCCESS ');
info(`on sessionDestroy : SUCCESS `);
controller.destroy().then(() => {
console.info('destroy : SUCCESS ');
console.info(`destroy : SUCCESS`);
}).catch((err) => {
console.info(`destroy : ERROR :${err.message}`);
console.error(`Failed to destroy session. Code: ${err.code}, message: ${err.message}`);
});
});
......@@ -164,10 +207,26 @@ To enable a system application to access the AVSession service as a controller,
controller.on('outputDeviceChange', (device) => {
console.info(`on outputDeviceChange device isRemote : ${device.isRemote}`);
});
// Subscribe to custom session event changes.
controller.on('sessionEvent', (eventName, eventArgs) => {
console.info(`Received new session event, event name is ${eventName}, args are ${JSON.stringify(eventArgs)}`);
});
// Subscribe to custom media packet changes.
controller.on('extrasChange', (extras) => {
console.info(`Received custom media packet, packet data is ${JSON.stringify(extras)}`);
});
// Subscribe to custom playlist item changes.
controller.on('queueItemsChange', (items) => {
console.info(`Caught queue items change, items length is ${items.length}`);
});
// Subscribe to custom playback name changes.
controller.on('queueTitleChange', (title) => {
console.info(`Caught queue title change, title is ${title}`);
});
```
4. Obtain the media information transferred by the provider for display on the UI, for example, displaying the track being played and the playback state in Media Controller.
```ts
async getInfoFromSessionByController() {
// It is assumed that an AVSessionController object corresponding to the session already exists. For details about how to create an AVSessionController object, see the code snippet above.
......@@ -186,19 +245,36 @@ To enable a system application to access the AVSession service as a controller,
let avPlaybackState: AVSessionManager.AVPlaybackState = await controller.getAVPlaybackState();
console.info(`get playbackState by controller : ${avPlaybackState.state}`);
console.info(`get favoriteState by controller : ${avPlaybackState.isFavorite}`);
// Obtain the playlist items of the session.
let queueItems: Array<AVSessionManager.AVQueueItem> = await controller.getAVQueueItems();
console.info(`get queueItems length by controller : ${queueItems.length}`);
// Obtain the playlist name of the session.
let queueTitle: string = await controller.getAVQueueTitle();
console.info(`get queueTitle by controller : ${queueTitle}`);
// Obtain the custom media packet of the session.
let extras: any = await controller.getExtras();
console.info(`get custom media packets by controller : ${JSON.stringify(extras)}`);
// Obtain the ability information provided by the application corresponding to the session.
let agent: WantAgent = await controller.getLaunchAbility();
console.info(`get want agent info by controller : ${JSON.stringify(agent)}`);
// Obtain the current playback position of the session.
let currentTime: number = controller.getRealPlaybackPositionSync();
console.info(`get current playback time by controller : ${currentTime}`);
// Obtain valid commands supported by the session.
let validCommands: Array<AVSessionManager.AVControlCommandType> = await controller.getValidCommands();
console.info(`get valid commands by controller : ${JSON.stringify(validCommands)}`);
}
```
5. Control the playback behavior, for example, sending a command to operate (play/pause/previous/next) the item being played in Media Controller.
After listening for the control command event, the audio and video application serving as the provider needs to implement the corresponding operation.
After listening for the playback control command event, the audio and video application serving as the provider needs to implement the corresponding operation.
```ts
async sendCommandToSessionByController() {
// It is assumed that an AVSessionController object corresponding to the session already exists. For details about how to create an AVSessionController object, see the code snippet above.
let controller: AVSessionManager.AVSessionController = ALLREADY_HAVE_A_CONTROLLER;
// Obtain the commands supported by the session.
// Obtain valid commands supported by the session.
let validCommandTypeArray: Array<AVSessionManager.AVControlCommandType> = await controller.getValidCommands();
console.info(`get validCommandArray by controller : length : ${validCommandTypeArray.length}`);
// Deliver the 'play' command.
......@@ -222,11 +298,28 @@ To enable a system application to access the AVSession service as a controller,
let avCommand: AVSessionManager.AVControlCommand = {command:'playNext'};
controller.sendControlCommand(avCommand);
}
// Deliver a custom playback control command.
let commandName: string = 'custom command';
let args = {
command : 'This is my custom command'
}
await controller.sendCommonCommand(commandName, args).then(() => {
console.info(`SendCommonCommand successfully`);
}).catch((err) => {
console.error(`Failed to send common command. Code: ${err.code}, message: ${err.message}`);
})
// Set the ID of an item in the specified playlist for the session to play.
let queueItemId: number = 0;
await controller.skipToQueueItem(queueItemId).then(() => {
console.info(`SkipToQueueItem successfully`);
}).catch((err) => {
console.error(`Failed to skip to queue item. Code: ${err.code}, message: ${err.message}`);
});
}
```
6. When the audio and video application exits, cancel the listener and release the resources.
```ts
async destroyController() {
// It is assumed that an AVSessionController object corresponding to the session already exists. For details about how to create an AVSessionController object, see the code snippet above.
......@@ -235,9 +328,9 @@ To enable a system application to access the AVSession service as a controller,
// Destroy the AVSessionController object. After being destroyed, it is no longer available.
controller.destroy(function (err) {
if (err) {
console.info(`Destroy controller ERROR : code: ${err.code}, message: ${err.message}`);
console.error(`Failed to destroy controller. Code: ${err.code}, message: ${err.message}`);
} else {
console.info('Destroy controller SUCCESS');
console.info(`Destroy controller SUCCESS`);
}
});
}
......
......@@ -36,15 +36,15 @@ To enable a system application that accesses the AVSession service as the contro
let audioDevices;
await audioRoutingManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG).then((data) => {
audioDevices = data;
console.info('Promise returned to indicate that the device list is obtained.');
console.info(`Promise returned to indicate that the device list is obtained.`);
}).catch((err) => {
console.info(`getDevices : ERROR : ${err.message}`);
console.error(`Failed to get devices. Code: ${err.code}, message: ${err.message}`);
});
AVSessionManager.castAudio('all', audioDevices).then(() => {
console.info('createController : SUCCESS');
console.info(`createController : SUCCESS`);
}).catch((err) => {
console.info(`createController : ERROR : ${err.message}`);
console.error(`Failed to cast audio. Code: ${err.code}, message: ${err.message}`);
});
```
......
......@@ -78,7 +78,9 @@ export class AVPlayerDemo {
private avPlayer;
private count: number = 0;
private surfaceID: string; // The surfaceID parameter specifies the window used to display the video. Its value is obtained through the XComponent.
private isSeek: boolean = true; // Specify whether the seek operation is supported.
private fileSize: number = -1;
private fd: number = 0;
// Set AVPlayer callback functions.
setAVPlayerCallback() {
// Callback function for the seek operation.
......@@ -113,8 +115,13 @@ export class AVPlayerDemo {
case 'playing': // This state is reported upon a successful callback of play().
console.info('AVPlayer state playing called.');
if (this.count !== 0) {
console.info('AVPlayer start to seek.');
this.avPlayer.seek (this.avPlayer.duration); // Call seek() to seek to the end of the video clip.
if (this.isSeek) {
console.info('AVPlayer start to seek.');
this.avPlayer.seek (this.avPlayer.duration); // Call seek() to seek to the end of the video clip.
} else {
// When the seek operation is not supported, the playback continues until it reaches the end.
console.info('AVPlayer wait to play end.');
}
} else {
this.avPlayer.pause(); // Call pause() to pause the playback.
}
......@@ -152,10 +159,11 @@ export class AVPlayerDemo {
let context = getContext(this) as common.UIAbilityContext;
// Obtain the sandbox address filesDir through UIAbilityContext. The stage model is used as an example.
let pathDir = context.filesDir;
let path = pathDir + '/H264_AAC.mp4';
let path = pathDir + '/H264_AAC.mp4';
// Open the corresponding file address to obtain the file descriptor and assign a value to the URL to trigger the reporting of the initialized state.
let file = await fs.open(path);
fdPath = fdPath + '' + file.fd;
this.isSeek = true; // The seek operation is supported.
this.avPlayer.url = fdPath;
}
......@@ -169,9 +177,86 @@ export class AVPlayerDemo {
// The return type is {fd,offset,length}, where fd indicates the file descriptor address of the HAP file, offset indicates the media asset offset, and length indicates the duration of the media asset to play.
let context = getContext(this) as common.UIAbilityContext;
let fileDescriptor = await context.resourceManager.getRawFd('H264_AAC.mp4');
this.isSeek = true; // The seek operation is supported.
// Assign a value to fdSrc to trigger the reporting of the initialized state.
this.avPlayer.fdSrc = fileDescriptor;
}
// The following demo shows how to use the file system to open the sandbox address, obtain the media file address, and play the media file with the seek operation using the dataSrc attribute.
async avPlayerDataSrcSeekDemo() {
// Create an AVPlayer instance.
this.avPlayer = await media.createAVPlayer();
// Set a callback function for state changes.
this.setAVPlayerCallback();
// dataSrc indicates the playback source address. When the seek operation is supported, fileSize indicates the size of the file to be played. The following describes how to assign a value to fileSize.
let src = {
fileSize: -1,
callback: (buf, length, pos) => {
let num = 0;
if (buf == undefined || length == undefined || pos == undefined) {
return -1;
}
num = fs.readSync(this.fd, buf, { offset: pos, length: length });
if (num > 0 && (this.fileSize >= pos)) {
return num;
}
return -1;
}
}
let context = getContext(this) as common.UIAbilityContext;
// Obtain the sandbox address filesDir through UIAbilityContext. The stage model is used as an example.
let pathDir = context.filesDir;
let path = pathDir + '/H264_AAC.mp4';
await fs.open(path).then((file) => {
this.fd = file.fd;
})
// Obtain the size of the file to be played.
this.fileSize = fs.statSync(path).size;
src.fileSize = this.fileSize;
this.isSeek = true; // The seek operation is supported.
this.avPlayer.dataSrc = src;
}
// The following demo shows how to use the file system to open the sandbox address, obtain the media file address, and play the media file without the seek operation using the dataSrc attribute.
async avPlayerDataSrcNoSeekDemo() {
// Create an AVPlayer instance.
this.avPlayer = await media.createAVPlayer();
// Set a callback function for state changes.
this.setAVPlayerCallback();
let context = getContext(this) as common.UIAbilityContext;
let src: object = {
fileSize: -1,
callback: (buf, length, pos) => {
let num = 0;
if (buf == undefined || length == undefined) {
return -1;
}
num = fs.readSync(this.fd, buf);
if (num > 0) {
return num;
}
return -1;
}
}
// Obtain the sandbox address filesDir through UIAbilityContext. The stage model is used as an example.
let pathDir = context.filesDir;
let path = pathDir + '/H264_AAC.mp4';
await fs.open(path).then((file) => {
this.fd = file.fd;
})
this.isSeek = false; // The seek operation is not supported.
this.avPlayer.dataSrc = src;
}
// The following demo shows how to play live streams by setting the network address through the URL.
async avPlayerLiveDemo() {
// Create an AVPlayer instance.
this.avPlayer = await media.createAVPlayer();
// Set a callback function for state changes.
this.setAVPlayerCallback();
this.isSeek = false; // The seek operation is not supported.
this.avPlayer.url = 'http://xxx.xxx.xxx.xxx:xx/xx/index.m3u8'; // Play live webcasting streams using HLS.
}
}
```
......
......@@ -114,15 +114,28 @@ To fully understand the preceding example, a knowledge of the following concepts
}
```
- \@Recycle: A custom component decorated with \@Recycle can be reused.
> **NOTE**
>
> Since API version 10, this decorator is supported in ArkTS widgets.
```ts
@Recycle
@Component
struct MyComponent {
}
```
## Member Functions/Variables
In addition to the mandatory** build()** function, a custom component may implement other member functions with the following restrictions:
In addition to the mandatory **build()** function, a custom component may implement other member functions with the following restrictions:
- Static functions are not supported.
- Access to the member functions is always private. Defining **private** access is optional. Defining access other than **private** is a syntax error.
- Access to the member functions is always private.
A custom component can also implement member variables with the following restrictions:
......@@ -130,7 +143,7 @@ A custom component can also implement member variables with the following restri
- Static member variables are not supported.
- Access to the member variables is always private.The access rules of member variables are the same as those of member functions.
- Access to the member variables is always private. The access rules of member variables are the same as those of member functions.
- Local initialization is optional for some member variables and mandatory for others. For details about whether local initialization or initialization from the parent component is required, see [State Management](arkts-state-management-overview.md).
......@@ -378,4 +391,5 @@ In the preceding example:
2. The **StyleExample** parent component holds a **Controller** instance and with which calls the **changeText** API of **Controller**. That is, the value of the state variable **value** of **MyComponent** is changed through the **this** pointer of the **MyComponent** child component held by the controller.
Through the encapsulation of the controller, **MyComponent** exposes the **changeText** API. All instances that hold the controller can call the **changeText** API to change the value of the **MyComponent** state variable **value**.
<!--no_check-->
......@@ -316,7 +316,7 @@ class StringArray extends Array<String> {
Declare a class that extends from** Array**: **class StringArray extends Array\<String> {}** and create an instance of **StringArray**. The use of the **new** operator is required for the \@Observed class decorator to work properly.
Declare a class that extends from **Array**: **class StringArray extends Array\<String> {}** and create an instance of **StringArray**. The use of the **new** operator is required for the \@Observed class decorator to work properly.
```ts
......
......@@ -19,7 +19,7 @@ The following lifecycle callbacks are provided for the lifecycle of a page, that
- [onBackPress](../reference/arkui-ts/ts-custom-component-lifecycle.md#onbackpress): Invoked when the user clicks the Back button.
The following lifecycle callbacks are provided for the lifecycle of a custom component, which is one decorated with \@Component:
The following lifecycle callbacks are provided for the lifecycle of a component, that is, the lifecycle of a custom component decorated with \@Component:
- [aboutToAppear](../reference/arkui-ts/ts-custom-component-lifecycle.md#abouttoappear): Invoked when the custom component is about to appear. Specifically, it is invoked after a new instance of the custom component is created and before its **build** function is executed.
......@@ -134,7 +134,7 @@ struct MyComponent {
Child()
}
// When this.showChild is false, the Child child component is deleted, and Child aboutToDisappear is invoked.
Button('create or delete Child').onClick(() => {
Button('delete Child').onClick(() => {
this.showChild = false;
})
// Because of the pushing from the current page to Page2, onPageHide is invoked.
......
......@@ -75,15 +75,17 @@ interface DataChangeListener {
}
```
| Declaration | Parameter Type | Description |
| ---------------------------------------- | -------------------------------------- | ---------------------------------------- |
| onDataReloaded():&nbsp;void | - | Invoked when all data is reloaded. |
| onDataAdded(index:&nbsp;number):void | number | Invoked when data is added to the position indicated by the specified index.<br>**index**: index of the position where data is added. |
| onDataMoved(from:&nbsp;number,&nbsp;to:&nbsp;number):&nbsp;void | from:&nbsp;number,<br>to:&nbsp;number | Invoked when data is moved.<br>**from**: original position of data; **to**: target position of data.<br>**NOTE**<br>The ID must remain unchanged before and after data movement. If the ID changes, APIs for deleting and adding data must be called.|
| onDataChanged(index:&nbsp;number):&nbsp;void | number | Invoked when data in the position indicated by the specified index is changed.<br>**index**: listener for data changes. |
| onDataAdd(index:&nbsp;number):&nbsp;void | number | Invoked when data is added to the position indicated by the specified index.<br>**index**: index of the position where data is added. |
| onDataMove(from:&nbsp;number,&nbsp;to:&nbsp;number):&nbsp;void | from:&nbsp;number,<br>to:&nbsp;number | Invoked when data is moved.<br>**from**: original position of data; **to**: target position of data.<br>**NOTE**<br>The ID must remain unchanged before and after data movement. If the ID changes, APIs for deleting and adding data must be called.|
| onDataChanged(index:&nbsp;number):&nbsp;void | number | Invoked when data in the position indicated by the specified index is changed.<br>**index**: index of the position where data is changed.|
| Declaration | Parameter Type | Description |
| ------------------------------------------------------------ | -------------------------------------- | ------------------------------------------------------------ |
| onDataReloaded():&nbsp;void | - | Invoked when all data is reloaded. |
| onDataAdded(index:&nbsp;number):void<sup>(deprecated)</sup> | number | Invoked when data is added to the position indicated by the specified index.<br>This API is deprecated since API version 8. You are advised to use **onDataAdd** instead.<br>**index**: index of the position where data is added.|
| onDataMoved(from:&nbsp;number,&nbsp;to:&nbsp;number):&nbsp;void<sup>(deprecated)</sup> | from:&nbsp;number,<br>to:&nbsp;number | Invoked when data is moved.<br>This API is deprecated since API version 8. You are advised to use **onDataMove** instead.<br>**from**: original position of data; **to**: target position of data.<br>**NOTE**<br>The ID must remain unchanged before and after data movement. If the ID changes, APIs for deleting and adding data must be called.|
| onDataDeleted(index: number):void<sup>(deprecated)</sup> | number | Invoked when data is deleted from the position indicated by the specified index. LazyForEach will update the displayed content accordingly.<br>This API is deprecated since API version 8. You are advised to use **onDataDelete** instead.<br>**index**: index of the position where data is deleted.|
| onDataChanged(index:&nbsp;number):&nbsp;void<sup>(deprecated)</sup> | number | Invoked when data in the position indicated by the specified index is changed.<br>This API is deprecated since API version 8. You are advised to use **onDataChange** instead.<br>**index**: listener for data changes.|
| onDataAdd(index:&nbsp;number):&nbsp;void<sup>8+</sup> | number | Invoked when data is added to the position indicated by the specified index.<br>**index**: index of the position where data is added.|
| onDataMove(from:&nbsp;number,&nbsp;to:&nbsp;number):&nbsp;void<sup>8+</sup> | from:&nbsp;number,<br>to:&nbsp;number | Invoked when data is moved.<br>**from**: original position of data; **to**: target position of data.<br>**NOTE**<br>The ID must remain unchanged before and after data movement. If the ID changes, APIs for deleting and adding data must be called.|
| onDataDelete(index: number):void<sup>8+</sup> | number | Invoked when data is deleted from the position indicated by the specified index. LazyForEach will update the displayed content accordingly.<br>**index**: index of the position where data is deleted.<br>**NOTE**<br>Before **onDataDelete** is called, ensure that the corresponding data in **dataSource** has been deleted. Otherwise, undefined behavior will occur during page rendering.|
| onDataChange(index:&nbsp;number):&nbsp;void<sup>8+</sup> | number | Invoked when data in the position indicated by the specified index is changed.<br>**index**: index of the position where data is changed.|
## Restrictions
......
......@@ -82,7 +82,7 @@ According to the data transfer mode and synchronization type, decorators can als
- Decorators that allow for two-way (mutable) transfer
The following figure illustrates the decorators. For details, see [Managing State by a Component](arkts-state.md) and [Managing State by an Application](arkts-application-state-management-overview.md). You can use these decorators at your disposal to implement linkage between data and the UI.
The following figure illustrates the decorators. For details, see [Component State Management](arkts-state.md) and [Application State Management](arkts-application-state-management-overview.md). You can use these decorators at your disposal to implement linkage between data and the UI.
![en-us_image_0000001502704640](figures/en-us_image_0000001502704640.png)
......@@ -106,6 +106,10 @@ Decorators for [managing the state owned by a component](arkts-state.md):
- \@ObjectLink: An \@ObjectLink decorated variable, when used with an \@Observed decorated class of the parent component, is for two-way data synchronization in scenarios involving multiple levels of nested objects or arrays in the class.
> **NOTE**
>
> Only [\@Observed/\@ObjectLink](arkts-observed-and-objectlink.md) can observe changes of nested attributes. Other decorators can only observe changes of attributes at the first layer. For details, see the "Observed Changes and Behavior" part in each decorator section.
Decorators for [managing the state owned by an application](arkts-state.md):
......
......@@ -231,11 +231,11 @@ struct MyComponent {
Text(`${this.title.value}`)
Button(`Click to change title`).onClick(() => {
// The update of the @State decorated variable triggers the update of the <Text> component.
this.title.value = this.title.value === 'Hello ArkUI' ? 'Hello World' : 'HelloArkUI';
this.title.value = this.title.value === 'Hello ArkUI' ? 'Hello World' : 'Hello ArkUI';
})
Button(`Click to increase count=${this.count}`).onClick(() => {
// The update of the @State decorated variable triggers the update of the <Text> component.
// The update of the @State decorated variable triggers the update of the <Button> component.
this.count += this.increaseBy;
})
}
......
......@@ -4,7 +4,7 @@ Space management for atomic services is necessary from two aspects. On the one h
## Managing Quota for Atomic Service Data Directories
Set a storage quota for the data sandbox directory of an atomic service. This quota can be obtained through the system parameter **persist.sys.bms.aging.policy.atomicservice.datasize.threshold**. The default value is 1024 MB. When the quota is used up, writing data will return an error message.
Set a storage quota for the data sandbox directory of an atomic service. This quota can be obtained through the system parameter **persist.sys.bms.aging.policy.atomicservice.datasize.threshold**. The default value is 50 MB. When the quota is used up, writing data will return an error message.
You can run the [param get/set](../../device-dev/subsystems/subsys-boot-init-plugin.md) command to view and set system parameters.
......
......@@ -17,34 +17,29 @@ An inter-application HSP works by combining the following parts:
HSP: contains the actual implementation code, including the JS/TS code, C++ libraries, resources, and configuration files. It is either released to the application market or integrated into the system version.
### Integrating the HAR in an Inter-Application HSP
Define the interfaces to be exported in the **index.d.ets** file in the HAR, which is the entry to the declaration file exported by the inter-application HSP. The path of the **index.d.ets** file is as follows:
Define the interfaces to be exported in the **index.ets** file in the HAR, which is the entry to the declaration file exported by the inter-application HSP. The path to the **index.ets** file is as follows:
```
src
├── main
| └── module.json5
├── index.d.ets
liba
├── src
│ └── main
│ ├── ets
│ │ ├── pages
│ │ └── index.ets
│ ├── resources
│ └── module.json5
└── oh-package.json5
```
Below is an example of the **index.d.ets** file content:
```ts
@Component
export declare struct UIComponent {
build():void;
}
export declare function hello(): string;
export declare function foo1(): string;
Below is an example of the **index.ets** file content:
export declare function foo2(): string;
export declare function nativeHello(): string;
```ts
// liba/src/main/ets/index.ets
export { hello, foo1, foo2, nativeMulti, UIComponent } from './ui/MyUIComponent'
```
In the example, **UIComponent** is an ArkUI component, **hello()**, **foo1()**, and **foo2()** are TS methods, and **nativeHello()** is a native method. Specific implementation is as follows:
In the example, **UIComponent** is an ArkUI component, **hello()**, **foo1()**, and **foo2()** are TS methods, and **nativeMulti()** is a native method. Specific implementation is as follows:
#### ArkUI Components
The following is an implementation example of ArkUI components in the HSP:
```ts
// lib/src/main/ets/ui/MyUIComponent.ets
// liba/src/main/ets/ui/MyUIComponent.ets
@Component
export struct UIComponent {
@State message: string = 'Hello World'
......@@ -63,6 +58,7 @@ export struct UIComponent {
#### **TS Methods**
The following is an implementation example of TS methods in the HSP:
```ts
// liba/src/main/ets/ui/MyUIComponent.ets
export function hello(name: string): string {
return "hello + " + name;
}
......@@ -74,50 +70,22 @@ export function foo1() {
export function foo2() {
return "foo2";
}
```
#### **Native Methods**
The following is an implementation example of native methods in the HSP:
```C++
#include "napi/native_api.h"
#include <js_native_api.h>
#include <js_native_api_types.h>
#include <string>
const std::string libname = "liba";
const std::string version = "v10001";
static napi_value Hello(napi_env env, napi_callback_info info) {
napi_value ret;
std::string msg = libname + ":native hello, " + version;
napi_create_string_utf8(env, msg.c_str(), msg.length(), &ret);
return ret;
}
The HSP can contain .so files compiled in C++. The HSP indirectly exports the native method in the .so file. In this example, the **multi** API in the **libnative.so** file is exported.
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
napi_property_descriptor desc[] = {
{"nativeHello", nullptr, Hello, nullptr, nullptr, nullptr, napi_default, nullptr}};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END
static napi_module demoModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "liba",
.nm_priv = ((void *)0),
.reserved = {0},
};
extern "C" __attribute__((constructor)) void RegisterLibaModule(void) {
napi_module_register(&demoModule);
```ts
// liba/src/main/ets/ui/MyUIComponent.ets
import native from "libnative.so"
export function nativeMulti(a: number, b: number) {
return native.multi(a, b);
}
```
### Using the Capabilities Exported from the HAR
To start with, [configure dependency](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ohos-development-npm-package-0000001222578434#section89674298391) on the HAR. The dependency information will then be generated in the **module.json5** file of the corresponding module, as shown in the following:
To start with, [configure dependency](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/creating_har_api9-0000001518082393-V3#section611662614153) on the HAR. The dependency information will then be generated in the **module.json5** file of the corresponding module, as shown in the following:
```json
"dependencies": [
{
......@@ -180,7 +148,7 @@ struct Index {
#### Referencing Native Methods in the HAR
To reference the native methods exported from the HAR, use **import** as follows:
``` ts
import { nativeHello } from 'liba'
import { nativeMulti } from 'liba'
@Component
struct Index {
......@@ -190,7 +158,7 @@ struct Index {
Button('Button')
.onClick(()=>{
// Reference the native method in the HAR.
nativeHello();
nativeMulti();
})
}
.width('100%')
......@@ -207,11 +175,6 @@ Inter-application HSPs are not completely integrated into an application. They a
### Inter-Application HSP Debugging Mode
You can debug an inter-application HSP after it is distributed to a device. If the aforementioned distribution methods are not applicable, you can distribute the HSP by running **bm** commands. The procedure is as follows:
> **NOTE**
>
> Do not reverse steps 2 and 3. Otherwise, your application will fail to be installed due to a lack of the required inter-application HSP. For more information about the **bm** commands, see [Bundle Management](../../readme/bundle-management.md).
1. Obtain the inter-application HSP installation package.
2. Run the following **bm** command to install the inter-application HSP.
```
......@@ -222,3 +185,7 @@ bm install -s sharebundle.hsp
bm install -p feature.hap
```
4. Start your application and start debugging.
> **NOTE**
>
> Do not reverse steps 2 and 3. Otherwise, your application will fail to be installed due to a lack of the required inter-application HSP. For more information about the **bm** commands, see [bm Commands](../../readme/bundle-management.md#bm-commands).
\ No newline at end of file
......@@ -2,7 +2,7 @@
A Harmony Archive (HAR) is a static shared package that can contain code, C++ libraries, resources, and configuration files. It enables modules and projects to share code related to ArkUI components, resources, and more. Unlike a Harmony Ability Package (HAP), a HAR cannot be independently installed on a device. Instead, it can be referenced only as the dependency of an application module.
## Creating a HAR Module
You can kickstart your HAR module development with the module template of the **Library** type in DevEco Studio. By default, obfuscation is disabled for the HAR module. To enable this feature, set **artifactType** in the **build-profile.json5** file of the HAR module to **obfuscation** as follows:
You can [create a HAR module in DevEco Studio](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/creating_har_api9-0000001518082393-V3#section143510369612). To better protect your source code, enable obfuscation for the HAR module so that DevEco Studio compiles, obfuscates, and compresses code during HAR building. To enable obfuscation, open the **build-profile.json5** file of the HAR module and set **artifactType** to **obfuscation** as follows:
```json
{
......@@ -12,15 +12,13 @@ You can kickstart your HAR module development with the module template of the **
}
}
```
The value options of **artifactType** are as follows, and the default value is **original**:
The value options of **artifactType** are as follows, with the default value being **original**:
- **original**: Code is not obfuscated.
- **obfuscation**: Code is obfuscated using Uglify.
When obfuscation is enabled, DevEco Studio compiles, obfuscates, and compresses code during HAR building, thereby protecting your code assets.
> **NOTE**
>
> If **artifactType** is set to **obfuscation**, **apiType** must be set to **stageMode**, because obfuscation is available only in the stage model.
> Obfuscation is available only in the stage model. Therefore, if **artifactType** is set to **obfuscation**, **apiType** must be set to **stageMode**.
## Precautions for HAR Development
- The HAR does not support the declaration of **abilities** and **extensionAbilities** in its configuration file.
......@@ -88,12 +86,12 @@ export { func2 } from './src/main/ts/test'
```
### Resources
Resources are packed into the HAR when it is being compiled and packaged. During compilation and building of a HAP, DevEco Studio collects resource files from the HAP module and its dependent modules. If the resource files of different modules have the same name, DevEco Studio overwrites the resource files based on the following priorities (in descending order):
- AppScope (supported only by the stage model of API version 9)
- AppScope (only for the stage model of API version 9)
- Modules in the HAP file
- If resource conflicts occur between dependent HAR modules, they are overwritten based on the dependency sequence. (The module that is higher in the dependency sequence list has higher priority.)
## Referencing ArkUI Components, APIs, and Resources in the HAR
To start with, [configure dependency](https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ohos-development-npm-package-0000001222578434#section89674298391) on the HAR.
To start with, [configure dependency](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/creating_har_api9-0000001518082393-V3#section611662614153) on the HAR.
### Reference ArkUI Components in the HAR
......@@ -170,3 +168,7 @@ struct Index {
}
}
```
## Releasing a HAR
Follow the [instructions](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/creating_har_api9-0000001518082393-V3#section1213451811512) to release a HAR.
......@@ -5,7 +5,7 @@ The in-application HSP is released with the Application Package (App Pack) of th
## Developing an In-Application HSP
You can kickstart your HSP development with the HSP template in DevEco Studio. In this example, an HSP module named **library** is created. The basic project directory structure is as follows:
[Create an HSP module in DevEco Studio](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/hsp-0000001521396322-V3#section7717162312546). In this example, an HSP module named **library** is created. The basic project directory structure is as follows:
```
library
├── src
......@@ -88,7 +88,7 @@ if **Image("common/example.png")** is used in the HSP module, the **\<Image>** c
### Exporting Native Methods
The HSP can contain .so files compiled in C++. The HSP indirectly exports the native method in the .so file. In this example, the **multi** method in the **libnative.so** file is exported.
```ts
// ibrary/src/main/ets/utils/nativeTest.ts
// library/src/main/ets/utils/nativeTest.ts
import native from "libnative.so"
export function nativeMulti(a: number, b: number) {
......@@ -103,15 +103,9 @@ export { nativeMulti } from './utils/nativeTest'
```
## Using the In-Application HSP
To use APIs in the HSP, first configure the dependency on the HSP in the **oh-package.json5** file of the module that needs to call the APIs (called the invoking module). If the HSP and the invoking module are in the same project, the APIs can be referenced locally. The sample code is as follows:
```json
// entry/oh-package.json5
"dependencies": {
"library": "file:../library"
}
```
You can now call the external APIs of the HSP in the same way as calling the APIs in the HAR.
In this example, the external APIs are the following ones exported from **library**:
To use APIs in the HSP, first [configure the dependency](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/hsp-0000001521396322-V3#section6161154819195) on the HSP in the **oh-package.json5** file of the module that needs to call the APIs (called the invoking module).
You can then call the external APIs of the HSP in the same way as calling the APIs in the HAR. In this example, the external APIs are the following ones exported from **library**:
```ts
// library/src/main/ets/index.ets
export { Log, add, minus } from './utils/test'
......
......@@ -309,7 +309,7 @@ Set **icon**, **label**, and **skills** under **abilities** in the **module.json
| [metadata](#metadata)| Metadata information of the UIAbility component.| Object array| Yes (initial value: left empty)|
| exported | Whether the UIAbility component can be called by other applications.<br>- **true**: The UIAbility component can be called by other applications.<br>- **false**: The UIAbility component cannot be called by other applications.| Boolean| Yes (initial value: **false**)|
| continuable | Whether the UIAbility component can be [migrated](../application-models/hop-cross-device-migration.md).<br>- **true**: The UIAbility component can be migrated.<br>- **false**: The UIAbility component cannot be migrated.| Boolean| Yes (initial value: **false**)|
| [skills](#skills) | Feature set of [wants](../application-models/want-overview.md) that can be received by the current UIAbility or ExtensionAbility component.<br>Configuring rule:<br>- For HAPs of the entry type, you can configure multiple **skills** attributes with the entry capability for an OpenHarmony application. (A **skills** attribute with the entry capability is the one that has **ohos.want.action.home** and **entity.system.home** configured.)<br>- For HAPs of the feature type, you can configure **skills** attributes with the entry capability for an OpenHarmony application, but not for an OpenHarmony service.| Object array| Yes (initial value: left empty)|
| [skills](#skills) | Feature set of [wants](../application-models/want-overview.md) that can be received by the current UIAbility or ExtensionAbility component.<br>Configuration rules:<br>- For HAPs of the entry type, you can configure multiple **skills** attributes with the entry capability for an OpenHarmony application. (A **skills** attribute with the entry capability is the one that has **ohos.want.action.home** and **entity.system.home** configured.)<br>- For HAPs of the feature type, you can configure **skills** attributes with the entry capability for an OpenHarmony application, but not for an OpenHarmony service.| Object array| Yes (initial value: left empty)|
| backgroundModes | Continuous tasks of the UIAbility component. <br>Continuous tasks are classified into the following types:<br>- **dataTransfer**: service for downloading, backing up, sharing, or transferring data from the network or peer devices.<br>- **audioPlayback**: audio playback service.<br>- **audioRecording**: audio recording service.<br>- **location**: location and navigation services.<br>- **bluetoothInteraction**: Bluetooth scanning, connection, and transmission services (wearables).<br>- **multiDeviceConnection**: multi-device interconnection service.<br>- **wifiInteraction**: Wi-Fi scanning, connection, and transmission services (as used in the Multi-screen Collaboration and clone features)<br>- **voip**: voice/video call and VoIP services.<br>- **taskKeeping**: computing service.| String array| Yes (initial value: left empty)|
| startWindowIcon | Index to the icon file of the UIAbility component startup page. Example: **$media:icon**.<br>The value is a string with a maximum of 255 bytes.| String| No|
| startWindowBackground | Index to the background color resource file of the UIAbility component startup page. Example: **$color:red**.<br>The value is a string with a maximum of 255 bytes.| String| No|
......
......@@ -10,7 +10,7 @@ Quick fix is a technical means provided by the OpenHarmony system for developers
* The bundle name and application version number configured in the quick fix package must be the same as those of the installed application. Otherwise, the deployment will fail.
* Make sure the version of the quick fix package to deploy is later than that of the one previously deployed. Otherwise, the deployment will fail.
* The signature information of the quick fix package must be the same as that of the application to be fixed. Otherwise, the deployment will fail.
* Installing an application update will delete quick fix package.
* Installing an application update will delete the quick fix package.
## Structure of the Quick Fix Package
......@@ -18,7 +18,7 @@ Quick fix is a technical means provided by the OpenHarmony system for developers
<br>The preceding figure shows the structure of the quick fix package released by an OpenHarmony application.
* As shown in the figure, the quick fix package comes in two formats:
* .appqf (Application Quick Fix)
<br> There is a one-to-one mapping between the .appqf file and App Pack of an application. For details, see [Application Package Structure in Stage Model](application-package-structure-stage).
<br> There is a one-to-one mapping between the .appqf file and App Pack of an application. For details, see [Application Package Structure in Stage Model](application-package-structure-stage.md).
* The .appqf file is used to release OpenHarmony applications to the application market and cannot be directly installed on devices.
* An .appqf file consists of one or more .hqf (Harmony Ability Package Quick Fix) files, which are extracted from the .appqf file by the application market and then distributed to specific devices.
* The .appqf file must contain the developer's signature information before being released to the application market. For details about how to sign the file, see [hapsigner Overview](../security/hapsigntool-overview.md).
......
......@@ -8,8 +8,6 @@ During application development, you may need to use different resources, such as
## Resource Categories
### resources Directory
Resource files used during application development must be stored in specified directories for management. The **resources** directory consists of three types of subdirectories: the **base** subdirectory, qualifiers subdirectories, and the **rawfile** subdirectory. The common resource files used across projects in the stage model are stored in the **resources** directory under **AppScope**.
The **base** subdirectory is provided by default, and the qualifiers subdirectories are created on your own. When your application needs to use a resource, the system preferentially searches the qualifiers subdirectories that match the current device state. The system searches the **base** subdirectory for the target resource only when the **resources** directory does not contain any qualifiers subdirectories that match the current device state or the target resource is not found in the qualifiers subdirectories. The **rawfile** directory is not searched for resources.
......@@ -18,24 +16,42 @@ Example of the **resources** directory:
```
resources
|---base // Default directory
|---base
| |---element
| | |---string.json
| |---media
| | |---icon.png
| |---profile
| | |---test_profile.json
|---en_US // Default directory. When the device language is en-us, resources in this directory are preferentially matched.
| |---element
| | |---string.json
| |---media
| | |---icon.png
| |---profile
| | |---test_profile.json
|---zh_CN // Default directory. When the device language is zh-cn, resources in this directory are preferentially matched.
| |---element
| | |---string.json
| |---media
| | |---icon.png
|---en_GB-vertical-car-mdpi // Example of a qualifiers subdirectory, which needs to be created on your own
| |---profile
| | |---test_profile.json
|---en_GB-vertical-car-mdpi // Example of a qualifiers subdirectory, which needs to be created on your own.
| |---element
| | |---string.json
| |---media
| | |---icon.png
|---rawfile
| |---profile
| | |---test_profile.json
|---rawfile // Other types of files are saved as raw files and will not be integrated into the resources.index file. You can customize the file name as needed.
```
**Table 1** Classification of the resources directory
| Category | base Subdirectory | Qualifiers Subdirectory | rawfile Subdirectory |
| ---- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| Structure| The **base** subdirectory is a default directory. If no qualifiers subdirectories in the **resources** directory of the application match the device status, the resource file in the **base** subdirectory will be automatically referenced.<br>Resource group subdirectories are located at the second level of subdirectories to store basic elements such as strings, colors, and boolean values, as well as resource files such as media, animations, and layouts. For details, see [Resource Group Subdirectories](#resource-group-subdirectories).| You need to create qualifiers subdirectories on your own. Each directory name consists of one or more qualifiers that represent the application scenarios or device characteristics. For details, see [Qualifiers Subdirectories](#qualifiers-subdirectories).<br>Resource group subdirectories are located at the second level of subdirectories to store basic elements such as strings, colors, and boolean values, as well as resource files such as media, animations, and layouts. For details, see [Resource Group Subdirectories](#resource-group-subdirectories).| You can create multiple levels of subdirectories with custom directory names. They can be used to store various resource files.<br>However, resource files in the **rawfile** subdirectory will not be matched based on the device status.|
| Structure| The **base** subdirectory is a default directory. If no qualifiers subdirectories in the **resources** directory of the application match the device status, the resource file in the **base** subdirectory will be automatically referenced.<br>Resource group subdirectories are located at the second level of subdirectories to store basic elements such as strings, colors, and boolean values, as well as resource files such as media, animations, and layouts. For details, see [Resource Group Subdirectories](#resource-group-subdirectories).| **en_US** and **zh_CN** are two default qualifiers subdirectories. You need to create other qualifiers subdirectories on your own. Each directory name consists of one or more qualifiers that represent the application scenarios or device characteristics. For details, see [Qualifiers Subdirectories](#qualifiers-subdirectories).<br>Resource group subdirectories are located at the second level of subdirectories to store basic elements such as strings, colors, and boolean values, as well as resource files such as media, animations, and layouts. For details, see [Resource Group Subdirectories](#resource-group-subdirectories).| You can create multiple levels of subdirectories with custom directory names. They can be used to store various resource files.<br>However, resource files in the **rawfile** subdirectory will not be matched based on the device status.|
| Compilation| Resource files in the subdirectory are compiled into binary files, and each resource file is assigned an ID. | Resource files in the subdirectory are compiled into binary files, and each resource file is assigned an ID. | Resource files in the subdirectory are directly packed into the application without being compiled, and no IDs will be assigned to the resource files. |
| Reference| Resource files in the subdirectory are referenced based on the resource type and resource name. | Resource files in the subdirectory are referenced based on the resource type and resource name. | Resource files in the subdirectory are referenced based on the file path and file name. |
......@@ -77,14 +93,13 @@ The name of a qualifiers subdirectory consists of one or more qualifiers that re
You can create resource group subdirectories (including element, media, and profile) in the **base** and qualifiers subdirectories to store resource files of specific types.
**Table 3** Resource group subdirectories
**Table 3** Resource group subdirectories
| Resource Group Subdirectory | Description | Resource File |
| ------- | ---------------------------------------- | ---------------------------------------- |
| element | Indicates element resources. Each type of data is represented by a JSON file. (Only files are supported in this directory.) The options are as follows:<br>- **boolean**: boolean data<br>- **color**: color data<br>- **float**: floating-point data<br>- **intarray**: array of integers<br>- **integer**: integer data<br>- **pattern**: pattern data<br>- **plural**: plural form data<br>- **strarray**: array of strings<br>- **string**: string data| It is recommended that files in the **element** subdirectory be named the same as the following files, each of which can contain only data of the same type:<br>- boolean.json<br>- color.json<br>- float.json<br>- intarray.json<br>- integer.json<br>- pattern.json<br>- plural.json<br>- strarray.json<br>- string.json |
| media | Indicates media resources, including non-text files such as images, audios, and videos. (Only files are supported in this directory.) | The file name can be customized, for example, **icon.png**. |
| profile | Indicates a custom configuration file. You can obtain the file content by using the [getProfileByAbility](../reference/apis/js-apis-bundleManager.md#bundlemanagergetprofilebyability) API. (Only files are supported in this directory.) | The file name can be customized, for example, **test_profile.json**. |
| rawfile | Indicates other types of files, which are stored in their raw formats after the application is built as an HAP file. They will not be integrated into the **resources.index** file.| The file name can be customized. |
**Media Resource Types**
......@@ -231,7 +246,7 @@ When referencing resources in the **rawfile** subdirectory, use the **"$rawfile(
>
> The return value of **$r** is a **Resource** object. You can obtain the corresponding string by using the [getStringValue](../reference/apis/js-apis-resource-manager.md#getstringvalue9) API.
In the **.ets** file, you can use the resources defined in the **resources** directory. The following is a resource usage example based on the resource file examples in [Resource Group Sub-directories](#resource-group-subdirectories):
In the **.ets** file, you can use the resources defined in the **resources** directory. As described in [Resource Group Subdirectories](#resource-group-subdirectories), you can reference .json resource files, including **color.json**, **string.json**, and **plural.json**. The usage is as follows:
```ts
Text($r('app.string.string_hello'))
......@@ -242,13 +257,14 @@ Text($r('app.string.string_world'))
.fontColor($r('app.color.color_world'))
.fontSize($r('app.float.font_world'))
// Reference string resources. The second parameter of $r is used to replace %s, and value is "We will arrive at five'o clock".
Text($r('app.string.message_arrive', "five'o clock"))
// Reference string resources. The first parameter of $r indicates the string resource, and the second parameter is used to replace %s in the string.json file.
// In this example, the resultant value is "We will arrive at five of the clock".
Text($r('app.string.message_arrive', "five of the clock"))
.fontColor($r('app.color.color_hello'))
.fontSize($r('app.float.font_hello'))
// Reference plural resources. The first parameter indicates the plural resource, the second parameter indicates the number of plural resources, and the third parameter indicates the substitute of %d.
// The value is "5 apple" in singular form and "5 apples" in plural form.
// Reference plural resources. The first parameter of $r indicates the plural resource, the second parameter indicates the number of plural resources (for English, **one** indicates singular and is represented by **1**, and **other** indicates plural and is represented by an integer greater than or equal to 1; for Chinese, **other** indicates both singular and plural), and the third parameter is used to replace %d.
// In this example, the resultant value is "5 apples".
Text($r('app.plural.eat_apple', 5, 5))
.fontColor($r('app.color.color_world'))
.fontSize($r('app.float.font_world'))
......
......@@ -10,7 +10,7 @@
## Creating an ArkTS Project
1. If you are opening DevEco Studio for the first time, click **Create Project**. If a project is already open, choose **File** > **New** > **Create Project** from the menu bar. On the **Choose Your Ability Template** page, select **Application** (or **Atomic Service**, depending on your project), select **Empty Ability** as the template, and click Next.
1. If you are opening DevEco Studio for the first time, click **Create Project**. If a project is already open, choose **File** > **New** > **Create Project** from the menu bar. On the **Choose Your Ability Template** page, select **Application** (or **Atomic Service**, depending on your project), select **Empty Ability** as the template, and click **Next**.
![createProject](figures/createProject.png)
......
......@@ -10,7 +10,7 @@
## Creating an ArkTS Project
1. If you are opening DevEco Studio for the first time, click **Create Project**. If a project is already open, choose **File** > **New** > **Create Project** from the menu bar. On the **Choose Your Ability Template** page, select **Application** (or **Atomic Service**, depending on your project), select **Empty Ability** as the template, and click Next.
1. If you are opening DevEco Studio for the first time, click **Create Project**. If a project is already open, choose **File** > **New** > **Create Project** from the menu bar. On the **Choose Your Ability Template** page, select **Application** (or **Atomic Service**, depending on your project), select **Empty Ability** as the template, and click **Next**.
![createProject](figures/createProject.png)
......
......@@ -8,7 +8,7 @@
## Creating a JavaScript Project
1. If you are opening DevEco Studio for the first time, click **Create Project**. If a project is already open, choose **File** > **New** > **Create Project** from the menu bar. On the **Choose Your Ability Template** page, select **Application** (or **Atomic Service**, depending on your project), select **Empty Ability** as the template, and click Next.
1. If you are opening DevEco Studio for the first time, click **Create Project**. If a project is already open, choose **File** > **New** > **Create Project** from the menu bar. On the **Choose Your Ability Template** page, select **Application** (or **Atomic Service**, depending on your project), select **Empty Ability** as the template, and click **Next**.
![createProject](figures/createProject.png)
......
......@@ -18,8 +18,6 @@
- [@ohos.app.form.FormExtensionAbility (FormExtensionAbility)](js-apis-app-form-formExtensionAbility.md)
- [@ohos.application.DataShareExtensionAbility (DataShare Extension Ability)](js-apis-application-dataShareExtensionAbility.md)
- [@ohos.application.StaticSubscriberExtensionAbility (StaticSubscriberExtensionAbility)](js-apis-application-staticSubscriberExtensionAbility.md)
- Stage Model (To Be Deprecated Soon)
- [@ohos.application.EnvironmentCallback (EnvironmentCallback)](js-apis-application-environmentCallback.md)
- FA Model
- [@ohos.ability.ability (Ability)](js-apis-ability-ability.md)
- [@ohos.ability.featureAbility (FeatureAbility)](js-apis-ability-featureAbility.md)
......@@ -39,10 +37,12 @@
- [@ohos.app.ability.Want (Want)](js-apis-app-ability-want.md)
- [@ohos.app.ability.wantAgent (WantAgent)](js-apis-app-ability-wantAgent.md)
- [@ohos.app.ability.wantConstant (wantConstant)](js-apis-app-ability-wantConstant.md)
- [@ohos.app.businessAbilityRouter (Business Ability Router)](js-apis-businessAbilityRouter.md)
- [@ohos.app.form.formBindingData (formBindingData)](js-apis-app-form-formBindingData.md)
- [@ohos.app.form.formHost (FormHost)](js-apis-app-form-formHost.md)
- [@ohos.app.form.formInfo (FormInfo)](js-apis-app-form-formInfo.md)
- [@ohos.app.form.formProvider (FormProvider)](js-apis-app-form-formProvider.md)
- [@ohos.application.uriPermissionManager (URI Permission Management)](js-apis-uripermissionmanager.md)
- Both Models (To Be Deprecated Soon)
- [@ohos.ability.dataUriUtils (DataUriUtils)](js-apis-ability-dataUriUtils.md)
- [@ohos.ability.errorCode (ErrorCode)](js-apis-ability-errorCode.md)
......@@ -139,7 +139,11 @@
- [NotificationSlot](js-apis-inner-notification-notificationSlot.md)
- [NotificationTemplate](js-apis-inner-notification-notificationTemplate.md)
- [NotificationUserInput](js-apis-inner-notification-notificationUserInput.md)
- Bundle Management
- Common Events
- [Common Events of the Bundle Management Subsystem](common_event/commonEvent-bundleManager.md)
- [Common Events of the Notification Service](common_event/commonEvent-ans.md)
- [Common Events of the Telephony Subsystem](common_event/commonEvent-telephony.md)
- Bundle Management
- [@ohos.bundle.appControl (appControl)](js-apis-appControl.md)
- [@ohos.bundle.bundleManager (bundleManager)](js-apis-bundleManager.md)
- [@ohos.bundle.bundleMonitor (bundleMonitor)](js-apis-bundleMonitor.md)
......@@ -148,6 +152,7 @@
- [@ohos.bundle.freeInstall (freeInstall)](js-apis-freeInstall.md)
- [@ohos.bundle.installer (installer)](js-apis-installer.md)
- [@ohos.bundle.launcherBundleManager (launcherBundleManager)](js-apis-launcherBundleManager.md)
- [@ohos.bundle.overlay (overlay)](js-apis-overlay.md)
- [@ohos.zlib (Zip)](js-apis-zlib.md)
- bundleManager
- [abilityInfo](js-apis-bundleManager-abilityInfo.md)
......@@ -155,18 +160,22 @@
- [AppProvisionInfo](js-apis-bundleManager-AppProvisionInfo.md)
- [bundleInfo](js-apis-bundleManager-bundleInfo.md)
- [BundlePackInfo](js-apis-bundleManager-BundlePackInfo.md)
- [BusinessAbilityInfo](js-apis-bundleManager-businessAbilityInfo.md)
- [dispatchInfo](js-apis-bundleManager-dispatchInfo.md)
- [elementName](js-apis-bundleManager-elementName.md)
- [extensionAbilityInfo](js-apis-bundleManager-extensionAbilityInfo.md)
- [hapModuleInfo](js-apis-bundleManager-hapModuleInfo.md)
- [launcherAbilityInfo](js-apis-bundleManager-launcherAbilityInfo.md)
- [metadata](js-apis-bundleManager-metadata.md)
- [OverlayModuleInfo](js-apis-bundleManager-overlayModuleInfo.md)
- [permissionDef](js-apis-bundleManager-permissionDef.md)
- [remoteAbilityInfo](js-apis-bundleManager-remoteAbilityInfo.md)
- [SharedBundleInfo](js-apis-bundleManager-sharedBundleInfo.md)
- [shortcutInfo](js-apis-bundleManager-shortcutInfo.md)
- UI Page
- [@ohos.animator (Animator)](js-apis-animator.md)
- [@ohos.arkui.componentSnapshot (Component Snapshot)](js-apis-arkui-componentSnapshot.md)
- [@ohos.arkui.drawableDescriptor (DrawableDescriptor)](js-apis-arkui-drawableDescriptor.md)
- [@ohos.curves (Interpolation Calculation)](js-apis-curve.md)
- [@ohos.matrix4 (Matrix Transformation)](js-apis-matrix4.md)
......@@ -264,7 +273,7 @@
- [@ohos.net.connection (Network Connection Management)](js-apis-net-connection.md)
- [@ohos.net.ethernet (Ethernet Connection Management)](js-apis-net-ethernet.md)
- [@ohos.net.http (Data Request)](js-apis-http.md)
- [@ohos.net.policy (Network Policy Management)](js-apis-net-policy.md)
- [@ohos.net.mdns (mDNS Management)](js-apis-net-mdns.md)
- [@ohos.net.sharing (Network Sharing)](js-apis-net-sharing.md)
- [@ohos.net.socket (Socket Connection)](js-apis-socket.md)
- [@ohos.net.webSocket (WebSocket Connection)](js-apis-webSocket.md)
......@@ -449,4 +458,4 @@
- [remoteAbilityInfo](js-apis-bundle-remoteAbilityInfo.md)
- [shortcutInfo](js-apis-bundle-ShortcutInfo.md)
- data/rdb
- [resultSet (Result Set)](js-apis-data-resultset.md)
\ No newline at end of file
- [resultSet](js-apis-data-resultset.md)
\ No newline at end of file
......@@ -18,7 +18,7 @@ import ability from '@ohos.ability.ability';
| Name | Type | Description |
| ----------- | -------------------- | ------------------------------------------------------------ |
| DataAbilityHelper | [DataAbilityHelper](js-apis-inner-ability-dataAbilityHelper.md) | Level-2 module **DataAbilityHelper**. |
| PacMap | [PacMap](js-apis-inner-application-pacMap.md) | Level-2 module **PacMap**.|
| PacMap | [PacMap](js-apis-inner-ability-dataAbilityHelper.md#pacmap) | Level-2 module **PacMap**.|
| DataAbilityOperation | [DataAbilityOperation](js-apis-inner-ability-dataAbilityOperation.md) | Level-2 module **DataAbilityOperation**.|
| DataAbilityResult | [DataAbilityResult](js-apis-inner-ability-dataAbilityResult.md) | Level-2 module **DataAbilityResult**.|
| AbilityResult | [AbilityResult](js-apis-inner-ability-abilityResult.md) | Level-2 module **AbilityResult**.|
......
......@@ -370,7 +370,7 @@ Obtains the accessibility application list. This API uses a promise to return th
> **NOTE**
>
> This API is supported since API version 7 and deprecated since API version 9.
> You are advised to use[getAccessibilityExtensionList()](#accessibilitygetaccessibilityextensionlist9).
> You are advised to use [getAccessibilityExtensionList()](#accessibilitygetaccessibilityextensionlist9).
**System capability**: SystemCapability.BarrierFree.Accessibility.Core
......
# @ohos.app.ability.abilityDelegatorRegistry (AbilityDelegatorRegistry)
**AbilityDelegatorRegistry**, a module of the [Test Framework](../../ability-deprecated/ability-delegator.md), is used to obtain [AbilityDelegator](js-apis-inner-application-abilityDelegator.md) and [AbilityDelegatorArgs](js-apis-inner-application-abilityDelegatorArgs.md) objects. **AbilityDelegator** provides APIs for creating **AbilityMonitor** objects, which can be used to listen for ability lifecycle changes. **AbilityDelegatorArgs** provides APIs for obtaining test parameters.
**AbilityDelegatorRegistry**, a module of the [arkXtest User Guide](../../application-test/arkxtest-guidelines.md), is used to obtain [AbilityDelegator](js-apis-inner-application-abilityDelegator.md) and [AbilityDelegatorArgs](js-apis-inner-application-abilityDelegatorArgs.md) objects. **AbilityDelegator** provides APIs for creating **AbilityMonitor** objects, which can be used to listen for ability lifecycle changes. **AbilityDelegatorArgs** provides APIs for obtaining test parameters.
> **NOTE**
>
......
......@@ -26,7 +26,7 @@ import common from '@ohos.app.ability.common';
| FormExtensionContext | [FormExtensionContext](js-apis-inner-application-formExtensionContext.md) | Level-2 module **FormExtensionContext**.|
| ServiceExtensionContext | [ServiceExtensionContext](js-apis-inner-application-serviceExtensionContext.md) | Level-2 module **ServiceExtensionContext**.|
| EventHub | [EventHub](js-apis-inner-application-eventHub.md) | Level-2 module **EventHub**.|
| PacMap | [PacMap](js-apis-inner-application-pacMap.md) | Level-2 module **PacMap**.|
| PacMap | [PacMap](js-apis-inner-ability-dataAbilityHelper.md#pacmap) | Level-2 module **PacMap**.|
| AbilityResult | [AbilityResult](js-apis-inner-ability-abilityResult.md) | Level-2 module **AbilityResult**.|
| ConnectOptions | [ConnectOptions](js-apis-inner-ability-connectOptions.md) | Level-2 module **ConnectOptions**.|
......
......@@ -130,6 +130,6 @@ import Want from '@ohos.application.Want';
});
```
- For more details and examples, see [Want](../../application-models/want-overview.md).
- For more details and examples, see [Application Model](../../application-models/application-model-composition.md).
<!--no_check-->
......@@ -36,7 +36,7 @@ For details about the error codes, see [Thermal Manager Error Codes](../errorcod
| Code | Error Message |
|---------|---------|
| 4600101 | Operation failed. Cannot connect to service.|
| 4600101 | If connecting to the service failed. |
**Example**
......@@ -72,7 +72,7 @@ For details about the error codes, see [Thermal Manager Error Codes](../errorcod
| Code | Error Message |
|---------|---------|
| 4600101 | Operation failed. Cannot connect to service.|
| 4600101 | If connecting to the service failed. |
**Example**
......@@ -114,7 +114,7 @@ For details about the error codes, see [Thermal Manager Error Codes](../errorcod
| Code | Error Message |
|---------|---------|
| 4600101 | Operation failed. Cannot connect to service.|
| 4600101 | If connecting to the service failed. |
**Example**
......@@ -155,7 +155,7 @@ For details about the error codes, see [Thermal Manager Error Codes](../errorcod
| Code | Error Message |
|---------|---------|
| 4600101 | Operation failed. Cannot connect to service.|
| 4600101 | If connecting to the service failed. |
**Example**
......@@ -196,13 +196,13 @@ For details about the error codes, see [Thermal Manager Error Codes](../errorcod
| Code | Error Message |
|---------|---------|
| 4600101 | Operation failed. Cannot connect to service.|
| 4600101 | If connecting to the service failed. |
**Example**
```js
try {
var value = batteryStats.getHardwareUnitPowerValue(ConsumptionType.CONSUMPTION_TYPE_SCREEN);
var value = batteryStats.getHardwareUnitPowerValue(batteryStats.ConsumptionType.CONSUMPTION_TYPE_SCREEN);
console.info('battery statistics value of hardware is: ' + value);
} catch(err) {
console.error('get battery statistics percent of hardware failed, err: ' + err);
......@@ -237,13 +237,13 @@ For details about the error codes, see [Thermal Manager Error Codes](../errorcod
| Code | Error Message |
|---------|---------|
| 4600101 | Operation failed. Cannot connect to service.|
| 4600101 | If connecting to the service failed. |
**Example**
```js
try {
var percent = batteryStats.getHardwareUnitPowerPercent(ConsumptionType.CONSUMPTION_TYPE_SCREEN);
var percent = batteryStats.getHardwareUnitPowerPercent(batteryStats.ConsumptionType.CONSUMPTION_TYPE_SCREEN);
console.info('battery statistics percent of hardware is: ' + percent);
} catch(err) {
console.error('get battery statistics percent of hardware failed, err: ' + err);
......
......@@ -22,7 +22,7 @@ Sets the screen brightness.
**System API**: This is a system API.
**System capability**: SystemCapability.PowerManager.DisplayPowerManager
**System capability:** SystemCapability.PowerManager.DisplayPowerManager
**Parameters**
......@@ -34,9 +34,9 @@ Sets the screen brightness.
For details about the error codes, see [Screen Brightness Error Codes](../errorcodes/errorcode-brightness.md).
| Code | Error Message |
| ID | Error Message |
|---------|---------|
| 4700101 | Operation failed. Cannot connect to service.|
| 4700101 | If connecting to the service failed. |
**Example**
......
......@@ -81,7 +81,7 @@ Unsubscribes from bundle installation, uninstall, and update events.
| Name | Type | Mandatory| Description |
| ---------------------------- | -------- | ---- | ---------------------------------------------------------- |
| type| BundleChangedEvent| Yes | Type of the event to unsubscribe from. |
| callback | callback\<BundleChangedInfo>| No | Callback used for the unsubscription. If this parameter is left empty, all callbacks of the current event are unsubscribed from.|
| callback | callback\<BundleChangedInfo>| No | Callback used for the unsubscription. By default, no value is passed, and all callbacks of the current event are unsubscribed from.|
**Example**
......
......@@ -17,6 +17,8 @@ import charger from '@ohos.charger';
Enumerates charging types.
**System API**: This is a system API.
**System capability**: SystemCapability.PowerManager.BatteryManager.Core
| Name | Value | Description |
......
# @ohos.multimodalInput.inputDeviceCooperate (Screen Hopping)
The **inputDeviceCooperate** module enables two or more networked devices to share the keyboard and mouse for collaborative operations.
The **inputDeviceCooperate** module implements screen hopping for two or more networked devices to share the keyboard and mouse for collaborative operations.
> **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 APIs provided by this module are system APIs.
> - 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 APIs provided by this module are system APIs.
## Modules to Import
......@@ -66,7 +66,7 @@ Specifies whether to enable screen hopping. This API uses a promise to return th
**Return value**
| Name | Description |
| Parameters | Description |
| ------------------- | ------------------------------- |
| Promise&lt;void&gt; | Promise used to return the result. |
......@@ -221,7 +221,7 @@ Stops screen hopping. This API uses a promise to return the result.
| Name | Description |
| -------- | ---------------------------- |
| Promise\<void> | Promise used to return the result. |
| Promise\<void> | Promise used to return the result. |
**Example**
......@@ -287,7 +287,7 @@ Checks whether screen hopping is enabled. This API uses a promise to return the
**Return value**
| Name | Description |
| Parameters | Description |
| ------------------- | ------------------------------- |
| Promise<{ state: boolean }>| Promise used to return the result. |
......@@ -296,6 +296,7 @@ Checks whether screen hopping is enabled. This API uses a promise to return the
**Example**
```js
let deviceDescriptor = "descriptor";
try {
inputDeviceCooperate.getState(deviceDescriptor).then((data) => {
console.log(`Get the status success, data: ${JSON.stringify(data)}`);
......@@ -311,7 +312,7 @@ try {
on(type: 'cooperation', callback: AsyncCallback<{ deviceDescriptor: string, eventMsg: EventMsg }>): void
Enables listening for screen hopping events.
Enables listening for screen hopping status change events.
**System capability**: SystemCapability.MultimodalInput.Input.Cooperator
......@@ -340,7 +341,7 @@ try {
off(type: 'cooperation', callback?: AsyncCallback\<void>): void
Disables listening for screen hopping events.
Disables listening for screen hopping status change events.
**System capability**: SystemCapability.MultimodalInput.Input.Cooperator
......@@ -388,7 +389,7 @@ Enumerates screen hopping event.
**System capability**: SystemCapability.MultimodalInput.Input.Cooperator
| Name | Value | Description |
| Name | Value | Description |
| -------- | --------- | ----------------- |
| MSG_COOPERATE_INFO_START | 200 | Screen hopping starts. |
| MSG_COOPERATE_INFO_SUCCESS | 201 | Screen hopping succeeds. |
......
......@@ -1634,7 +1634,7 @@ Executes an SQL statement that contains specified arguments but returns no value
```js
const SQL_DELETE_TABLE = "DELETE FROM test WHERE name = ?"
rdbStore.executeSql(SQL_CREATE_TABLE, ['zhangsan'], function(err) {
rdbStore.executeSql(SQL_DELETE_TABLE, ['zhangsan'], function(err) {
if (err) {
console.info("Failed to execute SQL, err: " + err)
return
......@@ -2045,7 +2045,7 @@ Registers an observer for this RDB store. When the data in the RDB store changes
| -------- | -------- | -------- | -------- |
| event | string | Yes| The value is'dataChange', which indicates a data change event.|
| type | [SubscribeType](#subscribetype8) | Yes| Subscription type to register.|
| observer | Callback&lt;Array&lt;string&gt;&gt; | Yes| Observer that listens for the data changes in the RDB store.|
| observer | Callback&lt;Array&lt;string&gt;&gt; | Yes| Observer that listens for the data changes in the RDB store. **Array<string>** indicates the ID of the peer device whose data in the database is changed.|
**Example**
......@@ -2076,7 +2076,7 @@ Unregisters the observer of the specified type from the RDB store. This API uses
| -------- | -------- | -------- | -------- |
| event | string | Yes| The value is'dataChange', which indicates a data change event.|
| type | [SubscribeType](#subscribetype8) | Yes| Subscription type to unregister.|
| observer | Callback&lt;Array&lt;string&gt;&gt; | Yes| Data change observer registered.|
| observer | Callback&lt;Array&lt;string&gt;&gt; | Yes| Data change observer to unregister. **Array<string>** indicates the ID of the peer device whose data in the database is changed.|
**Example**
......
......@@ -232,7 +232,6 @@ For details about the error codes, see [Bundle Error Codes](../errorcodes/errorc
| ID| Error Message |
| -------- | ----------------------------------------- |
| 17700004 | The specified user ID is not found. |
| 17700023 | The specified default app does not exist. |
| 17700025 | The specified type is invalid. |
......@@ -415,7 +414,6 @@ For details about the error codes, see [Bundle Error Codes](../errorcodes/errorc
| ID| Error Message |
| -------- | ---------------------------------------------- |
| 17700004 | The specified user ID is not found. |
| 17700025 | The specified type is invalid. |
| 17700028 | The specified ability does not match the type. |
......@@ -574,7 +572,6 @@ For details about the error codes, see [Bundle Error Codes](../errorcodes/errorc
| ID| Error Message |
| -------- | ----------------------------------- |
| 17700004 | The specified user ID is not found. |
| 17700025 | The specified type is invalid. |
**Example**
......
......@@ -7,6 +7,7 @@
> 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.
## Modules to Import
```js
import picker from '@ohos.file.picker';
```
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册