From 5b59ac7a19ad3612e0813787aad6d0e42bf50da5 Mon Sep 17 00:00:00 2001 From: zengyawen Date: Fri, 11 Feb 2022 14:53:46 +0800 Subject: [PATCH] update docs Signed-off-by: zengyawen --- .../Readme-EN.md | 4 + ...ckground-agent-scheduled-reminder-guide.md | 683 ++++++ ...round-agent-scheduled-reminder-overview.md | 4 + en/application-dev/database/Readme-EN.md | 13 +- .../database-relational-development.md | 671 ++++++ .../database/database-relational-overview.md | 42 + .../figures/en-us_image_0000001199139454.png | Bin 0 -> 12254 bytes .../database/figures/how-rdb-works.png | Bin 0 -> 12896 bytes .../lightweight-data-store-development.md | 272 +++ .../lightweight-data-store-overview.md | 31 + .../media/figures/playback-status.png | Bin 23062 -> 0 bytes .../reference/apis/Readme-EN.md | 4 + .../reference/apis/js-apis-Context.md | 23 - .../reference/apis/js-apis-commonEvent.md | 11 - .../reference/apis/js-apis-convertxml.md | 277 +++ .../apis/js-apis-dataAbilityHelper.md | 31 +- .../reference/apis/js-apis-featureAbility.md | 22 - .../reference/apis/js-apis-i18n.md | 2142 ++++++++++++++++- .../reference/apis/js-apis-intl.md | 1470 ++++++++--- .../reference/apis/js-apis-notification.md | 83 - .../reference/apis/js-apis-particleAbility.md | 13 - .../reference/apis/js-apis-process.md | 477 +++- .../reference/apis/js-apis-reminderAgent.md | 1199 +++++++++ .../apis/js-apis-resource-manager.md | 153 +- .../reference/apis/js-apis-system-time.md | 24 - .../reference/apis/js-apis-uri.md | 338 +++ .../apis/js-apis-useriam-userauth.md | 24 - .../reference/apis/js-apis-worker.md | 129 +- .../reference/apis/js-apis-xml.md | 976 ++++++++ .../background-task-management/Readme-CN.md | 5 + .../background-task-overview.md | 2 +- zh-cn/application-dev/database/Readme-CN.md | 13 +- .../database-preference-guidelines.md | 161 ++ .../database/database-preference-overview.md | 28 + .../database-relational-guidelines.md | 200 ++ .../database/database-relational-overview.md | 41 + .../database/figures/how-rdb-works.png | Bin 0 -> 21260 bytes .../figures/zh-cn_image_0000001199139454.png | Bin 0 -> 14201 bytes .../reference/apis/js-apis-hiappevent.md | 4 +- 39 files changed, 8892 insertions(+), 678 deletions(-) create mode 100644 en/application-dev/background-agent-scheduled-reminder/Readme-EN.md create mode 100644 en/application-dev/background-agent-scheduled-reminder/background-agent-scheduled-reminder-guide.md create mode 100644 en/application-dev/background-agent-scheduled-reminder/background-agent-scheduled-reminder-overview.md create mode 100644 en/application-dev/database/database-relational-development.md create mode 100644 en/application-dev/database/database-relational-overview.md create mode 100644 en/application-dev/database/figures/en-us_image_0000001199139454.png create mode 100644 en/application-dev/database/figures/how-rdb-works.png create mode 100644 en/application-dev/database/lightweight-data-store-development.md create mode 100644 en/application-dev/database/lightweight-data-store-overview.md delete mode 100755 en/application-dev/media/figures/playback-status.png create mode 100644 en/application-dev/reference/apis/js-apis-convertxml.md create mode 100644 en/application-dev/reference/apis/js-apis-reminderAgent.md create mode 100644 en/application-dev/reference/apis/js-apis-uri.md create mode 100644 en/application-dev/reference/apis/js-apis-xml.md create mode 100644 zh-cn/application-dev/background-task-management/Readme-CN.md create mode 100644 zh-cn/application-dev/database/database-preference-guidelines.md create mode 100644 zh-cn/application-dev/database/database-preference-overview.md create mode 100644 zh-cn/application-dev/database/database-relational-guidelines.md create mode 100644 zh-cn/application-dev/database/database-relational-overview.md create mode 100644 zh-cn/application-dev/database/figures/how-rdb-works.png create mode 100644 zh-cn/application-dev/database/figures/zh-cn_image_0000001199139454.png diff --git a/en/application-dev/background-agent-scheduled-reminder/Readme-EN.md b/en/application-dev/background-agent-scheduled-reminder/Readme-EN.md new file mode 100644 index 0000000000..7f4083e641 --- /dev/null +++ b/en/application-dev/background-agent-scheduled-reminder/Readme-EN.md @@ -0,0 +1,4 @@ +# Agent-Powered Scheduled Reminders + +- [Overview](background-agent-scheduled-reminder-overview.md) +- [Development Guidelines](background-agent-scheduled-reminder-guide.md) diff --git a/en/application-dev/background-agent-scheduled-reminder/background-agent-scheduled-reminder-guide.md b/en/application-dev/background-agent-scheduled-reminder/background-agent-scheduled-reminder-guide.md new file mode 100644 index 0000000000..dedcdc819a --- /dev/null +++ b/en/application-dev/background-agent-scheduled-reminder/background-agent-scheduled-reminder-guide.md @@ -0,0 +1,683 @@ +# Development Guidelines + +## When to Use + +You can set your application to call the **ReminderRequest** class to create scheduled reminders for countdown timers, calendar events, and alarm clocks. When the created reminders are published, the timing and pop-up notification functions of your application will be taken over by the reminder agent in the background, even when your application is frozen or exits. + +## Available APIs + +**reminderAgent** encapsulates the methods for publishing and canceling reminders. + +**Table 1** Major APIs in reminderAgent + + + + + + + + + + + + + + + + + + + + + + + + + +

API

+

Description

+

function publishReminder(reminderReq: ReminderRequest, callback: AsyncCallback<number>): void;

+

function publishReminder(reminderReq: ReminderRequest): Promise<number>;

+

Publishes a scheduled reminder.

+

The maximum number of valid notifications (excluding expired ones that will not pop up again) is 30 for one application and 2000 for the entire system.

+

function cancelReminder(reminderId: number, callback: AsyncCallback<void>): void;

+

function cancelReminder(reminderId: number): Promise<void>;

+

Cancels a specified reminder. (The value of reminderId is obtained from the return value of publishReminder.)

+

function getValidReminders(callback: AsyncCallback<Array<ReminderRequest>>): void;

+

function getValidReminders(): Promise<Array<ReminderRequest>>;

+

Obtains all valid reminders set by the current application.

+

function cancelAllReminders(callback: AsyncCallback<void>): void;

+

function cancelAllReminders(): Promise<void>;

+

Cancels all reminders set by the current application.

+

function addNotificationSlot(slot: NotificationSlot, callback: AsyncCallback<void>): void;

+

function addNotificationSlot(slot: NotificationSlot): Promise<void>;

+

Registers a NotificationSlot instance to be used by the reminder.

+

function removeNotificationSlot(slotType: notification.SlotType, callback: AsyncCallback<void>): void;

+

function removeNotificationSlot(slotType: notification.SlotType): Promise<void>;

+

Removes a NotificationSlot instance of a specified type.

+
+ +**ActionButtonType** enumerates types of buttons displayed in a reminder notification. + +**Table 2** ActionButtonType enumeration + + + + + + + + + + +

Name

+

Description

+

ACTION_BUTTON_TYPE_CLOSE

+

Close button, which can be tapped to stop the reminder alert tone, close the reminder notification, and cancel the reminder snoozing.

+
+ +**ReminderType** enumerates the reminder types. + +**Table 3** ReminderType enumeration + + + + + + + + + + + + + + + + +

Name

+

Description

+

REMINDER_TYPE_TIMER

+

Countdown reminder.

+

REMINDER_TYPE_CALENDAR

+

Calendar reminder.

+

REMINDER_TYPE_ALARM

+

Alarm reminder.

+
+ +**ActionButton** defines a button displayed in the reminder notification. + +**Table 4** ActionButton instance + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

title

+

string

+

Yes

+

Text on the button.

+

type

+

ActionButtonType

+

Yes

+

Button type.

+
+ +**WantAgent** sets the package and ability that are redirected to when the reminder notification is clicked. + +**Table 5** WantAgent instance + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

pkgName

+

string

+

Yes

+

Name of the package redirected to when the reminder notification is clicked.

+

abilityName

+

string

+

Yes

+

Name of the ability redirected to when the reminder notification is clicked.

+
+ +**MaxScreenWantAgent** sets the name of the target package and ability to start automatically when the reminder arrives and the device is not in use. If the device is in use, a notification will be displayed. + +**Table 6** MaxScreenWantAgent instance + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

pkgName

+

string

+

Yes

+

Name of the package that is automatically started when the reminder arrives and the device is not in use.

+

abilityName

+

string

+

Yes

+

Name of the ability that is automatically started when the reminder arrives and the device is not in use.

+
+ +**ReminderRequest** defines the reminder to publish. + +**Table 7** ReminderRequest instance + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

reminderType

+

ReminderType

+

Yes

+

Type of the reminder.

+

actionButton

+

[ActionButton?, ActionButton?]

+

No

+

Action button displayed in the reminder notification.

+

wantAgent

+

WantAgent

+

No

+

Information about the ability that is redirected to when the notification is clicked.

+

maxScreenWantAgent

+

MaxScreenWantAgent

+

No

+

Information about the ability that is automatically started when the reminder arrives. If the device is in use, a notification will be displayed.

+

ringDuration

+

number

+

No

+

Ring duration.

+

snoozeTimes

+

number

+

No

+

Number of reminder snooze times.

+

timeInterval

+

number

+

No

+

Reminder snooze interval.

+

title

+

string

+

No

+

Reminder title.

+

content

+

string

+

No

+

Reminder content.

+

expiredContent

+

string

+

No

+

Extended content to be displayed when the reminder expires.

+

snoozeContent

+

string

+

No

+

Extended content to be displayed when the reminder is snoozing.

+

notificationId

+

number

+

No

+

Notification ID used by the reminder. For details, see the API reference of the NotificationRequest.setNotificationId(int id) method.

+

slotType

+

SlotType

+

No

+

Type of the slot used by the reminder

+
+ +**ReminderRequestCalendar** extends **ReminderRequest** and defines a reminder for a calendar event. + +The earliest reminder time must be later than the current time. + +**Table 8** ReminderRequestCalendar instance + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

dateTime

+

LocalDateTime

+

Yes

+

Reminder time.

+

repeatMonths

+

Array<number>

+

No

+

Months in which the reminder repeats.

+

repeatDays

+

Array<number>

+

No

+

Date on which the reminder repeats.

+
+ +**ReminderRequestAlarm** extends **ReminderRequest** and defines a reminder for the alarm clock. + +**Table 9** ReminderRequestAlarm instance + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

hour

+

number

+

Yes

+

Hour portion of the reminder time.

+

minute

+

number

+

Yes

+

Minute portion of the reminder time.

+

daysOfWeek

+

Array<number>

+

No

+

Days of a week when the reminder repeats.

+
+ +**ReminderRequestTimer** extends **ReminderRequest** and defines a reminder for a scheduled timer. + +**Table 10** ReminderRequestTimer instance + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

triggerTimeInSeconds

+

number

+

Yes

+

Number of seconds in the countdown timer.

+
+ +**LocalDateTime** defines a **LocalDateTime** instance. + +**Table 11** LocalDateTime instance + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

year

+

number

+

Yes

+

Year.

+

month

+

number

+

Yes

+

Month.

+

day

+

number

+

Yes

+

Date.

+

hour

+

number

+

Yes

+

Hour.

+

minute

+

number

+

Yes

+

Minute.

+

second

+

number

+

No

+

Second.

+
+ +## How to Develop + +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>To publish a reminder, your application needs to apply for the **ohos.permission.PUBLISH\_AGENT\_REMINDER** permission. + +Publish a 10-second countdown reminder. + +1. Define a countdown timer instance. + + ``` + import reminderAgent from '@ohos.reminderAgent'; + import notification from '@ohos.notification'; + export default { + timer: { + reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, + triggerTimeInSeconds: 10, + actionButton: [ + { + title: "close", + type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE + } + ], + wantAgent: { + pkgName: "com.huawei.phone", + abilityName: "com.huawei.phone.MainAbility" + }, + maxScreenWantAgent: { + pkgName: "com.huawei.phone", + abilityName: "com.huawei.phone.MainAbility" + }, + title: "this is title", + content: "this is content", + expiredContent: "this reminder has expired", + notificationId: 100, + slotType: notification.SlotType.SOCIAL_COMMUNICATION + } + } + ``` + +2. Publish the reminder. + + ``` + startTimer() { + reminderAgent.publishReminder(this.timer, (err, reminderId) =>{ + this.printInfo(JSON.stringify(err)); + this.printInfo("reminderId:" + reminderId); + }); + } + ``` + + HTML page code: + + ``` +
+ +
+ ``` + + +Sample code for defining a calendar reminder instance: + +``` +calendar: { + reminderType: reminderAgent.ReminderType.REMINDER_TYPE_CALENDAR, + dateTime: { + year: 2050, + month: 7, + day: 30, + hour: 11, + minute: 14, + second: 30 + }, + repeatMonths: [0], + repeatDays: [0], + actionButton: [ + { + title: "close", + type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE + }, + { + title: "snooze", + type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_SNOOZE + }, + ], + wantAgent: { + pkgName: "com.huawei.phone", + abilityName: "com.huawei.phone.MainAbility" + }, + maxScreenWantAgent: { + pkgName: "com.huawei.phone", + abilityName: "com.huawei.phone.MainAbility" + }, + ringDuration: 5, + snoozeTimes: 2, + timeInterval: 5, + title: "this is title", + content: "this is content", + expiredContent: "this reminder has expired", + snoozeContent: "remind later", + notificationId: 100, + slotType: notification.SlotType.SOCIAL_COMMUNICATION +} +``` + +Sample code for defining an alarm reminder instance: + +``` +alarm: { + reminderType: reminderAgent.ReminderType.REMINDER_TYPE_ALARM, + hour: 11, + minute: 14, + daysOfWeek: [0], + actionButton: [ + { + title: "close", + type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_CLOSE + }, + { + title: "snooze", + type: reminderAgent.ActionButtonType.ACTION_BUTTON_TYPE_SNOOZE + }, + ], + wantAgent: { + pkgName: "com.huawei.phone", + abilityName: "com.huawei.phone.MainAbility" + }, + maxScreenWantAgent: { + pkgName: "com.huawei.phone", + abilityName: "com.huawei.phone.MainAbility" + }, + ringDuration: 5, + snoozeTimes: 2, + timeInterval: 5, + title: "this is title", + content: "this is content", + expiredContent: "this reminder has expired", + snoozeContent: "remind later", + notificationId: 100, + slotType: notification.SlotType.SOCIAL_COMMUNICATION +} +``` + diff --git a/en/application-dev/background-agent-scheduled-reminder/background-agent-scheduled-reminder-overview.md b/en/application-dev/background-agent-scheduled-reminder/background-agent-scheduled-reminder-overview.md new file mode 100644 index 0000000000..32f0b858f3 --- /dev/null +++ b/en/application-dev/background-agent-scheduled-reminder/background-agent-scheduled-reminder-overview.md @@ -0,0 +1,4 @@ +# Overview + +Your application can call the **ReminderRequest** class to create scheduled reminders for countdown timers, calendar events, and alarm clocks. When the created reminders are published, the timing and pop-up notification functions of your application will be taken over by the reminder agent in the background, even when your application is frozen or exits. + diff --git a/en/application-dev/database/Readme-EN.md b/en/application-dev/database/Readme-EN.md index 9e68a292b4..2555d715a7 100644 --- a/en/application-dev/database/Readme-EN.md +++ b/en/application-dev/database/Readme-EN.md @@ -1,4 +1,11 @@ -# Distributed Data Service +# Data Management -- [Distributed Data Service Overview](database-mdds-overview.md) -- [Distributed Data Service Development](database-mdds-guidelines.md) +- Distributed Data Service + - [Distributed Data Service Overview](database-mdds-overview.md) + - [Distributed Data Service Development](database-mdds-guidelines.md) +- Relational Database Overview + - [RDB Overview](database-relational-overview.md) + - [RDB Development](database-relational-guidelines.md) +- Lightweight Data Store + - [Lightweight Data Store Overview](database-preference-overview.md) + - [Lightweight Data Store Development](database-preference-guidelines.md) \ No newline at end of file diff --git a/en/application-dev/database/database-relational-development.md b/en/application-dev/database/database-relational-development.md new file mode 100644 index 0000000000..2411dd2c9a --- /dev/null +++ b/en/application-dev/database/database-relational-development.md @@ -0,0 +1,671 @@ +# RDB Development + +## When to Use + +On the basis of the SQLite database, the RDB allows you to operate data with or without native SQL statements. An RDB is also called RDB store. + +## Available APIs + +**Creating and Deleting an RDB Store** + +The following table describes APIs available for creating and deleting an RDB store. + +**Table 1** APIs for creating and deleting an RDB store + + + + + + + + + + + + + + + + + + + + + + + + +

Class

+

API

+

Description

+

dataRdb

+

getRdbStore(config: StoreConfig, version: number, callback: AsyncCallback<RdbStore>): void

+

Obtains an RDB store. You can set parameters for the RDB store based on service requirements, call APIs to perform data operations, and use a callback to return the result.

+
  • config: configuration of the RDB store.
  • version: version of the RDB store.
  • callback: callback invoked to return the RDB store.
+

dataRdb

+

getRdbStore(config: StoreConfig, version: number): Promise<RdbStore>

+

Obtains an RDB store. You can set parameters for the RDB store based on service requirements, call APIs to perform data operations, and use a promise to return the result.

+
  • config: configuration of the RDB store.
  • version: version of the RDB store.
+

dataRdb

+

deleteRdbStore(name: string, callback: AsyncCallback<void>): void

+

Deletes an RDB store. This method uses a callback to return the result.

+
  • name: name of the RDB store to delete.
  • callback: callback invoked to return the result. If the RDB store is deleted, true will be returned. Otherwise, false will be returned.
+

dataRdb

+

deleteRdbStore(name: string): Promise<void>

+

Deletes an RDB store. This method uses a promise to return the result.

+
  • name: name of the RDB store to delete.
+
+ +**Managing Data in an RDB Store** + +The RDB provides APIs for inserting, deleting, modifying, and querying data in the local RDB store. + +- **Inserting data** + + The RDB provides methods for inserting data through **ValuesBucket** in a data table. If the data is inserted successfully, the row number of the data inserted is returned; otherwise, **-1** is returned. + + **Table 2** APIs for inserting data to a data table + + + + + + + + + + + + + + + + +

Class

+

API

+

Description

+

RdbStore

+

insert(name: string, values: ValuesBucket, callback: AsyncCallback<number>):void

+

Inserts a row of data into a table. This method uses a callback to return the result.

+
  • name: name of the target table.
  • values: data to be inserted into the table.
  • callback: callback invoked to return the result. If the operation is successful, the row ID will be returned. Otherwise, -1 will be returned.
+

RdbStore

+

insert(name: string, values: ValuesBucket): Promise<number>

+

Inserts a row of data into a table. This method uses a promise to return the result.

+
  • name: name of the target table.
  • values: data to be inserted into the table.
+
+ +- **Updating data** + + Call the **update\(\)** method to pass the new data and specify the update conditions by using **RdbPredicates**. If the data is successfully updated, the row number of the updated data is returned; otherwise, **0** is returned. + + **Table 3** APIs for updating data + + + + + + + + + + + + + + + + +

Class

+

API

+

Description

+

RdbStore

+

update(values: ValuesBucket, rdbPredicates: RdbPredicates, callback: AsyncCallback<number>):void

+

Updates the data that meets the conditions specified by the RdbPredicates object. This method uses a callback to return the result.

+
  • values: data to update, which is stored in ValuesBucket.
  • rdbPredicates: conditions for updating data.
  • callback: callback invoked to return the number of rows updated.
+

RdbStore

+

update(values: ValuesBucket, rdbPredicates: RdbPredicates): Promise

+

Updates the data that meets the conditions specified by the RdbPredicates object. This method uses a promise to return the result.

+
  • values: data to update, which is stored in ValuesBucket.
  • rdbPredicates: conditions for updating data.
+
+ +- **Deleting data** + + Call the **delete\(\)** method to delete data meeting the conditions specified by **RdbPredicates**. If the data is deleted, the row number of the deleted data is returned; otherwise, **0** is returned. + + **Table 4** APIs for deleting data + + + + + + + + + + + + + + + + +

Class

+

API

+

Description

+

RdbStore

+

delete(rdbPredicates: RdbPredicates, callback: AsyncCallback<number>):void

+

Deletes data based on the conditions specified by RdbPredicates. This method uses a callback to return the result.

+
  • rdbPredicates: conditions for deleting data.
  • callback: callback invoked to return the number of rows deleted.
+

RdbStore

+

delete(rdbPredicates: RdbPredicates): Promise

+

Deletes data based on the conditions specified by RdbPredicates. This method uses a promise to return the result.

+
  • rdbPredicates: conditions for deleting data.
+
+ +- **Querying data** + + You can query data in the RDB in either of the following ways: + + - Call the **query** method to query data based on the predicates, without passing any SQL statement. + - Run the native SQL statement. + + **Table 5** APIs for querying data + + + + + + + + + + + + + + + + + + + + + + + + +

Class

+

API

+

Description

+

RdbStore

+

query(rdbPredicates: RdbPredicates, columns: Array, callback: AsyncCallback<ResultSet>): void;

+

Queries data in the database based on specified conditions. This method uses a callback to return the result.

+
  • rdbPredicates: conditions for querying data.
+
  • columns: columns to query. If this parameter is not specified, the query applies to all columns.
  • callback: callback invoked to return the result. If the operation is successful, a ResultSet object will be returned.
+

RdbStore

+

query(rdbPredicates: RdbPredicates, columns: Array): Promise<ResultSet>;

+

Queries data in the database based on specified conditions. This method uses a promise to return the result.

+
  • rdbPredicates: conditions for querying data.
+
  • columns: columns to query. If this parameter is not specified, the query applies to all columns.
+

RdbStore

+

querySql(sql: string, bindArgs: Array<ValueType>, callback: AsyncCallback<ResultSet>):void

+

Queries data in the RDB store using the specified SQL statement. This method uses a callback to return the result.

+
  • sql: SQL statement.
+
  • bindArgs: arguments in the SQL statement.
  • callback: callback invoked to return the result. If the operation is successful, a ResultSet object will be returned.
+

RdbStore

+

querySql(sql: string, bindArgs?: Array<ValueType>):Promise<ResultSet>

+

Queries data in the RDB store using the specified SQL statement. This method uses a promise to return the result.

+
  • sql: SQL statement.
+
  • bindArgs: arguments in the SQL statement.
+
+ + +**Using Predicates** + +The RDB provides **RdbPredicates** for you to set database operation conditions. + +**Table 6** APIs for RDB predicates + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Class

+

API

+

Description

+

RdbPredicates

+

equalTo(field: string, value: ValueType): RdbPredicates

+

Sets the RdbPredicates to match the field with data type ValueType and value equal to the specified value.

+
  • field: column name in the database table.
  • value: value to match the RdbPredicates.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

notEqualTo(field: string, value: ValueType): RdbPredicates

+

Sets the RdbPredicates to match the field with data type ValueType and value not equal to the specified value.

+
  • field: column name in the database table.
  • value: value to match the RdbPredicates.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

beginWrap(): RdbPredicates

+

Adds a left parenthesis to the RdbPredicates.

+
  • RdbPredicates: RdbPredicates with a left parenthesis.
+

RdbPredicates

+

endWrap(): RdbPredicates

+

Adds a right parenthesis to the RdbPredicates.

+
  • RdbPredicates: RdbPredicates with a right parenthesis.
+

RdbPredicates

+

or(): RdbPredicates

+

Adds the OR condition to the RdbPredicates.

+
  • RdbPredicates: RdbPredicates with the OR condition.
+

RdbPredicates

+

and(): RdbPredicates

+

Adds the AND condition to the RdbPredicates.

+
  • RdbPredicates: RdbPredicates with the AND condition.
+

RdbPredicates

+

contains(field: string, value: string): RdbPredicats

+

Sets the RdbPredicates to match a string containing the specified value.

+
  • field: column name in the database table.
  • value: value to match the RdbPredicates.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

beginsWith(field: string, value: string): RdbPredicates

+

Sets the RdbPredicates to match a string that starts with the specified value.

+
  • field: column name in the database table.
  • value: value to match the RdbPredicates.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

endsWith(field: string, value: string): RdbPredicates

+

Sets the RdbPredicates to match a string that ends with the specified value.

+
  • field: column name in the database table.
  • value: value to match the RdbPredicates.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

isNull(field: string): RdbPredicates

+

Sets the RdbPredicates to match the field whose value is null.

+
  • field: column name in the database table.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

isNotNull(field: string): RdbPredicates

+

Sets the RdbPredicates to match the field whose value is not null.

+
  • field: column name in the database table.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

like(field: string, value: string): RdbPredicates

+

Sets the RdbPredicates to match a string that is similar to the specified value.

+
  • field: column name in the database table.
  • value: value to match the RdbPredicates.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

glob(field: string, value: string): RdbPredicates

+

Sets the RdbPredicates to match the specified string.

+
  • field: column name in the database table.
  • value: value to match the RdbPredicates.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

between(field: string, low: ValueType, high: ValueType): RdbPredicates

+

Sets the RdbPredicates to match the field with data type ValueType and value within the specified range.

+
  • field: column name in the database table.
  • low: minimum value that matches the RdbPredicates.
  • high: maximum value that matches the RdbPredicates.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

notBetween(field: string, low: ValueType, high: ValueType): RdbPredicates

+

Sets the RdbPredicates to match the field with data type ValueType and value out of the specified range.

+
  • field: column name in the database table.
  • low: minimum value that matches the RdbPredicates.
  • high: maximum value that matches the RdbPredicates.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

greaterThan(field: string, value: ValueType): RdbPredicatesgr

+

Sets the RdbPredicates to match the field with data type ValueType and value greater than the specified value.

+
  • field: column name in the database table.
  • value: value to match the RdbPredicates.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

lessThan(field: string, value: ValueType): RdbPredicates

+

Sets the RdbPredicates to match the field with data type ValueType and value less than the specified value.

+
  • field: column name in the database table.
  • value: value to match the RdbPredicates.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

greaterThanOrEqualTo(field: string, value: ValueType): RdbPredicates

+

Sets the RdbPredicates to match the field with data type ValueType and value greater than or equal to the specified value.

+
  • field: column name in the database table.
  • value: value to match the RdbPredicates.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

lessThanOrEqualTo(field: string, value: ValueType): RdbPredicates

+

Sets the RdbPredicates to match the field with data type ValueType and value less than or equal to the specified value.

+
  • field: column name in the database table.
  • value: value to match the RdbPredicates.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

orderByAsc(field: string): RdbPredicates

+

Sets the RdbPredicates to match the column with values sorted in ascending order.

+
  • field: column name in the database table.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

orderByDesc(field: string): RdbPredicates

+

Sets the RdbPredicates to match the column with values sorted in descending order.

+
  • field: column name in the database table.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

distinct(): RdbPredicates

+

Sets the RdbPredicates to filter out duplicate records.

+
  • RdbPredicates: RdbPredicates that can filter out duplicate records.
+

RdbPredicates

+

limitAs(value: number): RdbPredicates

+

Sets the RdbPredicates to specify the maximum number of records to match in a column.

+
  • value: maximum number of records in a column.
  • RdbPredicates: RdbPredicates that can be used to set the maximum number of records to match in a column.
+

RdbPredicates

+

offsetAs(rowOffset: number): RdbPredicates

+

Sets the RdbPredicates to specify the start position of the returned result.

+
  • rowOffset: start position of the returned result. The value is a positive integer.
  • RdbPredicates: RdbPredicates object that specifies the start position of the returned result.
+

RdbPredicates

+

groupBy(fields: Array<string>): RdbPredicates

+

Sets the RdbPredicates to group rows that have the same value into summary rows.

+
  • fields: names of the columns grouped for querying data.
  • RdbPredicates: RdbPredicates that groups rows that have the same value.
+

RdbPredicates

+

indexedBy(indexName: string): RdbPredicates

+

Sets the RdbPredicates object to specify the index column.

+
  • indexName: name of the index column.
  • RdbPredicates: RdbPredicates object that specifies the index column.
+

RdbPredicates

+

in(field: string, value: Array<ValueType>): RdbPredicates

+

Sets the RdbPredicates to match the field with data type Array<ValueType> and value within the specified range.

+
  • field: column name in the database table.
+
  • value: array of ValueType to match.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+

RdbPredicates

+

notIn(field: string, value: Array<ValueType>): RdbPredicates

+

Sets the RdbPredicates to match the field with data type Array<ValueType> and value out of the specified range.

+
  • field: column name in the database table.
+
  • value: array of ValueType to match.
  • RdbPredicates: RdbPredicates object that matches the specified field.
+
+ +**Using the Result Set** + +A result set can be regarded as rows of data in the queried results. It allows you to traverse and access the data you have queried. The following table describes the external APIs of **ResultSet**. + +>![](public_sys-resources/icon-notice.gif) **NOTICE:** +>After a result set is used, you must call the **close\(\)** method to close it explicitly. + +**Table 7** APIs for using the result set + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Class

+

API

+

Description

+

ResultSet

+

goTo(offset:number): boolean

+

Moves the result set forwards or backwards by an offset relative to its current position.

+

ResultSet

+

goToRow(position: number): boolean

+

Moves the result set to a specified row.

+

ResultSet

+

goToNextRow(): boolean

+

Moves the result set to the next row.

+

ResultSet

+

goToPreviousRow(): boolean

+

Moves the result set to the previous row.

+

ResultSet

+

getColumnIndex(columnName: string): number

+

Obtains the column index based on the specified column name.

+

ResultSet

+

getColumnName(columnIndex: number): string

+

Obtains the column name based on the specified column index.

+

ResultSet

+

goToFirstRow(): boolean

+

Checks whether the result set is located in the first row.

+

ResultSet

+

goToLastRow(): boolean

+

Checks whether the result set is located in the last row.

+

ResultSet

+

getString(columnIndex: number): string

+

Obtains the values in the specified column of the current row, in strings.

+

ResultSet

+

getBlob(columnIndex: number): Uint8Array

+

Obtains the values in the specified column of the current row, in a byte array.

+

ResultSet

+

getDouble(columnIndex: number): number

+

Obtains the values in the specified column of the current row, in double.

+

ResultSet

+

isColumnNull(columnIndex: number): boolean

+

Checks whether the values in the specified column of the current row are null.

+

ResultSet

+

close(): void

+

Closes the result set.

+
+ +**Encrypting an RDB Store** + +You can encrypt an RDB store. + +When creating an RDB store, you can add a key for security purposes. After that, the RDB store can be accessed only with the correct key. You can change the key but cannot delete it. + +Once an RDB store is created without a key, you cannot add a key any longer. + +**Table 8** APIs for changing the key + + + + + + + + + + + + + + + + +

Class

+

API

+

Description

+

RdbStore

+

changeEncryptKey(newEncryptKey:Uint8Array, callback: AsyncCallback<number>):void;

+

Changes the encryption key for an RDB store. This method uses a callback to return the result. If the key is changed, 0 is returned. Otherwise, a non-zero value is returned.

+

RdbStore

+

changeEncryptKey(newEncryptKey:Uint8Array): Promise<number>;

+

Changes the encryption key for an RDB store. This method uses a promise to return the result. If the key is changed, 0 is returned. Otherwise, a non-zero value is returned.

+
+ +## How to Develop + +1. Create an RDB store. + + 1. Configure the RDB attributes, including the name and storage mode of the database and whether it is read-only. + 2. Initialize the table structure and related data in the database. + 3. Create an RDB store. + + The sample code is as follows: + + ``` + import dataRdb from '@ohos.data.rdb'; + + const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, " + "age INTEGER, " + "salary REAL, " + "blobType BLOB)"; + const STORE_CONFIG = {name: "rdbstore.db",} + + let rdbStore = await dataRdb.getRdbStore(STORE_CONFIG, 1); + await rdbStore.executeSql(CREATE_TABLE_TEST); + ``` + +2. Insert data. + + 1. Create a **ValuesBucket** object to store the data you need to insert. + 2. Call the **insert\(\)** method to insert data into the RDB store. + + The sample code is as follows: + + ``` + var u8 = new Uint8Array([1, 2, 3]) + const valueBucket = {"name": "Tom", "age": 18, "salary": 100.5, "blobType": u8,} + let insertPromise = rdbStore.insert("test", valueBucket) + ``` + +3. Query data. + + 1. Create an **RdbPredicates** object to specify query conditions. + 2. Call the **query \(\)** method to query data in the RDB store. + 3. Call the **ResultSet\(\)** method to obtain the query result. + + The sample code is as follows: + + ``` + let predicates = new dataRdb.RdbPredicates("test"); + predicates.equalTo("name", "Tom") + let resultSet = await rdbStore.query(predicates) + + resultSet.goToFirstRow() + const id = await resultSet.getLong(resultSet.getColumnIndex("id")) + const name = await resultSet.getString(resultSet.getColumnIndex("name")) + const age = await resultSet.getLong(resultSet.getColumnIndex("age")) + const salary = await resultSet.getDouble(resultSet.getColumnIndex("salary")) + const blobType = await resultSet.getBlob(resultSet.getColumnIndex("blobType")) + + resultSet.close() + ``` + + diff --git a/en/application-dev/database/database-relational-overview.md b/en/application-dev/database/database-relational-overview.md new file mode 100644 index 0000000000..cd675b9701 --- /dev/null +++ b/en/application-dev/database/database-relational-overview.md @@ -0,0 +1,42 @@ +# RDB Overview + +The relational database \(RDB\) manages data based on relational models. With the underlying SQLite database, the RDB provides a complete mechanism for managing local databases. To satisfy different needs in complicated scenarios, the RDB offers a series of methods for performing operations such as adding, deleting, modifying, and querying data, and supports direct execution of SQL statements. + +## Basic Concepts + +- **RDB** + + A type of database based on the relational model of data. The RDB stores data in rows and columns. An RDB is also called RDB store. + +- **Predicate** + + A representation of the property or feature of a data entity, or the relationship between data entities. It is mainly used to define operation conditions. + +- **Result set** + + A set of query results used to access the data. You can access the required data in a result set in flexible modes. + +- **SQLite database** + + A lightweight open-source relational database management system that complies with Atomicity, Consistency, Isolation, and Durability \(ACID\). + + +## Working Principles + +The RDB provides a common operation interface for external systems. It uses the SQLite as the underlying persistent storage engine, which supports all SQLite database features. + +**Figure 1** How RDB works +![](figures/how-rdb-works.png "how-rdb-works") + +## Default Settings + +- The default database logging mode is write-ahead logging \(WAL\). +- The default database flush mode is Full mode. +- The default shared memory used by the OpenHarmony database is 2 MB. + +## Constraints + +- A maximum of four connection pools can be connected to an RDB to manage read and write operations. + +- To ensure data accuracy, the RDB supports only one write operation at a time. + diff --git a/en/application-dev/database/figures/en-us_image_0000001199139454.png b/en/application-dev/database/figures/en-us_image_0000001199139454.png new file mode 100644 index 0000000000000000000000000000000000000000..ca52bd43d384c5b2d06fe19623b50e0c66ba6295 GIT binary patch literal 12254 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 + +## When to Use + +The lightweight data store is ideal for storing lightweight and frequently used data, but not for storing a large amount of data or data with frequent changes. The application data is persistently stored on a device in the form of files. Note that the instance accessed by an application contains all data of the file. The data is always loaded to the memory of the device until the application removes it from the memory. The application can perform data operations using the **Storage** APIs. + +## Available APIs + +The lightweight data store provides applications with data processing capability and allows applications to perform lightweight data storage and query. Data is stored in key-value pairs. Keys are of the string type, and values can be of the number, string, or Boolean type. + +**Creating a Storage Instance** + +Create a **Storage** instance for data operations. A **Storage** instance is created after data is read from a specified file and loaded to the instance. + +**Table 1** API for creating a **Storage** instance + + + + + + + + + + + + +

Package Name

+

Method

+

Description

+

ohos.data.storage

+

getStorage(path: string): Promise<Storage>;

+

Obtains the Storage singleton corresponding to a file for data operations.

+
+ +**Writing Data** + +Call the **put\(\)** method to add or modify data in a **Storage** instance. + +**Table 2** API for writing data + + + + + + + + + + + + +

Class

+

Method

+

Description

+

Storage

+

put(key: string, value: ValueType): Promise<void>;

+

Writes data of the number, string, and Boolean types.

+
+ +**Reading Data** + +Call the **get\(\)** method to read data from a **Storage** instance. + +**Table 3** API for reading data + + + + + + + + + + + + +

Class

+

Method

+

Description

+

Storage

+

get(key: string, defValue: ValueType): Promise<ValueType>;

+

Reads data of the number, string, and Boolean types.

+
+ +**Storing Data Persistently** + +Call the **flush\(\)** method to write the cached data back to its text file for persistent storage. + +**Table 4** API for data persistence + + + + + + + + + + + + +

Class

+

Method

+

Description

+

Storage

+

flush(): Promise<void>;

+

Writes data in the Storage instance back to its file through an asynchronous thread.

+
+ +**Observing Data Changes** + +Specify **StorageObserver** as the callback to subscribe to data changes. When the value of the subscribed key is changed and the **flush\(\)** method is executed, **StorageObserver** will be invoked. + +**Table 5** APIs for subscribing to data changes + + + + + + + + + + + + + + + + +

Class

+

Method

+

Description

+

Storage

+

on(type: 'change', callback: Callback<StorageObserver>): void;

+

Subscribes to data changes.

+

Storage

+

off(type: 'change', callback: Callback<StorageObserver>): void;

+

Unsubscribes from data changes.

+
+ +**Deleting Data** + +Use the following APIs to delete a **Storage** instance or data file. + +**Table 6** APIs for deleting data + + + + + + + + + + + + + + + + +

Package Name

+

Method

+

Description

+

ohos.data.storage

+

deleteStorage(path: string): Promise<void>;

+

Deletes a Storage instance from the cache and deletes its file from the device.

+

ohos.data.storage

+

removeStorageFromCache(path: string): Promise<void>;

+

Deletes a Storage instance from the cache to release memory.

+
+ +## How to Develop + +1. Import **@ohos.data.storage** and related modules to the development environment. + + ``` + import dataStorage from '@ohos.data.storage' + import featureAbility from '@ohos.ability.featureAbility' // Used to obtain the file storage path. + ``` + +2. Create a **Storage** instance. + + Read the specified file and load its data to the **Storage** instance for data operations. + + ``` + var context = featureAbility.getContext() + var path = await context.getFilesDir() + let promise = dataStorage.getStorage(path + '/mystore') + ``` + + +1. Write data. + + Use the **put\(\)** method of the **Storage** class to write data to the cached **Storage** instance. + + ``` + promise.then((storage) => { + let getPromise = storage.put('startup', 'auto') // Save data to the Storage instance. + getPromise.then(() => { + console.info("Put the value of startup successfully.") + }).catch((err) => { + console.info("Put the value of startup failed with err: " + err) + }) + }).catch((err) => { + console.info("Get the storage failed") + }) + ``` + + +1. Read data. + + Use the **get\(\)** method of the **Storage** class to read data. + + ``` + promise.then((storage) => { + let getPromise = storage.get('startup', 'default') + getPromise.then((value) => { + console.info("The value of startup is " + value) + }).catch((err) => { + console.info("Get the value of startup failed with err: " + err) + }) + }).catch((err) => { + console.info("Get the storage failed") + }) + ``` + + +1. Store data persistently. + + Use the **flush** or **flushSync** method to flush data in the **Storage** instance to its file. + + ``` + storage.flush(); + ``` + +2. Observe data changes. + + Specify **StorageObserver** as the callback to subscribe to data changes for an application. When the value of the subscribed key is changed and the **flush\(\)** method is executed, **StorageObserver** will be invoked. Unregister the **StorageObserver** when it is no longer required. + + ``` + promise.then((storage) => { + var observer = function (key) { + console.info("The key of " + key + " changed.") + } + storage.on('change', observer) + storage.putSync('startup', 'auto') // Modify data in the Storage instance. + storage.flushSync() // Trigger the StorageObserver callback. + + storage.off(...change..., observer) // Unsubscribe from the data changes. + }).catch((err) => { + console.info("Get the storage failed") + }) + ``` + + +1. Delete the specified file. + + Use the **deleteStorage** method to delete the **Storage** singleton of the specified file from the memory, and delete the specified file, its backup file, and damaged files. After the specified files are deleted, the application cannot use that instance to perform any data operation. Otherwise, data inconsistency will occur. The deleted data and files cannot be restored. + + ``` + let promise = dataStorage.deleteStorage(path + '/mystore') + promise.then(() => { + console.info("Deleted successfully.") + }).catch((err) => { + console.info("Deleted failed with err: " + err) + }) + ``` + + diff --git a/en/application-dev/database/lightweight-data-store-overview.md b/en/application-dev/database/lightweight-data-store-overview.md new file mode 100644 index 0000000000..45639c75e8 --- /dev/null +++ b/en/application-dev/database/lightweight-data-store-overview.md @@ -0,0 +1,31 @@ +# Lightweight Data Store Overview + +Lightweight data store is applicable to access and persistence operations on the data in key-value pairs. When an application accesses a lightweight **Storage** instance, data in the **Storage** instance will be cached in the memory for faster access. The cached data can also be written back to the text file for persistent storage. Since file read and write consume system resources, you are advised to minimize the frequency of reading and writing persistent files. + +## Basic Concepts + +- **Key-Value data structure** + + A type of data structure. The key is the unique identifier for a piece of data, and the value is the specific data being identified. + +- **Non-relational database** + + A database not in compliance with the atomicity, consistency, isolation, and durability \(ACID\) database management properties of relational data transactions. The data in a non-relational database is independent. + + +## Working Principles + +1. When an application loads data from a specified **Storage** file to a **Storage** instance, the system stores the instance in the memory through a static container. Each file of an application or process has only one **Storage** instance in the memory, till the application removes the instance from the memory or deletes the **Storage** file. +2. When obtaining a **Storage** instance, the application can read data from or write data to the instance. The data in the **Storage** instance can be flushed to its **Storage** file by calling the **flush** or **flushSync** method. + +**Figure 1** How lightweight data store works + + +![](figures/en-us_image_0000001199139454.png) + +## Constraints + +- **Storage** instances are loaded to the memory. To minimize non-memory overhead, the number of data records stored in a **Storage** instance cannot exceed 10,000. Delete the instances that are no longer used in a timely manner. +- The key in the key-value pairs is of the string type. It cannot be empty or exceed 80 characters. +- If the value in the key-value pairs is of the string type, it can be empty or contain a maximum of 8192 characters. + diff --git a/en/application-dev/media/figures/playback-status.png b/en/application-dev/media/figures/playback-status.png deleted file mode 100755 index e0777e28838f6d2455233f2068339f8548f50c67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23062 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 | Yes| Yes| Yes| Yes| No| No| -| Context.getOrCreateLocalDir() | Yes| Yes| Yes| Yes| No| No| -| Context.verifyPermission(permission: string, options: PermissionOptions, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| Context.verifyPermission(permission: string, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| Context.verifyPermission(permission: string, options?: PermissionOptions) | Yes| Yes| Yes| Yes| No| No| -| Context.requestPermissionsFromUser(permissions: Array\, requestCode: number, resultCallback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| Context.getApplicationInfo(callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| Context.getApplicationInfo() | Yes| Yes| Yes| Yes| No| No| -| Context.getBundleName(callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| Context.getBundleName() | Yes| Yes| Yes| Yes| No| No| -| Context.getProcessInfo(callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| Context.getProcessInfo() | Yes| Yes| Yes| Yes| No| No| -| Context.getElementName(callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| Context.getElementName() | Yes| Yes| Yes| Yes| No| No| -| Context.getProcessName(callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| Context.getProcessName() | Yes| Yes| Yes| Yes| No| No| -| Context.getCallingBundle(callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| Context.getCallingBundle() | Yes| Yes| Yes| Yes| No| No| - ## Modules to Import ```js diff --git a/en/application-dev/reference/apis/js-apis-commonEvent.md b/en/application-dev/reference/apis/js-apis-commonEvent.md index e3f7238a12..9ef873e163 100644 --- a/en/application-dev/reference/apis/js-apis-commonEvent.md +++ b/en/application-dev/reference/apis/js-apis-commonEvent.md @@ -3,17 +3,6 @@ **Note:** The initial APIs of this module are supported since API version 7. Newly added APIs will be marked with a superscript to indicate their earliest API version. -## Applicable Devices - -| API | Phone| Tablet| Smart TV| Wearable| Lite Wearable| -| ------------------------------------------------------------ | ---- | ---- | ------ | -------- | -------------- | -| CommonEvent.publish(event: string, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| -| CommonEvent.publish(event: string, options: CommonEventPublishData, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| -| CommonEvent.createSubscriber(subscribeInfo: CommonEventSubscribeInfo, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| -| CommonEvent.createSubscriber(subscribeInfo: CommonEventSubscribeInfo) | Yes| Yes| Yes| Yes| No| -| CommonEvent.subscribe(subscriber: CommonEventSubscriber, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| -| CommonEvent.unsubscribe(subscriber: CommonEventSubscriber, callback?: AsyncCallback\) | Yes| Yes| Yes| Yes| No| - ## Required Permissions | Common Event Macro| Common Event Name| Subscriber Permissions| diff --git a/en/application-dev/reference/apis/js-apis-convertxml.md b/en/application-dev/reference/apis/js-apis-convertxml.md new file mode 100644 index 0000000000..7d3d923d94 --- /dev/null +++ b/en/application-dev/reference/apis/js-apis-convertxml.md @@ -0,0 +1,277 @@ +# XML-to-JavaScript Conversion + +>![](public_sys-resources/icon-note.gif) **NOTE:** +>The initial APIs of this module are supported since API version 8. Newly added APIs will be marked with a superscript to indicate their earliest API version. + +## Modules to Import + +``` +import convertxml from '@ohos.convertxml'; +``` + +## Required Permissions + +None + +## ConvertXML + +### convert + +convert\(xml: string, options?: ConvertOptions\) : Object + +Converts an XML text into a JavaScript object. + +- Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

xml

+

string

+

Yes

+

XML text to convert.

+

options

+

ConvertOptions

+

No

+

Settings of the convert operation.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

JavaScript object.

+
+ +- Example + + ``` + var xml = + '' + + '' + + ' Happy' + + ' Work' + + ' Play' + + ''; + var conv = new convertxml.ConvertXML(); + var result1 = conv.convert(xml, {trim: false, ignoreDeclaration: false}); + console.log(result1) + ``` + + +## ConvertOptions + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

trim

+

boolean

+

No

+

Whether to trim the whitespace characters before and after the text. The default value is false.

+

ignoreDeclaration

+

boolean

+

No

+

Whether to ignore the XML declaration. The default value is false.

+

ignoreInstruction

+

boolean

+

No

+

Whether to ignore the XML processing instruction. The default value is false.

+

ignoreAttributes

+

boolean

+

No

+

Whether to print attributes across multiple lines and indent attributes. The default value is false.

+

ignoreComment

+

boolean

+

No

+

Whether to ignore element comments. The default value is false.

+

ignoreCDATA

+

boolean

+

No

+

Whether to ignore the element's CDATA information. The default value is false.

+

ignoreDoctype

+

boolean

+

No

+

Whether to ignore the element's Doctype information. The default value is false.

+

ignoreText

+

boolean

+

No

+

Whether to ignore the element's text information. The default value is false.

+

declarationKey

+

string

+

No

+

Name of the attribute key for declaration in the output object. The default value is _declaration.

+

instructionKey

+

string

+

No

+

Name of the attribute key for instruction in the output object. The default value is _instruction.

+

attributesKey

+

string

+

No

+

Name of the attribute key for attributes in the output object. The default value is _attributes.

+

textKey

+

string

+

No

+

Name of the attribute key for text in the output object. The default value is _text.

+

cdataKey

+

string

+

No

+

Name of the attribute key for CDATA in the output object. The default value is _cdata.

+

doctypeKey

+

string

+

No

+

Name of the attribute key for Doctype in the output object. The default value is _doctype.

+

commentKey

+

string

+

No

+

Name of the attribute key for comment in the output object. The default value is _comment.

+

parentKey

+

string

+

No

+

Name of the attribute key for parent in the output object. The default value is _parent.

+

typeKey

+

string

+

No

+

Name of the attribute key for type in the output object. The default value is _type.

+

nameKey

+

string

+

No

+

Name of the attribute key for name in the output object. The default value is _name.

+

elementsKey

+

string

+

No

+

Name of the attribute key for elements in the output object. The default value is _elements.

+
+ diff --git a/en/application-dev/reference/apis/js-apis-dataAbilityHelper.md b/en/application-dev/reference/apis/js-apis-dataAbilityHelper.md index 39d8c92342..dc09e18685 100644 --- a/en/application-dev/reference/apis/js-apis-dataAbilityHelper.md +++ b/en/application-dev/reference/apis/js-apis-dataAbilityHelper.md @@ -1,33 +1,4 @@ -### DataAbilityHelper Module (JavaScript SDK APIs) - -#### Applicable Devices - -| API | Phone| Tablet| Smart TV| Wearable| Lite Wearable| SmartVision Device| -| ------------------------------------------------------------ | ---- | ---- | ------ | -------- | -------------- | ------------ | -| DataAbilityHelper.openFile(uri: string, mode: string, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.openFile(uri: string, mode: string) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.on(type: 'dataChange', uri: string, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.off(type: 'dataChange', uri: string, callback?: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.getFileTypes(uri: string, mimeTypeFilter: string, callback: AsyncCallback>) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.getFileTypes(uri: string, mimeTypeFilter: string) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.getType(uri: string, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.getType(uri: string) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.normalizeUri(uri: string, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.normalizeUri(uri: string) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.denormalizeUri(uri: string, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.denormalizeUri(uri: string) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.notifyChange(uri: string, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.notifyChange(uri: string) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.insert(uri: string, valuesBucket: rdb.ValuesBucket, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.insert(uri: string, valuesBucket: rdb.ValuesBucket) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.batchInsert(uri: string, valuesBuckets: Array, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.batchInsert(uri: string, valuesBuckets: Array) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.delete(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.delete(uri: string, predicates: dataAbility.DataAbilityPredicates) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.update(uri: string, valuesBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.update(uri: string, valuesBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.query(uri: string, columns: Array\, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| DataAbilityHelper.query(uri: string, columns: Array\, predicates: dataAbility.DataAbilityPredicates) | Yes| Yes| Yes| Yes| No| No| +# DataAbilityHelper Module (JavaScript SDK APIs) #### Modules to Import diff --git a/en/application-dev/reference/apis/js-apis-featureAbility.md b/en/application-dev/reference/apis/js-apis-featureAbility.md index 88279ca859..c07e862c47 100644 --- a/en/application-dev/reference/apis/js-apis-featureAbility.md +++ b/en/application-dev/reference/apis/js-apis-featureAbility.md @@ -1,27 +1,5 @@ # FeatureAbility Module (JavaScript) -#### Applicable Devices - -| API | Phone| Tablet| Smart TV| Wearable| Lite Wearable| SmartVision Device| -| ------------------------------------------------------------ | ---- | ---- | ------ | -------- | -------------- | ------------ | -| FeatureAbility.startAbility(parameter: StartAbilityParameter, callback: AsyncCallback\): void | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.startAbility(parameter: StartAbilityParameter): Promise\ | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.acquireDataAbilityHelper(uri: string): DataAbilityHelper | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.startAbilityForResult(parameter: StartAbilityParameter, callback: AsyncCallback\): void | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.startAbilityForResult(parameter: StartAbilityParameter): Promise\ | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.terminateSelfWithResult(parameter: AbilityResult, callback: AsyncCallback\): void | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.terminateSelfWithResult(parameter: AbilityResult): Promise\ | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.hasWindowFocus(callback: AsyncCallback\): void | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.hasWindowFocus(): Promise\ | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.getWant(callback: AsyncCallback\) | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.getWant(): void | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.getContext(): Context | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.terminateSelf(callback: AsyncCallback\): void | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.terminateSelf(): Promise\ | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.connectAbility(request: Want, options:ConnectOptions): number | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.disconnectAbility(connection: number, callback:AsyncCallback\): void | Yes| Yes| Yes| Yes| No| No| -| FeatureAbility.disconnectAbility(connection: number): Promise\ | Yes| Yes| Yes| Yes| No| No| - #### Constraints APIs of the **FeatureAbility** module can be called only by Page abilities. diff --git a/en/application-dev/reference/apis/js-apis-i18n.md b/en/application-dev/reference/apis/js-apis-i18n.md index 6f684c8c06..0763a15987 100644 --- a/en/application-dev/reference/apis/js-apis-i18n.md +++ b/en/application-dev/reference/apis/js-apis-i18n.md @@ -1,10 +1,10 @@ -# Internationalization \(i18n\) +# Internationalization (i18n) + >![](../../public_sys-resources/icon-note.gif) **NOTE:** >- The initial APIs of this module are supported since API version 7. Newly added APIs will be marked with a superscript to indicate their earliest API version. >- This module contains enhanced i18n APIs, which are not defined in ECMA 402. - ## Modules to Import ``` @@ -21,9 +21,10 @@ getDisplayLanguage\(language: string, locale: string, sentenceCase?: boolean\): Obtains the localized script for the specified language. -- Parameters +- Parameters + - - - - -

Name

Type

@@ -163,6 +164,58 @@ Obtains the localized script for the specified country. ``` +## i18n.isRTL8+ + +isRTL\(locale: string\): boolean + +Checks whether the localized script for the specified language is displayed from right to left. + +- Parameters + + + + + + + + + + + + +

Name

+

Type

+

Description

+

locale

+

string

+

Locale ID.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

The value true indicates that the localized script is displayed from right to left, and value false indicates the opposite.

+
+ +- Example + + ``` + i18n.isRTL("zh-CN");// Since Chinese is not written from right to left, false is returned. + i18n.isRTL("ar-EG");// Since Arabic is written from right to left, true is returned. + ``` + + ## i18n.getSystemLanguage getSystemLanguage\(\): string @@ -253,3 +306,2086 @@ Obtains the system locale. ``` +## i18n.getCalendar8+ + +getCalendar\(locale: string, type? : string\): Calendar + +Obtains a **Calendar** object. + +- Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

locale

+

string

+

Yes

+

Valid locale value, for example, zh-Hans-CN.

+

type

+

string

+

No

+

Valid calendar type. Currently, the valid types are as follows: buddhist, chinese, coptic, ethiopic, hebrew, gregory, indian, islamic_civil, islamic_tbla, islamic_umalqura, japanese, and persian. If this parameter is left unspecified, the default calendar type of the specified locale is used.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

Calendar

+

Calendar object.

+
+ +- Example + + ``` + i18n.getCalendar("zh-Hans", "gregory"); + ``` + + +## Calendar8+ + +### setTime8+ + +setTime\(date: Date\): void + +Sets the date for this **Calendar** object. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

date

+

Date

+

Yes

+

Date to be set for the Calendar object.

+
+ + +- Example + + ``` + var calendar = I18n.getCalendar("en-US", "gregory"); + var date = new Date(2021, 10, 7, 8, 0, 0, 0); + calendar.setTime(date); + ``` + + +### setTime8+ + +setTime\(time: number\): void + +Sets the date and time for this **Calendar** object. The value is represented by the number of milliseconds that have elapsed since the Unix epoch \(00:00:00 UTC on January 1, 1970\). + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

time

+

number

+

Yes

+

Number of milliseconds that have elapsed since the Unix epoch.

+
+ + +- Example + + ``` + var calendar = I18n.getCalendar("en-US", "gregory"); + calendar.setTime(10540800000); + ``` + + +### set8+ + +set\(year: number, month: number, date:number, hour?: number, minute?: number, second?: number\): void + +Sets the year, month, day, hour, minute, and second for this **Calendar** object. + +- Parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

year

+

number

+

Yes

+

Year to set.

+

month

+

number

+

Yes

+

Month to set.

+

date

+

number

+

Yes

+

Day to set.

+

hour

+

number

+

No

+

Hour to set.

+

minute

+

number

+

No

+

Minute to set.

+

second

+

number

+

No

+

Second to set.

+
+ +- Example + + ``` + var calendar = i18n.getCalendar("zh-Hans"); + calendar.setTime(2021, 10, 1, 8, 0, 0); // set time to 2021.10.1 08:00:00 + ``` + + +### setTimeZone8+ + +setTimeZone\(timezone: string\): void + +Sets the time zone of this **Calendar** object. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

timezone

+

string

+

Yes

+

Time zone, for example, Asia/Shanghai.

+
+ +- Example + + ``` + var calendar = i18n.getCalendar("zh-Hans"); + calendar.setTimeZone("Asia/Shanghai"); + ``` + + +### getTimeZone8+ + +getTimeZone\(\): string + +Obtains the time zone of this **Calendar** object. + +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Time zone of the Calendar object.

+
+ +- Example + + ``` + var calendar = i18n.getCalendar("zh-Hans"); + calendar.setTimeZone("Asia/Shanghai"); + calendar.getTimeZone(); // Asia/Shanghai" + ``` + + +### getFirstDayOfWeek8+ + +getFirstDayOfWeek\(\): number + +Obtains the start day of a week for this **Calendar** object. + +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Start day of a week. The value 1 indicates Sunday, and value 7 indicates Saturday.

+
+ + +- Example + + ``` + var calendar = I18n.getCalendar("en-US", "gregory"); + calendar.getFirstDayOfWeek(); + ``` + + +### setFirstDayOfWeek8+ + +setFirstDayOfWeek\(value: number\): void + +Sets the start day of a week for this **Calendar** object. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

value

+

number

+

No

+

Start day of a week. The value 1 indicates Sunday, and value 7 indicates Saturday.

+
+ +- Example + + ``` + var calendar = i18n.getCalendar("zh-Hans"); + calendar.setFirstDayOfWeek(0); + ``` + + +### getMinimalDaysInFirstWeek8+ + +getMinimalDaysInFirstWeek\(\): number + +Obtains the minimum number of days in the first week of a year. + +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Minimum number of days in the first week of a year.

+
+ +- Example + + ``` + var calendar = i18n.getCalendar("zh-Hans"); + calendar.getMinimalDaysInFirstWeek(); + ``` + + +### setMinimalDaysInFirstWeek8+ + +setMinimalDaysInFirstWeek\(value: number\): void + +Sets the minimum number of days in the first week of a year. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

value

+

number

+

No

+

Minimum number of days in the first week of a year.

+
+ +- Example + + ``` + var calendar = i18n.getCalendar("zh-Hans"); + calendar.setMinimalDaysInFirstWeek(3); + ``` + + +### get8+ + +get\(field: string\): number + +Obtains the value of the specified field in the **Calendar** object. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

field

+

string

+

Yes

+

Value of the specified field in the Calendar object. Currently, the valid fields are as follows: era, year, month, week_of_year, week_of_month, date, day_of_year, day_of_week, day_of_week_in_month, hour, hour_of_day, minute, second, millisecond, zone_offset, dst_offset, year_woy, dow_local, extended_year, julian_day, milliseconds_in_day, and is_leap_month.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Value of the specified field. For example, if the year in the internal date of this Calendar object is 1990, the get("year") function will return 1990.

+
+ +- Example + + ``` + var calendar = i18n.getCalendar("zh-Hans"); + calendar.setTime(2021, 10, 1, 8, 0, 0); // set time to 2021.10.1 08:00:00 + calendar.get("hour_of_day"); // 8 + ``` + + +### getDisplayName8+ + +getDisplayName\(locale: string\): string + +Obtains the name of the **Calendar** object displayed for the specified locale. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

locale

+

string

+

Yes

+

Locale for which the name of the Calendar object is displayed. For example, if locale is en-US, the name of the Buddhist calendar will be Buddhist Calendar.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Name of the Calendar object displayed for the specified locale.

+
+ +- Example + + ``` + var calendar = i18n.getCalendar("en-US", "buddhist"); + calendar.getDisplayName("zh"); // Obtain the name of the Buddhist calendar in zh. + ``` + + +### isWeekend8+ + +isWeekend\(date?: Date\): boolean + +Checks whether the specified date in this **Calendar** object is a weekend. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

date

+

Date

+

No

+

Specified date in this Calendar object. If this parameter is left unspecified, the system checks whether the current date in the Calendar object is a weekend.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

The value true indicates that the date is a weekend, and value false indicates a weekday.

+
+ +- Example + + ``` + var calendar = i18n.getCalendar("zh-Hans"); + calendar.setTime(2021, 11, 11, 8, 0, 0); // Set the time to 2021.11.11 08:00:00. + calendar.isWeekend(); // false + var date = new Date(2011, 11, 6, 9, 0, 0); + calendar.isWeekend(date); // true + ``` + + +## PhoneNumberFormat8+ + +### constructor8+ + +constructor\(country: string, options?: PhoneNumberFormatOptions\) + +Creates a **PhoneNumberFormat** object. + +Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

country

+

string

+

Yes

+

Country or region to which the phone number to be formatted belongs.

+

options

+

PhoneNumberFormatOptions

+

No

+

Options of the PhoneNumberFormat object.

+
+ +- Example + + ``` + var phoneNumberFormat= new i18n.PhoneNumberFormat("CN", {"type": "E164"}); + ``` + + +### isValidNumber8+ + +isValidNumber\(number: string\): boolean + +Checks whether the format of the specified phone number is valid. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

number

+

string

+

Yes

+

Phone number to be checked.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

The value true indicates the phone number format is valid, and value false indicates the opposite.

+
+ + +- Example + + ``` + var phonenumberfmt = new i18n.PhoneNumberFormat("CN"); + phonenumberfmt.isValidNumber("15812312312"); + ``` + + +### format8+ + +format\(number: string\): string + +Formats a phone number. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

number

+

string

+

Yes

+

Phone number to be formatted.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Formatted phone number.

+
+ + +- Example + + ``` + var phonenumberfmt = new i18n.PhoneNumberFormat("CN"); + phonenumberfmt.format("15812312312"); + ``` + + +## PhoneNumberFormatOptions8+ + +Defines the options for this **PhoneNumberFormat** object. + + + + + + + + + + + + + + + + +

Name

+

Type

+

Readable

+

Writable

+

Description

+

type

+

string

+

Yes

+

Yes

+

Format type of a phone number. The available options are as follows: E164, INTERNATIONAL, NATIONAL, and RFC3966.

+
+ +## UnitInfo8+ + +Defines the measurement unit information. + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Readable

+

Writable

+

Description

+

unit

+

string

+

Yes

+

Yes

+

Name of the measurement unit, for example, meter, inch, or cup.

+

measureSystem

+

string

+

Yes

+

Yes

+

Measurement system. The value can be SI, US, or UK.

+
+ +## Util8+ + +### unitConvert8+ + +unitConvert\(fromUnit: UnitInfo, toUnit: UnitInfo, value: number, locale: string, style?: string\): string + +Converts one measurement unit into another and formats the unit based on the specified locale and style. + +- Parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

fromUnit

+

UnitInfo

+

Yes

+

Measurement unit to be converted.

+

toUnit

+

UnitInfo

+

Yes

+

Measurement unit to be converted to.

+

value

+

number

+

Yes

+

Value of the measurement unit to be converted.

+

locale

+

string

+

Yes

+

Locale used for formatting, for example, zh-Hans-CN.

+

style

+

string

+

No

+

Style used for formatting. The value can be long, short, or medium.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Character string obtained after formatting based on the measurement unit specified by toUnit.

+
+ + +- Example + + ``` + I18n.Util.unitConvert({unit: "cup", measureSystem: "US"}, {unit: "liter", measureSystem: "SI"}, 1000, "en-US", "long"); + ``` + + +## i18n.getInstance8+ + +getInstance\(locale?: string\): IndexUtil + +Creates an **IndexUtil** object. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

locale

+

string

+

No

+

A string containing locale information, including the language, optional script, and region.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

IndexUtil

+

IndexUtil object mapping to the specified locale.

+
+ + +- Example + + ``` + var indexUtil= i18n.getInstance("zh-CN"); + ``` + + +## IndexUtil8+ + +### getIndexList8+ + +getIndexList\(\): Array + +Obtains the index list for this **locale** object. + +- Return values + + + + + + + + + + +

Type

+

Description

+

Array<string>

+

Index list for this locale.

+
+ + +- Example + + ``` + var indexUtil = i18n.getInstance("zh-CN"); + var indexList = indexUtil.getIndexList(); + ``` + + +### addLocale8+ + +addLocale\(locale: string\) + +Adds the index of the new **locale** object to the index list. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

locale

+

string

+

Yes

+

A string containing locale information, including the language, optional script, and region.

+
+ + +- Example + + ``` + var indexUtil = i18n.getInstance("zh-CN"); + indexUtil.addLocale("en-US"); + ``` + + +### getIndex8+ + +getIndex\(text: string\): string + +Obtains the index of a **text** object. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

text

+

string

+

Yes

+

text object whose index is to be obtained.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Index of the text object.

+
+ + +- Example + + ``` + var indexUtil= i18n.getInstance("zh-CN"); + indexUtil.getIndex("hi"); // Return h. + ``` + + +## Character8+ + +### isDigit8+ + +isDigit\(char: string\): boolean + +Checks whether the input character string is comprised of digits. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

char

+

string

+

Yes

+

Input character.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

The value true indicates that the input character is a digit, and value false indicates the opposite.

+
+ + +- Example + + ``` + var isdigit = Character.isDigit("1"); // Return true. + ``` + + +### isSpaceChar8+ + +isSpaceChar\(char: string\): boolean + +Checks whether the input character is comprised of space. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

char

+

string

+

Yes

+

Input character.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

The value true indicates that the input character is a space, and value false indicates the opposite.

+
+ + +- Example + + ``` + var isspacechar = Character.isSpaceChar("a"); // Return false. + ``` + + +### isWhitespace8+ + +isWhitespace\(char: string\): boolean + +Checks whether the input character is comprised of white space. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

char

+

string

+

Yes

+

Input character.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

The value true indicates that the input character is a white space, and value false indicates the opposite.

+
+ + +- Example + + ``` + var iswhitespace = Character.isWhitespace("a"); // Return false. + ``` + + +### isRTL8+ + +isRTL\(char: string\): boolean + +Checks whether the input character string is of the right to left \(RTL\) language. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

char

+

string

+

Yes

+

Input character.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

The value true indicates that the input character is of the RTL language, and value false indicates the opposite.

+
+ + +- Example + + ``` + var isrtl = Character.isRTL("a"); // Return false. + ``` + + +### isIdeograph8+ + +isIdeograph\(char: string\): boolean + +Checks whether the input character string is comprised of ideographic characters. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

char

+

string

+

Yes

+

Input character.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

The value true indicates that the input character is an ideographic character, and value false indicates the opposite.

+
+ + +- Example + + ``` + var isideograph = Character.isIdeograph("a"); // Return false. + ``` + + +### isLetter8+ + +isLetter\(char: string\): boolean + +Checks whether the input character string is comprised of letters. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

char

+

string

+

Yes

+

Input character.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

The value true indicates that the input character is a letter, and value false indicates the opposite.

+
+ + +- Example + + ``` + var isletter = Character.isLetter("a"); // Return true. + ``` + + +### isLowerCase8+ + +isLowerCase\(char: string\): boolean + +Checks whether the input character is comprised of lowercase letters. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

char

+

string

+

Yes

+

Input character.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

The value true indicates that the input character is a lowercase letter, and value false indicates the opposite.

+
+ + +- Example + + ``` + var islowercase = Character.isLowerCase("a"); // Return true. + ``` + + +### isUpperCase8+ + +isUpperCase\(char: string\): boolean + +Checks whether the input character is comprised of uppercase letters. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

char

+

string

+

Yes

+

Input character.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

The value true indicates that the input character is an uppercase letter, and value false indicates the opposite.

+
+ + +- Example + + ``` + var isuppercase = Character.isUpperCase("a"); // Return false. + ``` + + +### getType8+ + +getType\(char: string\): string + +Obtains the type of the input character string. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

char

+

string

+

Yes

+

Input character.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Type of the input character.

+
+ + +- Example + + ``` + var type = Character.getType("a"); + ``` + + +## i18n.getLineInstance8+ + +getLineInstance\(locale: string\): BreakIterator + +Obtains a [BreakIterator](#section1312302611613) object for text segmentation. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

locale

+

string

+

Yes

+

Valid locale value, for example, zh-Hans-CN. The BreakIterator object segments text according to the rules of the specified locale.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

BreakIterator

+

Break iterator used for text segmentation.

+
+ +- Example + + ``` + i18n.getLineInstance("en"); + ``` + + +## BreakIterator8+ + +### setLineBreakText8+ + +setLineBreakText\(text: string\): void + +Sets the text to be processed by the [BreakIterator](#section1312302611613) object. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

text

+

string

+

Yes

+

Text to be processed by the BreakIterator object.

+
+ + +- Example + + ``` + iterator = I18n.getLineInstance("en"); + iterator.setLineBreakText("Apple is my favorite fruit."); + ``` + + +### getLineBreakText8+ + +getLineBreakText\(\): string + +Obtains the text being processed by the [BreakIterator](#section1312302611613) object. + +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Text being processed by the BreakIterator object.

+
+ + +- Example + + ``` + iterator = I18n.getLineInstance("en"); + iterator.setLineBreakText("Apple is my favorite fruit."); + iterator.getLineBreakText(); // Apple is my favorite fruit. + ``` + + +### current8+ + +current\(\): number + +Obtains the position of the [BreakIterator](#section1312302611613) object in the text being processed. + +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Position of the BreakIterator object in the text being processed.

+
+ + +- Example + + ``` + iterator = I18n.getLineInstance("en"); + iterator.setLineBreakText("Apple is my favorite fruit."); + breakIter.current(); // 0 + ``` + + +### first8+ + +first\(\): number + +Puts the [BreakIterator](#section1312302611613) object to the first text boundary, which is always at the beginning of the processed text. + +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Offset to the first text boundary of the processed text.

+
+ + +- Example + + ``` + iterator = I18n.getLineInstance("en"); + iterator.setLineBreakText("Apple is my favorite fruit."); + breakIter.first(); // 0 + ``` + + +### last8+ + +last\(\): number + +Puts the [BreakIterator](#section1312302611613) object to the last text boundary, which is always the next position after the end of the processed text. + +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Offset of the last text boundary of the processed text.

+
+ + +- Example + + ``` + iterator = I18n.getLineInstance("en"); + iterator.setLineBreakText("Apple is my favorite fruit."); + iterator.last(); // 27 + ``` + + +### next8+ + +next\(index?: number\): number + +Moves the [BreakIterator](#section1312302611613) object backward by the specified number of text boundaries if the specified index is a positive number. If the index is a negative number, the [BreakIterator](#section1312302611613) object will be moved forward by the corresponding number of text boundaries. If no index is specified, the index will be treated as **1**. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

index

+

number

+

No

+

Number of text boundaries by which the BreakIterator object is moved. A positive value indicates that the text boundary is moved backward, and a negative value indicates the opposite. If no index is specified, the index will be treated as 1.

+
+ + +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Position of the BreakIterator object in the text after it is moved by the specified number of text boundaries. The value -1 is returned if the position of the BreakIterator object is outside of the processed text after it is moved by the specified number of text boundaries.

+
+ + +- Example + + ``` + iterator = I18n.getLineInstance("en"); + iterator.setLineBreakText("Apple is my favorite fruit."); + iterator.first(); // 0 + iterator.next(); // 6 + iterator.next(10); // -1 + ``` + + +### previous8+ + +previous\(\): number + +Moves the [BreakIterator](#section1312302611613) object to the previous text boundary. + +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Position of the BreakIterator object in the text after it is moved to the previous text boundary. The value -1 is returned if the position of the BreakIterator object is outside of the processed text after it is moved by the specified number of text boundaries.

+
+ + +- Example + + ``` + iterator = I18n.getLineInstance("en"); + iterator.setLineBreakText("Apple is my favorite fruit."); + iterator.first(); // 0 + iterator.next(3); // 12 + iterator.previous(); // 9 + ``` + + +### following8+ + +following\(offset: number\): number + +Moves the [BreakIterator](#section1312302611613) object to the text boundary after the position specified by the offset. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

offset

+

number

+

Yes

+

Offset to the position before the text boundary to which the BreakIterator object is moved.

+
+ + +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

The value -1 is returned if the text boundary to which the BreakIterator object is moved is outside of the processed text.

+
+ + +- Example + + ``` + iterator = I18n.getLineInstance("en"); + iterator.setLineBreakText("Apple is my favorite fruit."); + iterator.following(0); // 6 + iterator.following(100); // -1 + iterator.current(); // 27 + ``` + + +### isBoundary8+ + +isBoundary\(offset: number\): boolean + +Checks whether the position specified by the offset is a text boundary. If **true** is returned, the [BreakIterator](#section1312302611613) object is moved to the position specified by the offset. If **false** is returned, the [BreakIterator](#section1312302611613) object is moved to the text boundary after the position specified by the offset, which is equivalent to calling [following\(offset\)](#section1743155314301). + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

offset

+

number

+

Yes

+

Position to check.

+
+ + +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

The value true indicates that the position specified by the offset is a text boundary, and value false indicates the opposite.

+
+ + +- Example + + ``` + iterator = I18n.getLineInstance("en"); + iterator.setLineBreakText("Apple is my favorite fruit."); + iterator.isBoundary(0); // true; + iterator.isBoundary(5); // false; + ``` + diff --git a/en/application-dev/reference/apis/js-apis-intl.md b/en/application-dev/reference/apis/js-apis-intl.md index 7d182fd07e..f18b8b8bf3 100644 --- a/en/application-dev/reference/apis/js-apis-intl.md +++ b/en/application-dev/reference/apis/js-apis-intl.md @@ -1,10 +1,9 @@ -# Internationalization \(intl\) +# Internationalization (intl) >![](../../public_sys-resources/icon-note.gif) **NOTE:** >- The initial APIs of this module are supported since API version 7. Newly added APIs will be marked with a superscript to indicate their earliest API version. >- This module contains standard i18n APIs, which are defined in ECMA 402. - ## Modules to Import ``` @@ -17,7 +16,7 @@ None ## Locale -### Attributes +### Attributes - - - - - - - - -

Name

@@ -40,7 +39,7 @@ None

No

Language associated with the locale.

+

Language associated with the locale, for example, zh.

script

@@ -51,7 +50,7 @@ None

No

Script type of the language.

+

Script type of the language, for example, Hans.

region

@@ -62,7 +61,7 @@ None

No

Region associated with the locale.

+

Region associated with the locale, for example, CN.

baseName

@@ -73,7 +72,7 @@ None

No

Basic information about the locale.

+

Basic key information about the locale, which consists of the language, script, and region, for example, zh-Hans-CN.

caseFirst

@@ -84,7 +83,7 @@ None

No

Whether case is taken into account for the locale's collation rules.

+

Whether case is taken into account for the locale's collation rules. The value can be upper, lower, or false.

calendar

@@ -95,7 +94,7 @@ None

No

Calendar for the locale.

+

Calendar for the locale. The value can be buddhist, chinese, coptic, dangi, ethioaa, ethiopic, gregory, hebrew, indian, islamic, islamic-umalqura, islamic-tbla, islamic-civil, islamic-rgsa, iso8601, japanese, persian, roc, or islamicc.

collation

@@ -106,7 +105,7 @@ None

No

Collation rules for the locale.

+

Collation rules for the locale. The value can be any of the following: big5han, compat, dict, direct, ducet, eor, gb2312, phonebk, phonetic, pinyin, reformed, searchjl, stroke, trad, unihan, and zhuyin.

hourCycle

@@ -117,7 +116,7 @@ None

No

Time system for the locale.

+

Time system for the locale. The value can be h11, h12, h23, or h24.

numberingSystem

@@ -128,7 +127,7 @@ None

No

Numbering system for the locale.

+

Numbering system for the locale. The value can be any of the following: adlm, ahom, arab, arabext, bali, beng, bhks, brah, cakm, cham, deva, diak, fullwide, gong, gonm, gujr, guru, hanidec, hmng, hmnp, java, kali, khmr, knda, lana, lanatham, laoo, latn, lepc, limb, mathbold, mathdbl, mathmono, mathsanb, mathsans, mlym, modi, mong, mroo, mtei, mymr, mymrshan, mymrtlng, newa, nkoo, olck, orya, osma, rohg, saur, segment, shrd, sind, sinh, sora, sund, takr, talu, tamldec, telu, thai, tibt, tirh, vaii, wara, and wcho.

numeric

@@ -145,9 +144,9 @@ None
-### constructor +### constructor -constructor\(locale: string, options?:options\) +constructor\(locale: string, options?: options\) Creates a **Locale** object. @@ -173,15 +172,6 @@ Creates a **Locale** object.

A string containing locale information, including the language, optional script, and locale.

options

-

options

-

No

-

Options for creating the Locale object.

-
@@ -193,7 +183,7 @@ Creates a **Locale** object. ``` -### toString +### toString toString\(\): string @@ -225,7 +215,7 @@ Converts locale information to a string. ``` -### maximize +### maximize maximize\(\): Locale @@ -240,7 +230,7 @@ Maximizes information of the **Locale** object. If the script and locale infor -

Locale

+

Locale

Locale object with the maximized information.

@@ -257,7 +247,7 @@ Maximizes information of the **Locale** object. If the script and locale infor ``` -### minimize +### minimize minimize\(\): Locale @@ -272,7 +262,7 @@ Minimizes information of the **Locale** object. If the script and locale infor -

Locale

+

Locale

Locale object with the minimized information.

@@ -291,9 +281,9 @@ Minimizes information of the **Locale** object. If the script and locale infor ## DateTimeFormat -### constructor +### constructor -constructor\(locale: string, options?:DateTimeOptions\) +constructor\(locale: string, options?: DateTimeOptions\) Creates a **DateTimeOptions** object for the specified locale. @@ -321,11 +311,11 @@ Creates a **DateTimeOptions** object for the specified locale.

options

-

DateTimeOptions

+

DateTimeOptions

No

-

Options of the DateTimeFormat object.

+

Options for creating a DateTimeFormat object.

@@ -339,9 +329,9 @@ Creates a **DateTimeOptions** object for the specified locale. ``` -### constructor +### constructor -constructor\(locales: Array, options?:DateTimeOptions\) +constructor\(locales: Array, options?: DateTimeOptions\) Creates a **DateTimeOptions** object for the specified array of locales. @@ -369,11 +359,11 @@ Creates a **DateTimeOptions** object for the specified array of locales.

options

-

DateTimeOptions

+

DateTimeOptions

No

-

Options of the DateTimeFormat object.

+

Options for creating a DateTimeFormat object.

@@ -387,9 +377,9 @@ Creates a **DateTimeOptions** object for the specified array of locales. ``` -### format +### format -format\(date: Date\): string; +format\(date: Date\): string Formats the specified date and time. @@ -445,9 +435,9 @@ Formats the specified date and time. ``` -### formatRange +### formatRange -formatRange\(fromDate: Date, toDate: Date\): string; +formatRange\(fromDate: Date, toDate: Date\): string Formats the specified date range. @@ -513,11 +503,11 @@ Formats the specified date range. ``` -### resolvedOptions +### resolvedOptions resolvedOptions\(\): DateTimeOptions -Obtains the options of the **DateTimeFormat** object. +Obtains the formatting options for **DateTimeFormat** object. - Return values @@ -528,9 +518,9 @@ Obtains the options of the **DateTimeFormat** object. -

DateTimeOptions

+

DateTimeOptions

-

Options of the DateTimeFormat object.

+

Formatting options for DateTimeFormat objects.

@@ -545,193 +535,7 @@ Obtains the options of the **DateTimeFormat** object. ``` -## NumberFormat - -### constructor - -constructor\(locale: string, options?:NumberOptions\) - -Creates a **NumberFormat** object for the specified locale. - -Parameters - - - - - - - - - - - - - - - - - - - -

Name

-

Type

-

Mandatory

-

Description

-

locale

-

string

-

Yes

-

A string containing locale information, including the language, optional script, and locale.

-

options

-

NumberOptions

-

No

-

Options of the NumberFormat object.

-
- -- Example - - ``` - var numfmt = new Intl.NumberFormat("en-GB", {style:'decimal', notation:"scientific"}); - ``` - - -### constructor - -constructor\(locales: Array, options?:NumberOptions\) - -Creates a **NumberFormat** object for the specified array of locales. - -- Parameters - - - - - - - - - - - - - - - - - - - -

Name

-

Type

-

Mandatory

-

Description

-

locales

-

Array<string>

-

Yes

-

An array of strings containing locale information.

-

options

-

NumberOptions

-

No

-

Options of the NumberFormat object.

-
- - -- Example - - ``` - var numfmt = new Intl.NumberFormat(["en-GB", "zh"], {style:'decimal', notation:"scientific"}); - ``` - - -### format - -format\(number: number\): string; - -Formats a number. - -- Parameters - - - - - - - - - - - - - - -

Name

-

Type

-

Mandatory

-

Description

-

number

-

number

-

Yes

-

Number to be formatted.

-
- -- Return values - - - - - - - - - - -

Type

-

Description

-

string

-

Formatted number.

-
- - -- Example - - ``` - var numfmt = new Intl.NumberFormat(["en-GB", "zh"], {style:'decimal', notation:"scientific"}); - numfmt.format(1223); - ``` - - -### resolvedOptions - -resolvedOptions\(\): NumberOptions - -Obtains the options of the **NumberFormat** object. - -- Return values - - - - - - - - - - -

Type

-

Description

-

NumberOptions

-

Options of the NumberFormat object.

-
- - -- Example - - ``` - var numfmt = new Intl.NumberFormat(["en-GB", "zh"], {style:'decimal', notation:"scientific"}); - numfmt.resolvedOptions(); - ``` - - -## DateTimeOptions +## DateTimeOptions Provides the options for the **DateTimeFormat** object. @@ -756,7 +560,7 @@ Provides the options for the **DateTimeFormat** object.

No

-

Locale information.

+

Locale, for example, zh-Hans-CN.

dateStyle

@@ -789,7 +593,7 @@ Provides the options for the **DateTimeFormat** object.

Yes

-

Hour cycle. The value can be h11, h12, h23, or h24.

+

Time system for the locale. The value can be h11, h12, h23, or h24.

timeZone

@@ -811,7 +615,7 @@ Provides the options for the **DateTimeFormat** object.

Yes

-

Numbering system.

+

Numbering system for the locale. The value can be any of the following: adlm, ahom, arab, arabext, bali, beng, bhks, brah, cakm, cham, deva, diak, fullwide, gong, gonm, gujr, guru, hanidec, hmng, hmnp, java, kali, khmr, knda, lana, lanatham, laoo, latn, lepc, limb, mathbold, mathdbl, mathmono, mathsanb, mathsans, mlym, modi, mong, mroo, mtei, mymr, mymrshan, mymrtlng, newa, nkoo, olck, orya, osma, rohg, saur, segment, shrd, sind, sinh, sora, sund, takr, talu, tamldec, telu, thai, tibt, tirh, vaii, wara, and wcho.

hour12

@@ -960,94 +764,291 @@ Provides the options for the **DateTimeFormat** object. -## NumberOptions +## NumberFormat -Provides the device capability. +### constructor - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + +

Name

-

Parameter Type

-

Readable

-

Writable

-

Description

-

locale

-

string

-

Yes

-

No

-

Locale information.

-

currency

-

string

-

Yes

-

Yes

-

Currency for the specified locale.

-

currencySign

-

string

-

Yes

-

Yes

-

Currency symbol.

-

currencyDisplay

-

string

-

Yes

-

Yes

-

Currency display mode. The value can be symbol, narrowSymbol, code, or name.

-

unit

-

string

-

Yes

-

Yes

-

Currency unit.

-

unitDisplay

-

string

-

Yes

-

Yes

-

Currency unit display format. The value can be long, short, or medium.

-

signDisplay

-

string

-

Yes

+constructor\(locale: string, options?: NumberOptions\) + +Creates a **NumberFormat** object for the specified locale. + +- Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

locale

+

string

+

Yes

+

A string containing locale information, including the language, optional script, and locale.

+

options

+

NumberOptions

+

No

+

Options for creating a NumberFormat object.

+
+ +- Example + + ``` + var numfmt = new Intl.NumberFormat("en-GB", {style:'decimal', notation:"scientific"}); + ``` + + +### constructor + +constructor\(locales: Array, options?: NumberOptions\) + +Creates a **NumberFormat** object for the specified array of locales. + +- Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

locales

+

Array<string>

+

Yes

+

An array of strings containing locale information.

+

options

+

NumberOptions

+

No

+

Options for creating a NumberFormat object.

+
+ + +- Example + + ``` + var numfmt = new Intl.NumberFormat(["en-GB", "zh"], {style:'decimal', notation:"scientific"}); + ``` + + +### format + +format\(number: number\): string; + +Formats a number. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

number

+

number

+

Yes

+

Number to be formatted.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Formatted number.

+
+ + +- Example + + ``` + var numfmt = new Intl.NumberFormat(["en-GB", "zh"], {style:'decimal', notation:"scientific"}); + numfmt.format(1223); + ``` + + +### resolvedOptions + +resolvedOptions\(\): NumberOptions + +Obtains the options of the **NumberFormat** object. + +- Return values + + + + + + + + + + +

Type

+

Description

+

NumberOptions

+

Options of the NumberFormat object.

+
+ + +- Example + + ``` + var numfmt = new Intl.NumberFormat(["en-GB", "zh"], {style:'decimal', notation:"scientific"}); + numfmt.resolvedOptions(); + ``` + + +## NumberOptions + +Provides the device capability. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1106,7 +1107,7 @@ Provides the device capability. - - - - - - -

Name

+

Parameter Type

+

Readable

+

Writable

+

Description

+

locale

+

string

+

Yes

+

No

+

Locale, for example, zh-Hans-CN.

+

currency

+

string

+

Yes

+

Yes

+

Currency unit, for example, EUR, CNY, or USD.

+

currencySign

+

string

+

Yes

+

Yes

+

Currency unit symbol. The value can be symbol, narrowSymbol, code, or name.

+

currencyDisplay

+

string

+

Yes

+

Yes

+

Currency display mode. The value can be symbol, narrowSymbol, code, or name.

+

unit

+

string

+

Yes

+

Yes

+

Unit name, for example, meter, inch, or hectare.

+

unitDisplay

+

string

+

Yes

+

Yes

+

Unit display format. The value can be long, short, or medium.

+

unitUsage

+

string

+

Yes

+

Yes

+

Unit use case. The value can be any of the following: default, area-land-agricult, area-land-commercl, area-land-residntl, length-person, length-person-small, length-rainfall, length-road, length-road-small, length-snowfall, length-vehicle, length-visiblty, length-visiblty-small, length-person-informal, length-person-small-informal, length-road-informal, speed-road-travel, speed-wind, temperature-person, temperature-weather, and volume-vehicle-fuel.

+

signDisplay

+

string

+

Yes

Yes

Yes

Numbering system.

+

Numbering system for the locale. The value can be any of the following: adlm, ahom, arab, arabext, bali, beng, bhks, brah, cakm, cham, deva, diak, fullwide, gong, gonm, gujr, guru, hanidec, hmng, hmnp, java, kali, khmr, knda, lana, lanatham, laoo, latn, lepc, limb, mathbold, mathdbl, mathmono, mathsanb, mathsans, mlym, modi, mong, mroo, mtei, mymr, mymrshan, mymrtlng, newa, nkoo, olck, orya, osma, rohg, saur, segment, shrd, sind, sinh, sora, sund, takr, talu, tamldec, telu, thai, tibt, tirh, vaii, wara, and wcho.

useGrouping

@@ -1117,7 +1118,7 @@ Provides the device capability.

Yes

Whether to enable grouping for display.

+

Whether to use grouping for display.

miniumumIntegerDigits

@@ -1128,7 +1129,7 @@ Provides the device capability.

Yes

Minimum number of integer digits.

+

Minimum number of digits allowed in the integer part of a number. The value ranges from 1 to 21.

miniumumFractionDigits

@@ -1139,7 +1140,7 @@ Provides the device capability.

Yes

Minimum number of fraction digits.

+

Minimum number of digits in the fraction part of a number. The value ranges from 0 to 20.

maxiumumFractionDigits

@@ -1150,7 +1151,7 @@ Provides the device capability.

Yes

Maximum number of fraction digits.

+

Maximum number of digits in the fraction part of a number. The value ranges from 1 to 21.

miniumumSignificantDigits

@@ -1161,7 +1162,7 @@ Provides the device capability.

Yes

Minimum number of significant digits.

+

Minimum number of the least significant digits. The value ranges from 1 to 21.

maxiumumSignificantDigits

@@ -1172,9 +1173,824 @@ Provides the device capability.

Yes

Maximum number of significant digits.

+

Maximum number of the least significant digits. The value ranges from 1 to 21.

+## Collator8+ + +### constructor8+ + +constructor\(\) + +Creates a **Collator** object. + +- Example + + ``` + var collator = new Intl.Collator(); + ``` + + +### constructor8+ + +constructor\(locale: string | Array, options?: CollatorOptions\) + +Creates a **Collator** object based on the specified locale and options. + +Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

locale

+

string|Array<string>

+

Yes

+

A string containing locale information, including the language, optional script, and locale.

+

options

+

CollatorOptions

+

No

+

Options for creating a Collator object.

+
+ +- Example + + ``` + var collator = new Intl.Collator("zh-CN", {"localeMatcher": "lookup", "usage": "sort"}); + ``` + + +### compare8+ + +compare\(first: string, second: string\): number + +Compares two strings based on the sorting policy of the **Collator**. + +- Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

first

+

string

+

Yes

+

First string to compare.

+

second

+

string

+

Yes

+

Second string to compare.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Comparison result. If the value is a negative number, the first string is before the second string. If the value of number is 0, the first string is equal to the second string. If the value of number is a positive number, the first string is after the second string.

+
+ + +- Example + + ``` + var collator = new intl.Collator("zh-Hans"); + collator.compare("first", "second"); + ``` + + +### resolvedOptions8+ + +resolvedOptions\(\): CollatorOptions + +Returns properties reflecting the locale and collation options of a **Collator** object. + +- Return values + + + + + + + + + + +

Type

+

Description

+

CollatorOptions

+

Properties of the Collator object.

+
+ + +- Example + + ``` + var collator = new intl.Collator("zh-Hans"); + var options = collator.resolvedOptions(); + ``` + + +## CollatorOptions8+ + +Represents the properties of a **Collator** object. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Parameter Type

+

Readable

+

Writable

+

Description

+

localeMatcher

+

string

+

Yes

+

Yes

+

Locale matching algorithm. The value can be lookup or best fit.

+

usage

+

string

+

Yes

+

Yes

+

Whether the comparison is for sorting or for searching. The value can be sort or search.

+

sensitivity

+

string

+

Yes

+

Yes

+

Differences in the strings that lead to non-zero return values. The value can be base, accent, case, or variant.

+

ignorePunctuation

+

boolean

+

Yes

+

Yes

+

Whether punctuation is ignored. The value can be true or false.

+

collation

+

string

+

Yes

+

Yes

+

Sorting policy. The value can be any of the following: big5han, compat, dict, direct, ducet, eor, gb2312, phonebk, phonetic, pinyin, reformed, searchjl, stroke, trad, unihan, and zhuyin.

+

numeric

+

boolean

+

Yes

+

Yes

+

Whether numeric collation is used. The value can be true or false.

+

caseFirst

+

string

+

Yes

+

Yes

+

Whether upper case or lower case is sorted first. The value can be upper, lower, or false.

+
+ +## PluralRules8+ + +### constructor8+ + +constructor\(\) + +Create a **PluralRules** object. + +- Example + + ``` + var pluralRules = new Intl.PluralRules(); + ``` + + +### constructor8+ + +constructor\(locale: string | Array, options?: PluralRulesOptions\) + +Creates a **PluralRules** object based on the specified locale and options. + +Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

locale

+

string|Array<string>

+

Yes

+

A string containing locale information, including the language, optional script, and locale.

+

options

+

PluralRulesOptions

+

No

+

Options for creating a PluralRules object.

+
+ +- Example + + ``` + var pluralRules= new Intl.PluraRules("zh-CN", {"localeMatcher": "lookup", "type": "cardinal"}); + ``` + + +### select8+ + +select\(n: number\): string + +Obtains a string that represents the singular-plural type of the specified number. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

n

+

number

+

Yes

+

Number for which the singular-plural type is to be obtained.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Singular-plural type. The options are as follows: zero, one, two, few, many, and others.

+
+ + +- Example + + ``` + var pluralRules = new intl.PluralRules("zh-Hans"); + pluralRules.select(1); + ``` + + +## PluralRulesOptions8+ + +Represents the properties of a **PluralRules** object. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Parameter Type

+

Readable

+

Writable

+

Description

+

localeMatcher

+

string

+

Yes

+

Yes

+

Locale matching algorithm. The value can be lookup or best fit.

+

type

+

string

+

Yes

+

Yes

+

Sorting type. The value can be cardinal or ordinal.

+

minimumIntegerDigits

+

number

+

Yes

+

Yes

+

Minimum number of digits allowed in the integer part of a number. The value ranges from 1 to 21.

+

minimumFractionDigits

+

number

+

Yes

+

Yes

+

Minimum number of digits in the fraction part of a number. The value ranges from 0 to 20.

+

maximumFractionDigits

+

number

+

Yes

+

Yes

+

Maximum number of digits in the fraction part of a number. The value ranges from 1 to 21.

+

minimumSignificantDigits

+

number

+

Yes

+

Yes

+

Minimum number of the least significant digits. The value ranges from 1 to 21.

+

maximumSignificantDigits

+

number

+

Yes

+

Yes

+

Maximum number of the least significant digits. The value ranges from 1 to 21.

+
+ +## RelativeTimeFormat8+ + +### constructor8+ + +constructor\(\) + +Creates a **RelativeTimeFormat** object. + +- Example + + ``` + var relativetimefmt = new Intl.RelativeTimeFormat(); + ``` + + +### constructor8+ + +constructor\(locale: string | Array, options?: RelativeTimeFormatInputOptions\) + +Creates a **RelativeTimeFormat** object based on the specified locale and options. + +Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

locale

+

string|Array<string>

+

Yes

+

A string containing locale information, including the language, optional script, and locale.

+

options

+

RelativeTimeFormatInputOptions

+

No

+

Options for creating a RelativeTimeFormat object.

+
+ +- Example + + ``` + var relativeTimeFormat = new Intl.RelativeTimeFormat("zh-CN", {"localeMatcher": "lookup", "numeric": "always", "style": "long"}); + ``` + + +### format8+ + +format\(value: numeric, unit: string\): string + +Formats the value and unit based on the specified locale and formatting options. + +- Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

value

+

numeric

+

Yes

+

Value to format.

+

unit

+

string

+

Yes

+

Unit to format. The value can be year, quarter, month, week, day, hour, minute, or second.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Relative time after formatting.

+
+ + +- Example + + ``` + var relativetimefmt = new Intl.RelativeTimeFormat("zh-CN"); + relativetimefmt.format(3, "quarter") + ``` + + +### formatToParts8+ + +formatToParts\(value: numeric, unit: string\): Array + +Returns an array of **RelativeTimeFormat** objects in parts for locale-aware formatting. + +- Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

value

+

numeric

+

Yes

+

Value to format.

+

unit

+

string

+

Yes

+

Unit to format. The value can be year, quarter, month, week, day, hour, minute, or second.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

Array<Object>

+

An array of RelativeTimeFormat objects in parts.

+
+ + +- Example + + ``` + var relativetimefmt = new Intl.RelativeTimeFormat("en", {"numeric": "auto"}); + var parts = relativetimefmt.format(10, "seconds"); + ``` + + +### resolvedOptions8+ + +resolvedOptions\(\): RelativeTimeFormatResolvedOptions + +Obtains the formatting options for **RelativeTimeFormat** objects. + +- Return values + + + + + + + + + + +

Type

+

Description

+

RelativeTimeFormatResolvedOptions

+

Formatting options for RelativeTimeFormat objects.

+
+ + +- Example + + ``` + var relativetimefmt= new Intl.RelativeTimeFormat("en-GB"); + relativetimefmt.resolvedOptions(); + ``` + + +## RelativeTimeFormatInputOptions8+ + +Represents the properties of a **RelativeTimeFormat** object. + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Parameter Type

+

Readable

+

Writable

+

Description

+

localeMatcher

+

string

+

Yes

+

Yes

+

Locale matching algorithm. The value can be lookup or best fit.

+

numeric

+

string

+

Yes

+

Yes

+

Format of the output message. The value can be always or auto.

+

style

+

string

+

Yes

+

Yes

+

Length of the internationalized message. The value can be long, short, or narrow.

+
+ +## RelativeTimeFormatResolvedOptions8+ + +Represents the properties of a **RelativeTimeFormat** object. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Parameter Type

+

Readable

+

Writable

+

Description

+

locale

+

string

+

Yes

+

Yes

+

A string containing locale information, including the language, optional script, and locale.

+

numeric

+

string

+

Yes

+

Yes

+

Format of the output message. The value can be always or auto.

+

style

+

string

+

Yes

+

Yes

+

Length of the internationalized message. The value can be long, short, or narrow.

+

numberingSystem

+

string

+

Yes

+

Yes

+

Numbering system.

+
diff --git a/en/application-dev/reference/apis/js-apis-notification.md b/en/application-dev/reference/apis/js-apis-notification.md index 1e4bbafcd5..1105fa9acb 100644 --- a/en/application-dev/reference/apis/js-apis-notification.md +++ b/en/application-dev/reference/apis/js-apis-notification.md @@ -1,88 +1,5 @@ # Notification Module -## Applicable Devices - -| API | Phone | Tablet | Smart TV | Wearable | -| ------------------------------------------------------------ | ---- | ---- | ------ | -------- | -| Notification.publish(request: NotificationRequest, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.publish(request: NotificationRequest) | Yes | Yes | Yes | Yes | -| Notification.cancel(id: number, label: string, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.cancel(id:number, label?:string) | Yes | Yes | Yes | Yes | -| Notification.cancel(id: number, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.cancelAll(callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.cancelAll() | Yes | Yes | Yes | Yes | -| Notification.addSlot(slot: NotificationSlot, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.addSlot(slot: NotificationSlot) | Yes | Yes | Yes | Yes | -| Notification.addSlot(type: SlotType, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.addSlot(type: SlotType) | Yes | Yes | Yes | Yes | -| Notification.addSlots(slots: Array\, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.addSlots(slots: Array\) | Yes | Yes | Yes | Yes | -| Notification.getSlot(slotType: SlotType, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.getSlot(slotType: SlotType) | Yes | Yes | Yes | Yes | -| Notification.getSlots(callback: AsyncCallback>) | Yes | Yes | Yes | Yes | -| Notification.getSlots() | Yes | Yes | Yes | Yes | -| Notification.removeSlot(slotType: SlotType, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.removeSlot(slotType: SlotType) | Yes | Yes | Yes | Yes | -| Notification.removeAllSlots(callback: AsyncCallback\): void | Yes | Yes | Yes | Yes | -| Notification.removeAllSlots(): Promise\ | Yes | Yes | Yes | Yes | -| Notification.subscribe(subscriber: NotificationSubscriber, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.subscribe(subscriber: NotificationSubscriber, info: NotificationSubscribeInfo, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.subscribe(subscriber: NotificationSubscriber, info?: NotificationSubscribeInfo) | Yes | Yes | Yes | Yes | -| Notification.unsubscribe(subscriber: NotificationSubscriber, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.unsubscribe(subscriber: NotificationSubscriber) | Yes | Yes | Yes | Yes | -| Notification.enableNotification(bundle: BundleOption, enable: boolean, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.enableNotification(bundle: BundleOption, enable: boolean) | Yes | Yes | Yes | Yes | -| Notification.isNotificationEnabled(bundle: BundleOption, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.isNotificationEnabled(bundle: BundleOption) | Yes | Yes | Yes | Yes | -| Notification.isNotificationEnabled(callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.isNotificationEnabled() | Yes | Yes | Yes | Yes | -| Notification.displayBadge(bundle: BundleOption, enable: boolean, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.displayBadge(bundle: BundleOption, enable: boolean) | Yes | Yes | Yes | Yes | -| Notification.isBadgeDisplayed(bundle: BundleOption, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.isBadgeDisplayed(bundle: BundleOption) | Yes | Yes | Yes | Yes | -| Notification.setSlotByBundle(bundle: BundleOption, slot: NotificationSlot, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.setSlotByBundle(bundle: BundleOption, slot: NotificationSlot) | Yes | Yes | Yes | Yes | -| Notification.getSlotsByBundle(bundle: BundleOption, callback: AsyncCallback>) | Yes | Yes | Yes | Yes | -| Notification.getSlotsByBundle(bundle: BundleOption) | Yes | Yes | Yes | Yes | -| Notification.getSlotNumByBundle(bundle: BundleOption, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.getSlotNumByBundle(bundle: BundleOption) | Yes | Yes | Yes | Yes | -| Notification.remove(bundle: BundleOption, notificationKey: NotificationKey, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.remove(bundle: BundleOption, notificationKey: NotificationKey) | Yes | Yes | Yes | Yes | -| Notification.remove(hashCode: string, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.remove(hashCode: string) | Yes | Yes | Yes | Yes | -| Notification.removeAll(bundle: BundleOption, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.removeAll(callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.removeAll(bundle?: BundleOption) | Yes | Yes | Yes | Yes | -| Notification.getAllActiveNotifications(callback: AsyncCallback>) | Yes | Yes | Yes | Yes | -| Notification.getAllActiveNotifications() | Yes | Yes | Yes | Yes | -| Notification.getActiveNotificationCount(callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.getActiveNotificationCount() | Yes | Yes | Yes | Yes | -| Notification.getActiveNotifications(callback: AsyncCallback>) | Yes | Yes | Yes | Yes | -| Notification.getActiveNotifications() | Yes | Yes | Yes | Yes | -| Notification.cancelGroup(groupName: string, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.cancelGroup(groupName: string) | Yes | Yes | Yes | Yes | -| Notification.removeGroupByBundle(bundle: BundleOption, groupName: string, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.removeGroupByBundle(bundle: BundleOption, groupName: string) | Yes | Yes | Yes | Yes | -| Notification.setDoNotDisturbDate(date: DoNotDisturbDate, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.setDoNotDisturbDate(date: DoNotDisturbDate) | Yes | Yes | Yes | Yes | -| Notification.getDoNotDisturbDate(callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.getDoNotDisturbDate() | Yes | Yes | Yes | Yes | -| Notification.supportDoNotDisturbMode(callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| Notification.supportDoNotDisturbMode() | Yes | Yes | Yes | Yes | -| WantAgent.getWantAgent(info: WantAgentInfo, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| WantAgent.getWantAgent(info: WantAgentInfo): Promise\ | Yes | Yes | Yes | Yes | -| WantAgent.getBundleName(agent: WantAgent, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| WantAgent.getBundleName(agent: WantAgent): Promise\ | Yes | Yes | Yes | Yes | -| WantAgent.getUid(agent: WantAgent, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| WantAgent.getUid(agent: WantAgent): Promise\ | Yes | Yes | Yes | Yes | -| WantAgent.getWant(agent: WantAgent, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| WantAgent.getWant(agent: WantAgent): Promise\ | Yes | Yes | Yes | Yes | -| WantAgent.cancel(agent: WantAgent, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| WantAgent.cancel(agent: WantAgent): Promise\ | Yes | Yes | Yes | Yes | -| WantAgent.trigger(agent: WantAgent, triggerInfo: TriggerInfo, callback?: Callback\) | Yes | Yes | Yes | Yes | -| WantAgent.equal(agent: WantAgent, otherAgent: WantAgent, callback: AsyncCallback\) | Yes | Yes | Yes | Yes | -| WantAgent.equal(agent: WantAgent, otherAgent: WantAgent): Promise\ | Yes | Yes | Yes | Yes | - ## Required Permissions diff --git a/en/application-dev/reference/apis/js-apis-particleAbility.md b/en/application-dev/reference/apis/js-apis-particleAbility.md index 128d8282ba..9d4a14ccbe 100644 --- a/en/application-dev/reference/apis/js-apis-particleAbility.md +++ b/en/application-dev/reference/apis/js-apis-particleAbility.md @@ -1,18 +1,5 @@ # ParticleAbility Module -## Applicable Devices - -| API | Phone| Tablet| Smart TV| Wearable| Lite Wearable| SmartVision Device| -| ------------------------------------------------------------ | ---- | ---- | ------ | -------- | -------------- | ------------ | -| particleAbility.startAbility(parameter: StartAbilityParameter, callback: AsyncCallback\: void | Yes| Yes| Yes| Yes| No| No| -| particleAbility.startAbility(parameter: StartAbilityParameter): Promise\ | Yes| Yes| Yes| Yes| No| No| -| particleAbility.terminateSelf(callback: AsyncCallback\): void | Yes| Yes| Yes| Yes| No| No| -| particleAbility.terminateSelf(): Promise\ | Yes| Yes| Yes| Yes| No| No| -| particleAbility.acquireDataAbilityHelper(uri: string): DataAbilityHelper | Yes| Yes| Yes| Yes| No| No| -| particleAbility.connectAbility(request: Want, options:ConnectOptions): number | Yes| Yes| Yes| Yes| No| No| -| particleAbility.disconnectAbility(connection: number, callback:AsyncCallback\): void | Yes| Yes| Yes| Yes| No| No| -| particleAbility.disconnectAbility(connection: number): Promise\ | Yes| Yes| Yes| Yes| No| No| - ## Constraints The ParticleAbility module is used to perform operations on abilities of the Data and Service types. diff --git a/en/application-dev/reference/apis/js-apis-process.md b/en/application-dev/reference/apis/js-apis-process.md index 34fc52c050..3d828c219c 100644 --- a/en/application-dev/reference/apis/js-apis-process.md +++ b/en/application-dev/reference/apis/js-apis-process.md @@ -1,4 +1,4 @@ -# Obtaining Process Information +# Obtaining Process Information >![](../../public_sys-resources/icon-note.gif) **NOTE:** >The initial APIs of this module are supported since API version 7. Newly added APIs will be marked with a superscript to indicate their earliest API version. @@ -80,7 +80,7 @@ None

No

An array with supplementary group IDs.

+

Array with supplementary group IDs.

pid

@@ -105,12 +105,23 @@ None

Parent process ID (PPID) of a process.

tid8+

+

number

+

Yes

+

No

+

Thread ID (TID) of a process.

+
## ChildProcess -Allows a process to obtain the standard input and output of its child processes, send signals, and close its child processes. +Provides methods for a process to obtain the standard input and output of its child processes, send signals, and close its child processes. ### Attributes @@ -200,7 +211,6 @@ Waits until the child process ends. This method uses a promise to return the exi - Example ``` - import process from '@ohos.process'; var child = process.runCmd('ls'); var result = child.wait(); result.then(val=>{ @@ -235,7 +245,6 @@ Obtains the standard output of the child process. - Example ``` - import process from '@ohos.process'; var child = process.runCmd('ls'); var result = child.wait(); child.getOutput.then(val=>{ @@ -270,7 +279,6 @@ Obtains the standard error output of the child process. - Example ``` - import process from '@ohos.process'; var child = process.runCmd('madir test.text'); var result = child.wait(); child.getErrorOutput.then(val=>{ @@ -288,7 +296,6 @@ Closes the child process in running. - Example ``` - import process from '@ohos.process'; var child = process.runCmd('sleep 5; ls'); child.close(); ``` @@ -328,12 +335,443 @@ Sends a signal to the specified child process to terminate it. - Example ``` - import process from '@ohos.process'; var child = process.runCmd('sleep 5; ls'); child.kill(9); ``` +## process.isIsolatedProcess8+ + +isIsolatedProcess\(\): boolean + +Checks whether the process is isolated. + +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

Returns true if the process is isolated; returns false otherwise.

+
+ + +- Example + + ``` + var result = process.isIsolatedProcess(); + ``` + + +## process.isAppUid8+ + +isAppUid\(v:number\): boolean + +Checks whether a UID belongs to this app. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

v

+

number

+

Yes

+

UID.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

Returns true if the UID is the app's UID; returns false otherwise.

+
+ + +- Example + + ``` + var result = process.isAppUid(688); + ``` + + +## process.is64Bit8+ + +is64Bit\(\): boolean + +Checks whether the operating environment is of 64-bit. + +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

Returns true if the operating environment is of 64-bit; returns false otherwise.

+
+ +- Example + + ``` + var ressult = process.is64Bit(); + ``` + + +## process.getUidForName8+ + +getUidForName\(v:string\): number + +Obtains the process UID based on the process name. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

v

+

string

+

Yes

+

Process name.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Process UID.

+
+ +- Example + + ``` + var pres = process.getUidForName("tool") + ``` + + +## process.getThreadPriority8+ + +getThreadPriority\(v:number\): number + +Obtains the thread priority based on the specified TID. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

v

+

number

+

Yes

+

TID.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Priority of the thread.

+
+ +- Example + + ``` + var tid = process.tid; + var pres = process.getThreadPriority(tid); + ``` + + +## process.getStartRealtime8+ + +getStartRealtime\(\) :number + +Obtains the duration, in milliseconds, from the time the system starts to the time the process starts. + +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Time duration obtained.

+
+ + +- Example + + ``` + var realtime = process.getStartRealtime(); + ``` + + +## process.getAvailableCores8+ + +getAvailableCores\(\) :number\[\] + +Obtains the number of CPU cores available for the current process on a multi-core device. + +- Return values + + + + + + + + + + +

Type

+

Description

+

number[]

+

Number of cores available for the process.

+
+ + +- Example + + ``` + var result = getAvailableCores(); + ``` + + +## process.getPastCputime8+ + +getPastCputime\(\) :number + +Obtains the CPU time \(in milliseconds\) from the time the process starts to the current time. + +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

CPU time obtained.

+
+ + +- Example + + ``` + var result = process.getPastCputime() ; + ``` + + +## process.getSystemConfig8+ + +getSystemConfig\(name:number\): number + +Obtains the system configuration. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

name

+

number

+

Yes

+

System configuration parameter name.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

System configuration obtained.

+
+ +- Example + + ``` + var _SC_ARG_MAX = 0 + var pres = process.getSystemConfig(_SC_ARG_MAX) + ``` + + +## process.getEnvironmentVar8+ + +getEnvironmentVar\(name:string\): string + +Obtains the value of an environment variable. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

name

+

string

+

Yes

+

Environment variable name.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Value of the environment variable.

+
+ +- Example + + ``` + var pres = process.getEnvironmentVar("PATH") + ``` + + ## process.runCmd runCmd\(command: string, options?: \{ timeout : number, killSignal : number | string, maxBuffer : number \}\) : ChildProcess @@ -437,12 +875,11 @@ Forks a new process to run a shell command and returns the **ChildProcess** ob - Example ``` - import process from '@ohos.process'; var child = process.runCmd('ls', { maxBuffer : 2 }); var result = child.wait(); child.getOutput.then(val=>{ console.log("child.getOutput = " + val); - } + }) ``` @@ -455,7 +892,6 @@ Aborts a process and generates a core file. This method will cause a process to - Example ``` - import process from '@ohos.process'; process.abort(); ``` @@ -520,7 +956,6 @@ Stores the events triggered by the user. - Example ``` - import process from '@ohos.process'; process.on("data", (e)=>{ console.log("data callback"); }) @@ -569,7 +1004,7 @@ Deletes the event stored by the user.

boolean

-

Whether the event is deleted.

+

Returns true if the event is deleted; returns false otherwise.

@@ -578,7 +1013,6 @@ Deletes the event stored by the user. - Example ``` - import process from '@ohos.process'; process.on("data", (e)=>{ console.log("data callback"); }) @@ -590,7 +1024,7 @@ Deletes the event stored by the user. exit\(code: number\): void -Terminates a process. +Terminates this process. - Parameters @@ -620,7 +1054,6 @@ Terminates a process. - Example ``` - import process from '@ohos.process'; process.exit(0); ``` @@ -629,12 +1062,11 @@ Terminates a process. cwd\(\): string -Obtains the working directory of the process. +Obtains the working directory of this process. - Example ``` - import process from '@ohos.process'; var path = process.cwd(); ``` @@ -643,7 +1075,7 @@ Obtains the working directory of the process. chdir\(dir: string\): void -Changes the working directory of the process. +Changes the working directory of this process. - Parameters @@ -673,7 +1105,6 @@ Changes the working directory of the process. - Example ``` - import process from '@ohos.process'; process.chdir('/system'); ``` @@ -682,7 +1113,7 @@ Changes the working directory of the process. uptime\(\): number -Obtains the running time of the process. +Obtains the running time of this process. - Return values @@ -704,7 +1135,6 @@ Obtains the running time of the process. - Example ``` - import process from '@ohos.process'; var time = process.uptime(); ``` @@ -760,7 +1190,7 @@ Sends a signal to the specified process to terminate it.

boolean

-

Whether the signal is sent successfully.

+

Returns true if the signal is sent successfully; returns false otherwise.

@@ -769,7 +1199,6 @@ Sends a signal to the specified process to terminate it. - Example ``` - import process from '@ohos.process' var pres = process.pid var result = that.kill(pres, 28) ``` diff --git a/en/application-dev/reference/apis/js-apis-reminderAgent.md b/en/application-dev/reference/apis/js-apis-reminderAgent.md new file mode 100644 index 0000000000..9522366139 --- /dev/null +++ b/en/application-dev/reference/apis/js-apis-reminderAgent.md @@ -0,0 +1,1199 @@ +# Reminder Agent + +>**NOTE:** +>The initial APIs of this module are supported since API version 7. Newly added APIs will be marked with a superscript to indicate their earliest API version. + +## Applicable Devices + + + + + + + + + + + + + + +

Phone

+

Tablet

+

Smart TV

+

Wearable

+

Yes

+

Yes

+

Yes

+

Yes

+
+ +## Modules to Import + +``` +import reminderAgent from '@ohos.reminderAgent'; +``` + +## Required Permissions + +ohos.permission.PUBLISH\_AGENT\_REMINDER + +## reminderAgent.publishReminder + +publishReminder\(reminderReq: ReminderRequest, callback: AsyncCallback\): void + +Publishes an agent-powered reminder. This method uses an asynchronous callback to return the published reminder's ID. + +- Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

reminderReq

+

ReminderRequest

+

Yes

+

Reminder to be published.

+

callback

+

AsyncCallback<number>

+

Yes

+

Asynchronous callback used to return the result.

+
+ +- Example + + ``` + export default { + data: { + timer: { + reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, + triggerTimeInSeconds: 3 + } + }, + startTimer() { + reminderAgent.publishReminder(timer, (err, reminderId) => { + console.log("reminderId = " + reminderId); + }); + } + } + ``` + + +## reminderAgent.publishReminder + +publishReminder\(reminderReq: ReminderRequest\): Promise + +Publishes an agent-powered reminder. This method uses a promise callback to return the published reminder's ID. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

reminderReq

+

ReminderRequest

+

Yes

+

Reminder to be published.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

Promise<number>

+

Promise used to return the result.

+
+ +- Example + + ``` + export default { + data: { + timer: { + reminderType: reminderAgent.ReminderType.REMINDER_TYPE_TIMER, + triggerTimeInSeconds: 3 + } + }, + startTimer() { + reminderAgent.publishReminder(this.timer).then((reminderId) => { + console.log("reminderId = " + reminderId); + }); + } + } + ``` + + +## reminderAgent.cancelReminder + +cancelReminder\(reminderId: number, callback: AsyncCallback\): void + +Cancels the reminder with the specified ID. This method uses an asynchronous callback to return the cancellation result. + +- Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

reminderId

+

number

+

Yes

+

ID of the reminder to cancel.

+

callback

+

AsyncCallback<void>

+

Yes

+

Asynchronous callback used to return the result.

+
+ +- Example + +``` +export default { + cancel() { + reminderAgent.cancelReminder(1, (err, data) => { + console.log("do next"); + }); + } +} +``` + +## reminderAgent.cancelReminder + +cancelReminder\(reminderId: number\): Promise + +Cancels the reminder with the specified ID. This method uses a promise to return the cancellation result. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

reminderId

+

number

+

Yes

+

ID of the reminder to cancel.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

Promise<void>

+

Promise used to return the result.

+
+ +- Example + +``` +export default { + cancel() { + reminderAgent.cancelReminder(1).then(() => { + console.log("do next"); + }); + } +} +``` + +## reminderAgent.getValidReminders + +getValidReminders\(callback: AsyncCallback\>\): void + +Obtains all valid \(not yet expired\) reminders set by the current application. This method uses an asynchronous callback to return the reminders. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

callback

+

AsyncCallback<Array<ReminderRequest>>

+

Yes

+

Asynchronous callback used to return an array of all valid reminders set by the current application.

+
+ +- Example + +``` +reminderAgent.getValidReminders((err, reminders) => { + for (let i = 0; i < reminders.length; i++) { + console.log("getValidReminders = " + reminders[i]); + console.log("getValidReminders, reminderType = " + reminders[i].reminderType); + for (let j = 0; j < reminders[i].actionButton.length; j++) { + console.log("getValidReminders, actionButton.title = " + reminders[i].actionButton[j].title); + console.log("getValidReminders, actionButton.type = " + reminders[i].actionButton[j].type); + } + console.log("getValidReminders, wantAgent.pkgName = " + reminders[i].wantAgent.pkgName); + console.log("getValidReminders, wantAgent.abilityName = " + reminders[i].wantAgent.abilityName); + console.log("getValidReminders, maxScreenWantAgent.pkgName = " + reminders[i].maxScreenWantAgent.pkgName); + console.log("getValidReminders, maxScreenWantAgent.abilityName = " + reminders[i].maxScreenWantAgent.abilityName); + console.log("getValidReminders, ringDuration = " + reminders[i].ringDuration); + console.log("getValidReminders, snoozeTimes = " + reminders[i].snoozeTimes); + console.log("getValidReminders, timeInterval = " + reminders[i].timeInterval); + console.log("getValidReminders, title = " + reminders[i].title); + console.log("getValidReminders, content = " + reminders[i].content); + console.log("getValidReminders, expiredContent = " + reminders[i].expiredContent); + console.log("getValidReminders, snoozeContent = " + reminders[i].snoozeContent); + console.log("getValidReminders, notificationId = " + reminders[i].notificationId); + console.log("getValidReminders, slotType = " + reminders[i].slotType); + } +}) +``` + +## reminderAgent.getValidReminders + +getValidReminders\(\): Promise\> + +Obtains all valid \(not yet expired\) reminders set by the current application. This method uses a promise to return the reminders. + +- Return values + + + + + + + + + + +

Type

+

Description

+

Promise<Array<ReminderRequest>>

+

Promise used to return an array of all valid reminders set by the current application.

+
+ +- Example + +``` +reminderAgent.getValidReminders().then((reminders) => { + for (let i = 0; i < reminders.length; i++) { + console.log("getValidReminders = " + reminders[i]); + console.log("getValidReminders, reminderType = " + reminders[i].reminderType); + for (let j = 0; j < reminders[i].actionButton.length; j++) { + console.log("getValidReminders, actionButton.title = " + reminders[i].actionButton[j].title); + console.log("getValidReminders, actionButton.type = " + reminders[i].actionButton[j].type); + } + console.log("getValidReminders, wantAgent.pkgName = " + reminders[i].wantAgent.pkgName); + console.log("getValidReminders, wantAgent.abilityName = " + reminders[i].wantAgent.abilityName); + console.log("getValidReminders, maxScreenWantAgent.pkgName = " + reminders[i].maxScreenWantAgent.pkgName); + console.log("getValidReminders, maxScreenWantAgent.abilityName = " + reminders[i].maxScreenWantAgent.abilityName); + console.log("getValidReminders, ringDuration = " + reminders[i].ringDuration); + console.log("getValidReminders, snoozeTimes = " + reminders[i].snoozeTimes); + console.log("getValidReminders, timeInterval = " + reminders[i].timeInterval); + console.log("getValidReminders, title = " + reminders[i].title); + console.log("getValidReminders, content = " + reminders[i].content); + console.log("getValidReminders, expiredContent = " + reminders[i].expiredContent); + console.log("getValidReminders, snoozeContent = " + reminders[i].snoozeContent); + console.log("getValidReminders, notificationId = " + reminders[i].notificationId); + console.log("getValidReminders, slotType = " + reminders[i].slotType); + } +}) +``` + +## reminderAgent.cancelAllReminders + +cancelAllReminders\(callback: AsyncCallback\): void + +Cancels all reminders set by the current application. This method uses an asynchronous callback to return the cancellation result. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

callback

+

AsyncCallback<void>

+

Yes

+

Asynchronous callback used to return the result.

+
+ +- Example + +``` +reminderAgent.cancelAllReminders((err, data) =>{ + console.log("do next")} +) +``` + +## reminderAgent.cancelAllReminders + +cancelAllReminders\(\): Promise + +Cancels all reminders set by the current application. This method uses a promise to return the cancellation result. + +- Return values + + + + + + + + + + +

Type

+

Description

+

Promise<void>

+

Promise used to return the result.

+
+ +- Example + +``` +reminderAgent.cancelAllReminders().then(() => { + console.log("do next")} +) +``` + +## reminderAgent.addNotificationSlot + +addNotificationSlot\(slot: NotificationSlot, callback: AsyncCallback\): void + +Adds a reminder notification slot. This method uses an asynchronous callback to return the result. + +- Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

slot

+

NotificationSlot

+

Yes

+

Reminder notification slot to add.

+

callback

+

AsyncCallback<void>

+

Yes

+

Asynchronous callback used to return the result.

+
+ +- Example + +``` +export default { + data: { + mySlot: { + type: 3, + sound: "/sdcard/music2.mp3" + } + }, + addSlot() { + reminderAgent.addNotificationSlot(this.mySlot, (err, data) => { + console.log("do next"); + }); + } +} +``` + +## reminderAgent.addNotificationSlot + +addNotificationSlot\(slot: NotificationSlot\): Promise + +Adds a reminder notification slot. This method uses a promise to return the result. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

slot

+

NotificationSlot

+

Yes

+

Reminder notification slot to add.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

Promise<void>

+

Promise used to return the result.

+
+ +- Example + +``` +export default { + data: { + mySlot: { + type: 3, + sound: "/sdcard/music2.mp3" + } + }, + addSlot() { + reminderAgent.addNotificationSlot(this.mySlot).then(() => { + console.log("do next"); + }); + } +} +``` + +## reminderAgent.removeNotificationSlot + +removeNotificationSlot\(slotType: notification.SlotType, callback: AsyncCallback\): void + +Removes a **NotificationSlot** instance of a specified type. This method uses an asynchronous callback to return the result. + +- Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

slotType

+

notification.SlotType

+

Yes

+

Type of the reminder notification slot to remove.

+

callback

+

AsyncCallback<void>

+

Yes

+

Asynchronous callback used to return the result.

+
+ +- Example + +``` +export default { + removeSlot() { + reminderAgent.removeNotificationSlot(notification.SlotType.CONTENT_INFORMATION, (err, data) => { + console.log("do next"); + }); + } +} +``` + +## reminderAgent.removeNotificationSlot + +removeNotificationSlot\(slotType: notification.SlotType\): Promise + +Removes a **NotificationSlot** instance of a specified type. This method uses a promise to return the result. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

slotType

+

notification.SlotType

+

Yes

+

Type of the reminder notification slot to remove.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

Promise<void>

+

Promise used to return the result.

+
+ +- Example + +``` +export default { + removeSlot() { + reminderAgent.removeNotificationSlot(notification.SlotType.CONTENT_INFORMATION).then(() => { + console.log("do next"); + }); + } +} +``` + +## ActionButtonType + +Enumerates button types. + + + + + + + + + + + + + + + + +

Name

+

Default Value

+

Description

+

ACTION_BUTTON_TYPE_CLOSE

+

0

+

Button for closing the reminder.

+

ACTION_BUTTON_TYPE_SNOOZE

+

1

+

Button for snoozing the reminder.

+
+ +## ReminderType + +Enumerates reminder types. + + + + + + + + + + + + + + + + + + + + +

Name

+

Default Value

+

Description

+

REMINDER_TYPE_TIMER

+

0

+

Countdown reminder.

+

REMINDER_TYPE_CALENDAR

+

1

+

Calendar reminder.

+

REMINDER_TYPE_ALARM

+

2

+

Alarm reminder.

+
+ +## ActionButton + +Defines a button displayed in the reminder notification. + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

title

+

string

+

Yes

+

Text on the button.

+

type

+

ActionButtonType

+

Yes

+

Button type.

+
+ +## WantAgent + +Sets the package and ability that are redirected to when the reminder notification is clicked. + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

pkgName

+

string

+

Yes

+

Name of the package redirected to when the reminder notification is clicked.

+

abilityName

+

string

+

Yes

+

Name of the ability that is redirected to when the reminder notification is clicked.

+
+ +## MaxScreenWantAgent + +Sets the name of the target package and ability to start automatically when the reminder arrives and the device is not in use. If the device is in use, a notification will be displayed. + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

pkgName

+

string

+

Yes

+

Name of the package that is automatically started when the reminder arrives and the device is not in use.

+

abilityName

+

string

+

Yes

+

Name of the ability that is automatically started when the reminder arrives and the device is not in use.

+
+ +## ReminderRequest + +Defines the reminder to publish. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

reminderType

+

ReminderType

+

Yes

+

Type of the reminder.

+

actionButton

+

[ActionButton?, ActionButton?]

+

No

+

Action button displayed in the reminder notification. (The parameter is optional. Up to two buttons are supported.)

+

wantAgent

+

WantAgent

+

No

+

Information about the ability that is redirected to when the notification is clicked.

+

maxScreenWantAgent

+

MaxScreenWantAgent

+

No

+

Information about the ability that is automatically started when the reminder arrives. If the device is in use, a notification will be displayed.

+

ringDuration

+

number

+

No

+

Ringing duration.

+

snoozeTimes

+

number

+

No

+

Number of reminder snooze times.

+

timeInterval

+

number

+

No

+

Reminder snooze interval.

+

title

+

string

+

No

+

Reminder title.

+

content

+

string

+

No

+

Reminder content.

+

expiredContent

+

string

+

No

+

Content to be displayed after the reminder expires.

+

snoozeContent

+

string

+

No

+

Content to be displayed when the reminder is snoozing.

+

notificationId

+

number

+

No

+

Notification ID used by the reminder. If there are reminders with the same notification ID, the later one will overwrite the earlier one.

+

slotType

+

notification.SlotType

+

No

+

Type of the slot used by the reminder.

+
+ +## ReminderRequestCalendar + +ReminderRequestCalendar extends ReminderRequest + +Defines a reminder for a calendar event. + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

dateTime

+

LocalDateTime

+

Yes

+

Reminder time.

+

repeatMonths

+

Array<number>

+

No

+

Month in which the reminder repeats.

+

repeatDays

+

Array<number>

+

No

+

Date on which the reminder repeats.

+
+ +## ReminderRequestAlarm + +ReminderRequestAlarm extends ReminderRequest + +Defines a reminder for the alarm clock. + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

hour

+

number

+

Yes

+

Hour portion of the reminder time.

+

minute

+

number

+

Yes

+

Minute portion of the reminder time.

+

daysOfWeek

+

Array<number>

+

No

+

Days of a week when the reminder repeats.

+
+ +## ReminderRequestTimer + +Defines a **ReminderRequestTimer** instance, which extends **ReminderRequest**. + +Defines a reminder for a scheduled timer. + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

triggerTimeInSeconds

+

number

+

Yes

+

Number of seconds in the countdown timer.

+
+ +## LocalDateTime + +Sets the time information for a calendar reminder. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

year

+

number

+

Yes

+

Year.

+

month

+

number

+

Yes

+

Month.

+

day

+

number

+

Yes

+

Date.

+

hour

+

number

+

Yes

+

Hour.

+

minute

+

number

+

Yes

+

Minute.

+

second

+

number

+

No

+

Second.

+
+ diff --git a/en/application-dev/reference/apis/js-apis-resource-manager.md b/en/application-dev/reference/apis/js-apis-resource-manager.md index d90f8aef6a..355e1fb4df 100644 --- a/en/application-dev/reference/apis/js-apis-resource-manager.md +++ b/en/application-dev/reference/apis/js-apis-resource-manager.md @@ -1,9 +1,9 @@ -# Resource Manager +# Resource Manager + >![](../../public_sys-resources/icon-note.gif) **NOTE:** >The initial APIs of this module are supported since API version 7. Newly added APIs will be marked with a superscript to indicate their earliest API version. - ## Modules to Import ``` @@ -362,8 +362,6 @@ Enumerates screen density types. Provides the device configuration. -### Attributes - @@ -406,8 +404,6 @@ Provides the device configuration. Provides the device capability. -### Attributes -

Name

@@ -450,6 +446,10 @@ Provides the device capability. Provides the capability of accessing application resources. +>![](../public_sys-resources/icon-note.gif) **NOTE:** +>- The methods involved in **ResourceManager** are applicable only to the TypeScript-based declarative development paradigm. +>- Resource files are defined in the **resources** directory of the project. You can obtain the resource ID from **$r\(resource address\).id**, for example, **$r\(?app.string.test?\).id**. + ### getString getString\(resId: number, callback: AsyncCallback\): void @@ -494,7 +494,7 @@ Obtains the string corresponding to the specified resource ID. This method uses ``` resourceManager.getResourceManager((error, mgr) => { - mgr.getString(0x1000000, (error, value) => { + mgr.getString($r('app.string.test').id, (error, value) => { if (error != null) { console.log(value); } else { @@ -557,7 +557,7 @@ Obtains the string corresponding to the specified resource ID. This method uses ``` resourceManager.getResourceManager((error, mgr) => { - mgr.getString(0x1000000).then(value => { + mgr.getString($r('app.string.test').id).then(value => { console.log(value); }).catch(error => { console.log("getstring promise " + error); @@ -610,7 +610,7 @@ Obtains the array of strings corresponding to the specified resource ID. This me ``` resourceManager.getResourceManager((error, mgr) => { - mgr.getStringArray(0x1000000, (error, value) => { + mgr.getStringArray($r('app.strarray.test').id, (error, value) => { if (error != null) { console.log(value); } else { @@ -663,7 +663,7 @@ Obtains the array of strings corresponding to the specified resource ID. This me - @@ -673,7 +673,7 @@ Obtains the array of strings corresponding to the specified resource ID. This me ``` resourceManager.getResourceManager((error, mgr) => { - mgr.getStringArray(0x1000000).then(value => { + mgr.getStringArray($r('app.strarray.test').id).then(value => { console.log(value); }).catch(error => { console.log("getstring promise " + error); @@ -712,7 +712,7 @@ Obtains the content of the media file corresponding to the specified resource ID - @@ -726,7 +726,7 @@ Obtains the content of the media file corresponding to the specified resource ID ``` resourceManager.getResourceManager((error, mgr) => { - mgr.getMedia(0x1000000, (error, value) => { + mgr.getMedia($r('app.media.test').id, (error, value) => { if (error != null) { console.log(value); } else { @@ -777,7 +777,7 @@ Obtains the content of the media file corresponding to the specified resource ID - @@ -789,7 +789,7 @@ Obtains the content of the media file corresponding to the specified resource ID ``` resourceManager.getResourceManager((error, mgr) => { - mgr.getMedia(0x1000000).then(value => { + mgr.getMedia($r('app.media.test').id).then(value => { console.log(value); }).catch(error => { console.log("getstring promise " + error); @@ -842,7 +842,7 @@ Obtains the Base64 code of the image corresponding to the specified resource ID. ``` resourceManager.getResourceManager((error, mgr) => { - mgr.getMediaBase64(0x1000000, (error, value) => { + mgr.getMediaBase64($r('app.media.test').id, (error, value) => { if (error != null) { console.log(value); } else { @@ -905,7 +905,7 @@ Obtains the Base64 code of the image corresponding to the specified resource ID. ``` resourceManager.getResourceManager((error, mgr) => { - mgr.getMediaBase64(0x1000000).then(value => { + mgr.getMediaBase64($r('app.media.test').id).then(value => { console.log(value); }).catch(error => { console.log("getstring promise " + error); @@ -1131,7 +1131,7 @@ Obtains the specified number of singular-plural strings corresponding to the spe ``` resourceManager.getResourceManager((error, mgr) => { - mgr.getPluralString(0x1000000, 1, (error, value) => { + mgr.getPluralString($r("app.plural.test").id, 1, (error, value) => { if (error != null) { console.log(value); } else { @@ -1203,7 +1203,7 @@ Obtains the specified number of singular-plural strings corresponding to the spe ``` resourceManager.getResourceManager((error, mgr) => { - mgr.getPluralString(0x1000000, 1).then(value => { + mgr.getPluralString($r("app.plural.test").id, 1).then(value => { console.log(value); }).catch(error => { console.log("getstring promise " + error); @@ -1212,3 +1212,118 @@ Obtains the specified number of singular-plural strings corresponding to the spe ``` +### getRawFile8+ + +getRawFile\(path: string, callback: AsyncCallback\): void + +Obtains the content of rawfile in the specified path. This method uses an asynchronous callback to return the result. + +- Parameters + + +

Name

Promise<Array<string>>

Array of character strings corresponding to the specified resource ID.

+

Array of strings corresponding to the specified resource ID.

callback

AsyncCallback<Array<Uint8Array>>

+

AsyncCallback<Uint8Array>

Yes

Promise<Array<Uint8Array>>

+

Promise<Uint8Array>

Promise used to return the content of the obtained media file.

+ + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

path

+

string

+

Yes

+

Path of the rawfile.

+

callback

+

AsyncCallback<Uint8Array>

+

Yes

+

Asynchronous callback used to return the rawfile content, in byte arrays.

+
+ +- Example + + ``` + resourceManager.getResourceManager((error, mgr) => { + mgr.getRawFile("test.xml", (error, value) => { + if (error != null) { + console.log(value); + } else { + console.log(value); + } + }); + }); + ``` + + +### getRawFile8+ + +getRawFile\(path: string\): Promise + +Obtains the content of the rawfile in the specified path. This method uses a promise to return the result. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

path

+

string

+

Yes

+

Path of the rawfile.

+
+ +- Return values + + + + + + + + + + +

Type

+

Description

+

Promise<Uint8Array>

+

Promise used to return the rawfile content, in byte arrays.

+
+ +- Example + + ``` + resourceManager.getResourceManager((error, mgr) => { + mgr.getRawFile("test.xml").then(value => { + console.log(value); + }).catch(error => { + console.log("getrawfile promise " + error); + }); + }); + ``` + diff --git a/en/application-dev/reference/apis/js-apis-system-time.md b/en/application-dev/reference/apis/js-apis-system-time.md index e851eec105..d7cedf77c5 100644 --- a/en/application-dev/reference/apis/js-apis-system-time.md +++ b/en/application-dev/reference/apis/js-apis-system-time.md @@ -3,30 +3,6 @@ >![](../../public_sys-resources/icon-note.gif) **NOTE:** >The APIs of this module are supported since API version 7. -## Applicable Devices - - - - - - - - - - - - - - -

Phone

-

Tablet

-

Smart TV

-

Wearable

-

Yes

-

Yes

-

Yes

-

Yes

-
## Modules to Import diff --git a/en/application-dev/reference/apis/js-apis-uri.md b/en/application-dev/reference/apis/js-apis-uri.md new file mode 100644 index 0000000000..c3eb105e1c --- /dev/null +++ b/en/application-dev/reference/apis/js-apis-uri.md @@ -0,0 +1,338 @@ +# URI String Parsing + +>![](../../public_sys-resources/icon-note.gif) **NOTE:** +>The initial APIs of this module are supported since API version 8. Newly added APIs will be marked with a superscript to indicate their earliest API version. + +## Modules to Import + +``` +import uri from '@ohos.uri' +``` + +## Required Permissions + +None + +## URI + +### Attributes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Readable

+

Writable

+

Description

+

scheme

+

string

+

Yes

+

No

+

Protocol in the URI.

+

userinfo

+

string

+

Yes

+

No

+

User information in the URI.

+

host

+

string

+

Yes

+

No

+

Host name (without the port number) in the URI.

+

port

+

string

+

Yes

+

No

+

Port number in the URI.

+

path

+

string

+

Yes

+

No

+

Path in the URI.

+

query

+

string

+

Yes

+

No

+

Query part in the URI.

+

fragment

+

string

+

Yes

+

No

+

Fragment part in the URI.

+

authority

+

string

+

Yes

+

No

+

Authority part in the URI.

+

ssp

+

string

+

Yes

+

No

+

Scheme-specific part in the URI.

+
+ +### constructor + +constructor\(uri: string\) + +A constructor used to create a URI instance. + +- Parameters + + + + + + + + + + + + + + + + +

Name

+

Type

+

Readable

+

Writable

+

Description

+

url

+

string

+

Yes

+

Yes

+

Input parameter object.

+
+ + +- Example + + ``` + var mm = 'http://username:password@host:8080/directory/file?foo=1&bar=2#fragment'; + new uri.URI(mm); // Output 'http://username:password@host:8080/directory/file?foo=1&bar=2#fragment'; + ``` + + ``` + new uri.URI('http://username:password@host:8080'); // Output 'http://username:password@host:8080'; + ``` + + +### toString + +toString\(\): string + +Obtains the query string applicable to this URL. + +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Website address in a serialized string.

+
+ + +- Example + + ``` + const url = new uri.URL('http://username:password@host:8080/directory/file?query=pppppp#qwer=da'); + url.toString() + ``` + + +### equals + +equals\(other: URI\): boolean + +Checks whether this URI is the same as another URI object. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

other

+

URI

+

Yes

+

URI object to compare.

+
+ + +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

Returns true if the two URIs are the same; returns false otherwise.

+
+ + +- Example + + ``` + const uriInstance = new uri.URI('http://username:password@host:8080/directory/file?query=pppppp#qwer=da'); + const uriInstance1 = new uri.URI('http://username:password@host:8080/directory/file?query=pppppp#qwer=da#fragment'); + uriInstance.equals(uriInstance1); + ``` + + +### checkIsAbsolute + +checkIsAbsolute\(\): boolean + +Checks whether this URI is an absolute URI \(whether the scheme component is defined\). + +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

Returns true if the URI is an absolute URI; returns false otherwise.

+
+ + +- Example + + ``` + const uriInstance = new uri.URI('http://username:password@www.qwer.com:8080?query=pppppp'); + uriInstance.checkIsAbsolute(); + ``` + + +### normalize + +normalize\(\): URI + +Normalizes the path of this URI. + +- Return values + + + + + + + + + + +

Type

+

Description

+

URI

+

URI with the normalized path.

+
+ + +- Example + + ``` + const uriInstance = new uri.URI('http://username:password@www.qwer.com:8080/path/path1/../path2/./path3?query=pppppp'); + let uriInstance1 = uriInstance.normalize(); + uriInstance1.path; + ``` + + diff --git a/en/application-dev/reference/apis/js-apis-useriam-userauth.md b/en/application-dev/reference/apis/js-apis-useriam-userauth.md index e05a6fdd45..267445bbd6 100644 --- a/en/application-dev/reference/apis/js-apis-useriam-userauth.md +++ b/en/application-dev/reference/apis/js-apis-useriam-userauth.md @@ -3,30 +3,6 @@ >**NOTE:** >The initial APIs of this module are supported since API version 6. Newly added APIs will be marked with a superscript to indicate their earliest API version. -## Applicable Devices - - - - - - - - - - - - - - -

Phone

-

Tablet

-

Smart TV

-

Wearable

-

Yes

-

Yes

-

No

-

No

-
## Modules to Import diff --git a/en/application-dev/reference/apis/js-apis-worker.md b/en/application-dev/reference/apis/js-apis-worker.md index ff388df2f0..53879bb88f 100644 --- a/en/application-dev/reference/apis/js-apis-worker.md +++ b/en/application-dev/reference/apis/js-apis-worker.md @@ -1,6 +1,6 @@ # Worker Startup ->![](../../public_sys-resources/icon-note.gif) **NOTE:** +>**NOTE:** >The initial APIs of this module are supported since API version 7. Newly added APIs will be marked with a superscript to indicate their earliest API version. ## Modules to Import @@ -131,13 +131,13 @@ A constructor used to create a worker instance. - Return values -

Name

+ - @@ -148,8 +148,7 @@ A constructor used to create a worker instance. - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js", {name:"first worker"}); + const workerInstance = new worker.Worker("workers/worker.js", {name:"first worker"}); ``` @@ -196,13 +195,14 @@ Sends a message to the worker thread. The data is transferred using the structur - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js"); - worker.postMessage("hello world"); - - const worker = new worker.Worker("workers/worker.js"); + const workerInstance = new worker.Worker("workers/worker.js"); + workerInstance.postMessage("hello world"); + ``` + + ``` + const workerInstance = new worker.Worker("workers/worker.js"); var buffer = new ArrayBuffer(8); - worker.postMessage(buffer, [buffer]); + workerInstance.postMessage(buffer, [buffer]); ``` @@ -249,9 +249,8 @@ Adds an event listener to the worker. - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - worker.on("alert", (e)=>{ + const workerInstance = new worker.Worker("workers/worker.js") + workerInstance.on("alert", (e)=>{ console.log("alert listener callback"); }) ``` @@ -300,9 +299,8 @@ Adds an event listener to the worker and removes the event listener automaticall - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js"); - worker.once("alert", (e)=>{ + const workerInstance = new worker.Worker("workers/worker.js"); + workerInstance.once("alert", (e)=>{ console.log("alert listener callback"); }) ``` @@ -351,9 +349,8 @@ Removes an event listener for the worker. - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js"); - worker.off("alert"); + const workerInstance = new worker.Worker("workers/worker.js"); + workerInstance.off("alert"); ``` @@ -366,9 +363,8 @@ Terminates the worker thread to stop the worker from receiving messages. - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - worker.terminate() + const workerInstance = new worker.Worker("workers/worker.js") + workerInstance.terminate() ``` @@ -406,9 +402,8 @@ Defines the event handler to be called when the worker exits. The handler is exe - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - worker.onexit = function(e) { + const workerInstance = new worker.Worker("workers/worker.js") + workerInstance.onexit = function(e) { console.log("onexit") } ``` @@ -448,9 +443,8 @@ Defines the event handler to be called when an exception occurs during worker ex - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - worker.onerror = function(e) { + const workerInstance = new worker.Worker("workers/worker.js") + workerInstance.onerror = function(e) { console.log("onerror") } ``` @@ -490,9 +484,8 @@ Defines the event handler to be called when the host thread receives a message c - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - worker.onmessage = function(e) { + const workerInstance = new worker.Worker("workers/worker.js") + workerInstance.onmessage = function(e) { console.log("onerror") } ``` @@ -532,9 +525,8 @@ Defines the event handler to be called when the worker receives a message that c - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - worker.onmessageerror= function(e) { + const workerInstance = new worker.Worker("workers/worker.js") + workerInstance.onmessageerror= function(e) { console.log("onmessageerror") } ``` @@ -585,9 +577,8 @@ Adds an event listener to the worker. - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - worker.addEventListener("alert", (e)=>{ + const workerInstance = new worker.Worker("workers/worker.js") + workerInstance.addEventListener("alert", (e)=>{ console.log("alert listener callback"); }) ``` @@ -636,9 +627,8 @@ Removes an event listener for the worker. - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - worker.removeEventListener("alert") + const workerInstance = new worker.Worker("workers/worker.js") + workerInstance.removeEventListener("alert") ``` @@ -676,7 +666,7 @@ Dispatches the event defined for the worker. - Return values -

Type

Description

worker

+

Worker

Returns the worker instance created; returns undefined if the worker instance fails to be created.

Name

+ @@ -693,9 +683,8 @@ Dispatches the event defined for the worker. - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - worker.dispatchEvent({type:"alert"}) + const workerInstance = new worker.Worker("workers/worker.js") + workerInstance.dispatchEvent({type:"alert"}) ``` @@ -708,9 +697,8 @@ Removes all event listeners for the worker. - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - worker.removeAllListener({type:"alert"}) + const workerInstance = new worker.Worker("workers/worker.js") + workerInstance.removeAllListener({type:"alert"}) ``` @@ -762,13 +750,15 @@ Sends a message to the host thread from the worker. ``` // main.js - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - worker.postMessage("hello world") - worker.onmessage = function(e) { + import worker from "@ohos.worker"; + const workerInstance = new worker.Worker("workers/worker.js") + workerInstance.postMessage("hello world") + workerInstance.onmessage = function(e) { console.log("receive data from worker.js") } - + ``` + + ``` // worker.js import worker from "@ohos.worker"; const parentPort = worker.parentPort; @@ -789,8 +779,10 @@ Closes the worker thread to stop the worker from receiving messages. ``` // main.js import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - + const workerInstance = new worker.Worker("workers/worker.js") + ``` + + ``` // worker.js import worker from "@ohos.worker"; const parentPort = worker.parentPort; @@ -836,9 +828,11 @@ Defines the event handler to be called when the worker thread receives a message ``` // main.js import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - worker.postMessage("hello world") - + const workerInstance = new worker.Worker("workers/worker.js") + workerInstance.postMessage("hello world") + ``` + + ``` // worker.js import worker from "@ohos.worker"; const parentPort = worker.parentPort; @@ -884,8 +878,10 @@ Defines the event handler to be called when the worker receives a message that c ``` // main.js import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - + const workerInstance = new worker.Worker("workers/worker.js") + ``` + + ``` // worker.js import worker from "@ohos.worker"; const parentPort = worker.parentPort; @@ -1004,7 +1000,7 @@ Specifies the callback to invoke. - Return values -

Type

Description

Name

+ @@ -1021,9 +1017,8 @@ Specifies the callback to invoke. - Example ``` - import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js"); - worker.addEventListener("alert", (e)=>{ + const workerInstance = new worker.Worker("workers/worker.js"); + workerInstance.addEventListener("alert", (e)=>{ console.log("alert listener callback"); }) ``` @@ -1215,8 +1210,10 @@ Defines the event handler to be called when an exception occurs during worker ex ``` // main.js import worker from '@ohos.worker'; - const worker = new worker.Worker("workers/worker.js") - + const workerInstance = new worker.Worker("workers/worker.js") + ``` + + ``` // worker.js import worker from "@ohos.worker"; const parentPort = worker.parentPort diff --git a/en/application-dev/reference/apis/js-apis-xml.md b/en/application-dev/reference/apis/js-apis-xml.md new file mode 100644 index 0000000000..98ff62e6a3 --- /dev/null +++ b/en/application-dev/reference/apis/js-apis-xml.md @@ -0,0 +1,976 @@ +# XML Parsing and Generation + +>![](../../public_sys-resources/icon-note.gif) **NOTE:** +>The initial APIs of this module are supported since API version 8. Newly added APIs will be marked with a superscript to indicate their earliest API version. + +## Modules to Import + +``` +import xml from '@ohos.xml'; +``` + +## Required Permissions + +None + +## XmlSerializer + +### constructor + +constructor\(buffer: ArrayBuffer | DataView, encoding?: string\) + +A constructor used to create an **XmlSerializer** instance. + +- Parameters + + +

Type

Description

+ + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

buffer

+

ArrayBuffer | DataView

+

Yes

+

ArrayBuffer or DataView for storing the XML information to write.

+

encoding

+

string

+

No

+

Encoding format.

+
+ + +- Example + + ``` + var arrayBuffer = new ArrayBuffer(1024); + var bufView = new DataView(arrayBuffer); + var thatSer = new xml.XmlSerializer(bufView); + ``` + + +### setAttributes + +setAttributes\(name: string, value: string\): void + +Sets an attribute. + +- Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

name

+

string

+

Yes

+

Key of the attribute.

+

value

+

string

+

Yes

+

Value of the attribute.

+
+ +- Example + + ``` + var thatSer = new xml.XmlSerializer(bufView); + thatSer.setAttributes("importance", "high"); + ``` + + +### addEmptyElement + +addEmptyElement\(name: string\): void + +Adds an empty element. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

name

+

string

+

Yes

+

Name of the empty element to add.

+
+ + +- Example + + ``` + var thatSer = new xml.XmlSerializer(bufView); + thatSer.addEmptyElement("b"); // => + ``` + + +### setDeclaration + +setDeclaration\(\): void + +Sets a declaration. + +- Example + + ``` + var thatSer = new xml.XmlSerializer(bufView); + thatSer.setDeclaration() // => ; + ``` + + +### startElement + +startElement\(name: string\): void + +Writes the start tag based on the given element name. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

name

+

string

+

Yes

+

Name of the element.

+
+ + +- Example + + ``` + var arrayBuffer = new ArrayBuffer(1024); + var thatSer = new xml.XmlSerializer(arrayBuffer); + thatSer.startElement("notel"); + thatSer.endElement();// => ''; + ``` + + +### endElement + +endElement\(\): void + +Writes the end tag of the element. + +- Example + + ``` + var thatSer = new xml.XmlSerializer(bufView); + thatSer.setNamespace("h", "http://www.w3.org/TR/html4/"); + thatSer.startElement("table"); + thatSer.setAttributes("importance", "high"); + thatSer.setText("Happy"); + endElement(); // => Happy + ``` + + +### setNamespace + +setNamespace\(prefix: string, namespace: string\): void + +Sets the namespace for an element tag. + +- Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

prefix

+

string

+

Yes

+

Prefix of the element and its child elements.

+

namespace

+

string

+

Yes

+

Namespace to set.

+
+ + +- Example + + ``` + var arrayBuffer = new ArrayBuffer(1024); + var thatSer = new xml.XmlSerializer(arrayBuffer); + thatSer.setDeclaration(); + thatSer.setNamespace("h", "http://www.w3.org/TR/html4/"); + thatSer.startElement("note"); + thatSer.endElement();// = >'\r\n'; + ``` + + +### setComment + +setComment\(text: string\): void + +Sets the comment. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

text

+

string

+

Yes

+

Comment to set.

+
+ + +- Example + + ``` + var arrayBuffer = new ArrayBuffer(1024); + var thatSer = new xml.XmlSerializer(arrayBuffer); + thatSer.startElement("note"); + thatSer.setComment("Hi!"); + thatSer.endElement(); // => '\r\n \r\n'; + ``` + + +### setCDATA + +setCDATA\(text: string\): void + +Sets CDATA attributes. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

text

+

string

+

Yes

+

CDATA attribute to set.

+
+ + +- Example + + ``` + var arrayBuffer = new ArrayBuffer(1028); + var thatSer = new xml.XmlSerializer(arrayBuffer); + thatSer.setCDATA('root SYSTEM') // => ''; + ``` + + +### setText + +setText\(text: string\): void + +Sets **Text**. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

text

+

string

+

Yes

+

Content of the Text to set.

+
+ + +- Example + + ``` + var arrayBuffer = new ArrayBuffer(1024); + var thatSer = new xml.XmlSerializer(arrayBuffer); + thatSer.startElement("note"); + thatSer.setAttributes("importance", "high"); + thatSer.setText("Happy1"); + thatSer.endElement(); // => 'Happy1'; + ``` + + +### setDocType + +setDocType\(text: string\): void + +Sets **DocType**. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

text

+

string

+

Yes

+

Content of DocType to set.

+
+ + +- Example + + ``` + var arrayBuffer = new ArrayBuffer(1024); + var thatSer = new xml.XmlSerializer(arrayBuffer); + thatSer.setDocType('root SYSTEM'); // => ''; + ``` + + +## XmlPullParser + +### XmlPullParser + +constructor\(buffer: ArrayBuffer | DataView, encoding?: string\) + +Creates and returns an **XmlPullParser** object. The **XmlPullParser** object passes two parameters. The first parameter is the memory of the **ArrayBuffer** or **DataView** type, and the second parameter is the file format \(UTF-8 by default\). + +- Parameters + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

buffer

+

ArrayBuffer | DataView

+

Yes

+

ArrayBuffer or DataView that contains XML text information.

+

encoding

+

string

+

No

+

Encoding format. Only UTF-8 is supported.

+
+ + +- Example + + ``` + var strXml = + '' + + '' + + ' Happy' + + ' Work' + + ' Play' + + ''; + var arrayBuffer = new ArrayBuffer(strXml.length*2); + var bufView = new Uint8Array(arrayBuffer); + var strLen = strXml.length; + for (var i = 0; i < strLen; ++i) { + bufView[i] = strXml.charCodeAt(i);// Set the ArrayBuffer mode. + } + var that = new xml.XmlPullParser(arrayBuffer); + ``` + + +### parse + +parse\(option: ParseOptions\): void + +Parses XML information. + +- Parameters + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

option

+

ParseOptions

+

Yes

+

Options for controlling and obtaining the parsed information.

+
+ + +- Example + + ``` + var strXml = + '' + + '' + + ' Happy' + + ' Work' + + ' Play' + + ''; + var arrayBuffer = new ArrayBuffer(strXml.length*2); + var bufView = new Uint8Array(arrayBuffer); + var strLen = strXml.length; + for (var i = 0; i < strLen; ++i) { + bufView[i] = strXml.charCodeAt(i); + } + var that = new xml.XmlPullParser(arrayBuffer); + var arrTag = {}; + arrTag[0] = '132'; + var i = 1; + function func(key, value){ + arrTag[i] = 'key:'+key+' value:'+ value.getDepth(); + i++; + return true; + } + var options = {supportDoctype:true, ignoreNameSpace:true, tokenValueCallbackFunction:func} + that.parse(options); + ``` + + +## ParseOptions + +Defines the XML parsing options. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Type

+

Mandatory

+

Description

+

supportDoctype

+

boolean

+

No

+

Whether to ignore Doctype. The default value is false.

+

ignoreNameSpace

+

boolean

+

No

+

Whether to ignore Namespace. The default value is false.

+

tagValueCallbackFunction

+

(name: string, value: string)=> boolean

+

No

+

Callback used to return tagValue.

+

attributeValueCallbackFunction

+

(name: string, value: string)=> boolean

+

No

+

Callback used to return attributeValue.

+

tokenValueCallbackFunction

+

(eventType: EventType, value: ParseInfo)=> boolean

+

No

+

Callback used to return tokenValue.

+
+ +## ParseInfo + +Provides methods to manage the parsed XML information. + +### getColumnNumber + +getColumnNumber\(\): number + +Obtains the column line number, which starts from 1. + +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Column number obtained.

+
+ + +### getDepth + +getDepth\(\): number + +Obtains the depth of this element. + +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Depth obtained.

+
+ + +### getLineNumber + +getLineNumber\(\): number + +Obtains the current line number, starting from 1. + +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Line number obtained.

+
+ + +### getName + +getName\(\): string + +Obtains the name of this element. + +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Element name obtained.

+
+ + +### getNamespace + +getNamespace\(\): string + +Obtains the namespace of this element. + +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Namespace obtained.

+
+ + +### getPrefix + +getPrefix\(\): string + +Obtains the prefix of this element. + +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Element prefix obtained.

+
+ + +### getText + +getText\(\): string + +Obtains the text of the current event. + +- Return values + + + + + + + + + + +

Type

+

Description

+

string

+

Text content obtained.

+
+ + +### isEmptyElementTag + +isEmptyElementTag\(\): boolean + +Checks whether the current element is empty. + +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

Returns true if the element is empty; returns false otherwise.

+
+ + +### isWhitespace + +isWhitespace\(\): boolean + +Checks whether the current text event contains only whitespace characters. + +- Return values + + + + + + + + + + +

Type

+

Description

+

boolean

+

Returns true if the text event contains only whitespace characters; returns false otherwise.

+
+ + +### getAttributeCount + +getAttributeCount\(\): number + +Obtains the number of attributes for the current start tag. + +- Return values + + + + + + + + + + +

Type

+

Description

+

number

+

Number of attributes obtained.

+
+ + +## EventType + +Enumerates the events. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Name

+

Value

+

Description

+

START_DOCUMENT

+

0

+

Indicates a start document event.

+

END_DOCUMENT

+

1

+

Indicates an end document event.

+

START_TAG

+

2

+

Indicates a start tag event.

+

END_TAG

+

3

+

Indicates an end tag event.

+

TEXT

+

4

+

Indicates a text event.

+

CDSECT

+

5

+

Indicates a CDATA section event.

+

COMMENT

+

6

+

Indicates an XML comment event.

+

DOCDECL

+

7

+

Indicates an XML document type declaration event.

+

INSTRUCTION

+

8

+

Indicates an XML processing instruction event.

+

ENTITY_REFERENCE

+

9

+

Indicates an entity reference event.

+

WHITESPACE

+

10

+

Indicates a whitespace character event.

+
+ diff --git a/zh-cn/application-dev/background-task-management/Readme-CN.md b/zh-cn/application-dev/background-task-management/Readme-CN.md new file mode 100644 index 0000000000..36178f390b --- /dev/null +++ b/zh-cn/application-dev/background-task-management/Readme-CN.md @@ -0,0 +1,5 @@ +# 后台任务管理 + +- 后台任务 + - [后台任务概述](background-task-overview.md) + - [后台任务开发指导](background-task-dev-guide.md) \ No newline at end of file diff --git a/zh-cn/application-dev/background-task-management/background-task-overview.md b/zh-cn/application-dev/background-task-management/background-task-overview.md index f3cec92c41..5a4602a62b 100644 --- a/zh-cn/application-dev/background-task-management/background-task-overview.md +++ b/zh-cn/application-dev/background-task-management/background-task-overview.md @@ -1,4 +1,4 @@ -# 概述 +# 后台任务概述 对于有用户交互的OS来说,资源优先分配给与用户交互的业务进程,换句话说,在支撑OS运行的进程以外,用户能感知到的业务进程优先级最高,所以后台任务管理的范围是用户感知不到的业务进程。 diff --git a/zh-cn/application-dev/database/Readme-CN.md b/zh-cn/application-dev/database/Readme-CN.md index f6341aa680..c96d684813 100644 --- a/zh-cn/application-dev/database/Readme-CN.md +++ b/zh-cn/application-dev/database/Readme-CN.md @@ -1,4 +1,11 @@ -# 分布式数据服务 +# 数据管理 -- [分布式数据服务概述](database-mdds-overview.md) -- [分布式数据服务开发指导](database-mdds-guidelines.md) +- 分布式数据服务 + - [分布式数据服务概述](database-mdds-overview.md) + - [分布式数据服务开发指导](database-mdds-guidelines.md) +- 关系型数据库 + - [关系型数据库概述](database-relational-overview.md) + - [分布式数据服务开发指导](database-relational-guidelines.md) +- 轻量级数据存储 + - [轻量级数据存储概述](database-preference-overview.md) + - [轻量级数据存储开发指导](database-preference-guidelines.md) diff --git a/zh-cn/application-dev/database/database-preference-guidelines.md b/zh-cn/application-dev/database/database-preference-guidelines.md new file mode 100644 index 0000000000..93ae031327 --- /dev/null +++ b/zh-cn/application-dev/database/database-preference-guidelines.md @@ -0,0 +1,161 @@ +# 轻量级数据存储开发指导 + +## 场景介绍 + +轻量级数据存储功能通常用于保存应用的一些常用配置信息,并不适合需要存储大量数据和频繁改变数据的场景。应用的数据保存在文件中,这些文件可以持久化地存储在设备上。需要注意的是,应用访问的实例包含文件所有数据,这些数据会一直加载在设备的内存中,直到应用主动从内存中将其移除前,应用可以通过Storage的API进行数据操作。 + +## 接口说明 + +轻量级存储为应用提供key-value键值型的文件数据处理能力,支持应用对数据进行轻量级存储及查询。数据存储形式为键值对,键的类型为字符串型,值的存储数据类型包括数字型、字符型、布尔型。 + +**创建存储实例** + +读取指定文件,将数据加载到Storage实例,即可创建一个存储实例,用于数据操作。 + +**表1** 轻量级数据存储实例创建接口 + +| 包名 | 接口名 | 描述 | +| ----------------- | ------------------------------------------- | ------------------------------------------- | +| ohos.data.storage | getStorage(path: string): Promise\ | 获取文件对应的Storage单实例,用于数据操作。 | + +**存入数据** + +通过put系列方法,可以增加或修改Storage实例中的数据。 + +**表2** 轻量级数据存入接口 + +| 类名 | 接口名 | 描述 | +| ------- | -------------------------------------------------- | ----------------------------------------------- | +| Storage | put(key: string, value: ValueType): Promise\ | 支持值为number、string、boolean类型的数据存入。 | + +**读取数据** + +通过调用get系列方法,可以读取Storage中的数据。 + +**表3** 轻量级数据读取接口 + +| 类名 | 接口名 | 描述 | +| ------- | ---------------------------------------------------------- | ----------------------------------------------- | +| Storage | get(key: string, defValue: ValueType): Promise\ | 支持获取值为number、string、boolean类型的数据。 | + +**数据持久化** + +通过执行flush方法,应用可以将缓存的数据再次写回文本文件中进行持久化存储。 + +**表4** 轻量级数据持久化接口 + +| 类名 | 接口名 | 描述 | +| ------- | ----------------------- | --------------------------------------- | +| Storage | flush(): Promise\ | 将Storage实例通过异步线程回写入文件中。 | + +**订阅数据变化** + +订阅数据变化需要指定StorageObserver作为回调方法。订阅的key的值发生变更后,当执行flush方法时,StorageObserver被回调。 + +**表5** 轻量级数据变化订阅接口 + +| 类名 | 接口名 | 描述 | +| ------- | ------------------------------------------------------------ | -------------- | +| Storage | on(type: 'change', callback: Callback\): void | 订阅数据变化。 | +| Storage | off(type: 'change', callback: Callback\): void | 注销订阅。 | + +**删除数据文件** + +通过调用以下两种接口,可以删除数据实例或对应的文件。 + +**表6** 轻量级数据存储删除接口 + +| 包名 | 接口名 | 描述 | +| ----------------- | ---------------------------------------------------- | ------------------------------------------------------------ | +| ohos.data.storage | deleteStorage(path: string): Promise\ | 从缓存中移除已加载的Storage对象,同时从设备上删除对应的文件。 | +| ohos.data.storage | removeStorageFromCache(path: string): Promise\ | 仅从缓存中移除已加载的Storage对象,主要用于释放内存。 | + +## 开发步骤 + +1. 准备工作,导入@ohos.data.storage以及相关的模块到开发环境。 + + ``` + import dataStorage from '@ohos.data.storage' + import featureAbility from '@ohos.ability.featureAbility' // 用于获取文件存储路径 + ``` + +2. 获取Storage实例。 + + 读取指定文件,将数据加载到Storage实例,用于数据操作。 + ``` + var context = featureAbility.getContext() + var path = await context.getFilesDir() + let promise = dataStorage.getStorage(path + '/mystore') + ``` + +3. 存入数据。 + + 使用Storage put方法保存数据到缓存的实例中。 + + ``` + promise.then((storage) => { + let getPromise = storage.put('startup', 'auto') // 保存数据到缓存的storage示例中。 + getPromise.then(() => { + console.info("Put the value of startup successfully.") + }).catch((err) => { + console.info("Put the value of startup failed with err: " + err) + }) + }).catch((err) => { + console.info("Get the storage failed") + }) + ``` + +4. 读取数据。 + + 使用Storage get方法读取数据。 + + ``` + promise.then((storage) => { + let getPromise = storage.get('startup', 'default') + getPromise.then((value) => { + console.info("The value of startup is " + value) + }).catch((err) => { + console.info("Get the value of startup failed with err: " + err) + }) + }).catch((err) => { + console.info("Get the storage failed")}) + ``` + +5. 数据持久化。 + + 应用存入数据到Storage实例后,可以通过flush或者flushSync方法将Storage实例回写到文件中。 + + ``` + storage.flush(); + ``` + +6. 订阅数据变化。 + + 应用订阅数据变化需要指定StorageObserver作为回调方法。订阅的key的值发生变更后,当执行flush方法时,StorageObserver被触发回调。不再需要StorageObserver时请注销。 + + ``` + promise.then((storage) => { + var observer = function (key) { + console.info("The key of " + key + " changed.") + } + storage.on('change', observer) + storage.putSync('startup', 'auto') // 修改storage存储数据 + storage.flushSync() // 触发订阅者回调方法 + + storage.off('change', observer) // 注销数据变化订阅 + }).catch((err) => { + console.info("Get the storage failed") + }) + ``` + +7. 删除指定文件。 + + 使用deleteStorage方法从内存中移除指定文件对应的Storage单实例,并删除指定文件及其备份文件、损坏文件。删除指定文件时,应用不允许再使用该实例进行数据操作,否则会出现数据一致性问题。删除后,数据及文件将不可恢复。 + + ``` + let promise = dataStorage.deleteStorage(path + '/mystore') + promise.then(() => { + console.info("Deleted successfully.") + }).catch((err) => { + console.info("Deleted failed with err: " + err)}) + ``` \ No newline at end of file diff --git a/zh-cn/application-dev/database/database-preference-overview.md b/zh-cn/application-dev/database/database-preference-overview.md new file mode 100644 index 0000000000..b906e9423d --- /dev/null +++ b/zh-cn/application-dev/database/database-preference-overview.md @@ -0,0 +1,28 @@ +# 轻量级数据存储概述 + +轻量级数据存储适用于对Key-Value结构的数据进行存取和持久化操作。应用获取某个轻量级存储对象后,该存储对象中的数据将会被缓存在内存中,以便应用获得更快的数据存取速度。应用也可以将缓存的数据再次写回文本文件中进行持久化存储,由于文件读写将产生不可避免的系统资源开销,建议应用减少对持久化文件的读写频率。 + +## 基本概念 + +- **Key-Value数据结构** + + 一种键值结构数据类型。Key是不重复的关键字,Value是数据值。 + +- **非关系型数据库** + + 区别于关系数据库,不保证遵循ACID(Atomic、Consistency、Isolation及Durability)特性,不采用关系模型来组织数据,数据之间无关系。 + +## 运作机制 + +1. 应用通过指定Storage文件将其中的数据加载到Storage实例,系统会通过静态容器将该实例存储在内存中,同一应用或进程中每个文件仅存在一个Storage实例,直到应用主动从内存中移除该实例或者删除该Storage文件。 +2. 应用获取到Storage文件对应的实例后,可以从Storage实例中读取数据,或者将数据存入Storage实例中。通过调用flush或者flushSync方法可以将Storage实例中的数据回写到文件里。 + +**图1** 轻量级数据存储运作机制 + +![zh-cn_image_0000001199139454](figures/zh-cn_image_0000001199139454.png) + +## 约束与限制 + +- 因Storage实例会加载到内存中,建议存储的数据不超过一万条,并及时清理不再使用的实例,以便减少非内存开销。 +- 数据中的key为string类型,要求非空且字符长度不超过80个。 +- 当数据中的value为string类型时,允许为空,字符长度不超过8192个。 \ No newline at end of file diff --git a/zh-cn/application-dev/database/database-relational-guidelines.md b/zh-cn/application-dev/database/database-relational-guidelines.md new file mode 100644 index 0000000000..127fa0bae8 --- /dev/null +++ b/zh-cn/application-dev/database/database-relational-guidelines.md @@ -0,0 +1,200 @@ +# 关系型数据库开发指导 + +## 场景介绍 + +关系型数据库是在SQLite基础上实现的本地数据操作机制,提供给用户无需编写原生SQL语句就能进行数据增删改查的方法,同时也支持原生SQL语句操作。 + + +## 接口说明 + +**数据库的创建和删除** + +关系型数据库提供了数据库创建方式,以及对应的删除接口,涉及的API如下所示。 + +**表1** 数据库创建和删除API + +| 类名 | 接口名 | 描述 | +| -------- | -------- | -------- | +| dataRdb | getRdbStore(config: StoreConfig, version: number, callback: AsyncCallback<RdbStore>): void | 获得一个相关的RdbStore,操作关系型数据库,用户可以根据自己的需求配置RdbStore的参数,然后通过RdbStore调用相关接口可以执行相关的数据操作,结果以callback形式返回。
- config:与此RDB存储相关的数据库配置。
- version:数据库版本。
- callback:指定callback回调函数。返回一个RdbStore。 | +| dataRdb | getRdbStore(config: StoreConfig, version: number): Promise<RdbStore> | 获得一个相关的RdbStore,操作关系型数据库,用户可以根据自己的需求配置RdbStore的参数,然后通过RdbStore调用相关接口可以执行相关的数据操作,结果以Promise形式返回。
- config:与此RDB存储相关的数据库配置。
- version:数据库版本。 | +| dataRdb | deleteRdbStore(name: string, callback: AsyncCallback<void>): void | 删除数据库,结果以callback形式返回。
- name:数据库名称。
- callback:指定callback回调函数。如果数据库已删除,则为true;否则返回false。 | +| dataRdb | deleteRdbStore(name: string): Promise<void> | 使用指定的数据库文件配置删除数据库,结果以Promise形式返回。
- name:数据库名称。 | + +**数据库的增删改查** + +关系型数据库提供对本地数据增删改查操作的能力,相关API如下所示。 + +- **新增** + 关系型数据库提供了插入数据的接口,通过ValuesBucket输入要存储的数据,通过返回值判断是否插入成功,插入成功时返回最新插入数据所在的行号,失败时则返回-1。 + **表2** 数据库插入API + + | 类名 | 接口名 | 描述 | + | -------- | -------- | -------- | + | RdbStore | insert(name: string, values: ValuesBucket, callback: AsyncCallback<number>):void | 向目标表中插入一行数据,结果以callback形式返回。
- name:指定的目标表名。
- values:表示要插入到表中的数据行。
- callback:指定callback回调函数。如果操作成功,返回行ID;否则返回-1。 | + | RdbStore | insert(name: string, values: ValuesBucket): Promise<number> | 向目标表中插入一行数据,结果以Promise形式返回。
- name:指定的目标表名。
- values:表示要插入到表中的数据行。 | + +- **更新** + 调用更新接口,传入要更新的数据,并通过RdbPredicates指定更新条件。该接口的返回值表示更新操作影响的行数。如果更新失败,则返回0。 + + **表3** 数据库更新API + + | 类名 | 接口名 | 描述 | + | -------- | -------- | -------- | + | RdbStore | update(values: ValuesBucket, rdbPredicates: RdbPredicates, callback: AsyncCallback<number>):void | 根据RdbPredicates的指定实例对象更新数据库中的数据,结果以callback形式返回。
- values:以ValuesBucket存储的要更新的数据。
- rdbPredicates:表示RdbPredicates的实例对象指定的更新条件。
- callback:指定的callback回调方法。返回受影响的行数。 | + | RdbStore | update(values: ValuesBucket, rdbPredicates: RdbPredicates): Promise | 根据RdbPredicates的指定实例对象更新数据库中的数据,结果以Promise形式返回。
- values:以ValuesBucket存储的要更新的数据。
- rdbPredicates:表示RdbPredicates的实例对象指定的更新条件。 | + +- **删除** + 调用删除接口,通过RdbPredicates指定删除条件。该接口的返回值表示删除的数据行数,可根据此值判断是否删除成功。如果删除失败,则返回0。 + + **表4** 数据库删除API + + | 类名 | 接口名 | 描述 | + | -------- | -------- | -------- | + | RdbStore | delete(rdbPredicates: RdbPredicates, callback: AsyncCallback<number>):void | 根据rdbPredicates的指定实例对象从数据库中删除数据,结果以callback形式返回。
- rdbPredicates:RdbPredicates的实例对象指定的删除条件。
- callback:指定callback回调函数。返回受影响的行数。 | + | RdbStore | delete(rdbPredicates: RdbPredicates): Promise | 根据rdbPredicates的指定实例对象从数据库中删除数据,结果以Promise形式返回。
- rdbPredicates:RdbPredicates的实例对象指定的删除条件。 | + +- **查询** + 关系型数据库提供了两种查询数据的方式: + + - 直接调用查询接口。使用该接口,会将包含查询条件的谓词自动拼接成完整的SQL语句进行查询操作,无需用户传入原生的SQL语句。 + - 执行原生的SQL语句进行查询操作。 + + **表5** 数据库查询API + + | 类名 | 接口名 | 描述 | + | -------- | -------- | -------- | + | RdbStore | query(rdbPredicates: RdbPredicates, columns: Array, callback: AsyncCallback<ResultSet>): void | 根据指定条件查询数据库中的数据,结果以callback形式返回。
- rdbPredicates:表示RdbPredicates的实例对象指定的查询条件。
- columns:表示要查询的列。如果值为空,则查询应用于所有列。
- callback:指定callback回调函数。如果操作成功,则返回ResultSet对象。 | + | RdbStore | query(rdbPredicates: RdbPredicates, columns: Array): Promise<ResultSet> | 根据指定条件查询数据库中的数据,结果以Promise形式返回。
- rdbPredicates:表示RdbPredicates的实例对象指定的查询条件。
- columns:表示要查询的列。如果值为空,则查询应用于所有列。 | + | RdbStore | querySql(sql: string, bindArgs: Array<ValueType>, callback: AsyncCallback<ResultSet>):void | 根据指定SQL语句查询数据库中的数据,结果以callback形式返回。
- sql:指定要查询的SQL语句。
- bindArgs:SQL语句中参数的值。
- callback:指定callback回调函数。如果操作成功,则返回ResultSet对象。 | + | RdbStore | querySql(sql: string, bindArgs?: Array<ValueType>):Promise<ResultSet> | 根据指定SQL语句查询数据库中的数据,结果以Promise形式返回。
- sql:指定要查询的SQL语句。
- bindArgs:SQL语句中参数的值。 | + +**数据库谓词的使用** + +关系型数据库提供了用于设置数据库操作条件的谓词RdbPredicates,该类确定RDB中条件表达式的值是true还是false。 + +**表6** 数据库谓词API + +| 类名 | 接口名 | 描述 | +| -------- | -------- | -------- | +| RdbPredicates | equalTo(field: string, value: ValueType): RdbPredicates | 配置谓词以匹配数据字段为ValueType且值等于指定值的字段。
- field:数据库表中的列名。
- value:指示要与谓词匹配的值。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | notEqualTo(field: string, value: ValueType): RdbPredicates | 配置谓词以匹配数据字段为ValueType且值不等于指定值的字段。
- field:数据库表中的列名。
- value:指示要与谓词匹配的值。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | beginWrap(): RdbPredicates | 向谓词添加左括号。
- RdbPredicates:返回带有左括号的谓词。 | +| RdbPredicates | endWrap(): RdbPredicates | 向谓词添加右括号。
- RdbPredicates:返回带有右括号的谓词。 | +| RdbPredicates | or(): RdbPredicates | 将或条件添加到谓词中。
- RdbPredicates:返回带有或条件的谓词。 | +| RdbPredicates | and(): RdbPredicates | 向谓词添加和条件。
- RdbPredicates:返回带有和条件的谓词。 | +| RdbPredicates | contains(field: string, value: string): RdbPredicats | 配置谓词以匹配数据字段为String且value包含指定值的字段。
- field:数据库表中的列名。
- value:指示要与谓词匹配的值。
- RdbPredicates:返回带有包含条件的谓词。 | +| RdbPredicates | beginsWith(field: string, value: string): RdbPredicates | 配置谓词以匹配数据字段为String且值以指定字符串开头的字段。
- field:数据库表中的列名。
- value:指示要与谓词匹配的值。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | endsWith(field: string, value: string): RdbPredicates | 配置谓词以匹配数据字段为String且值以指定字符串结尾的字段。
- field:数据库表中的列名。
- value:指示要与谓词匹配的值。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | isNull(field: string): RdbPredicates | 配置谓词以匹配值为null的字段。
- field:数据库表中的列名。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | isNotNull(field: string): RdbPredicates | 配置谓词以匹配值不为null的指定字段。
- field:数据库表中的列名。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | like(field: string, value: string): RdbPredicates | 配置谓词以匹配数据字段为String且值类似于指定字符串的字段。
- field:数据库表中的列名。
- value:指示要与谓词匹配的值。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | glob(field: string, value: string): RdbPredicates | 配置RdbPredicates匹配数据字段为String的指定字段。
- field:数据库表中的列名。
- value:指示要与谓词匹配的值。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | between(field: string, low: ValueType, high: ValueType): RdbPredicates | 将谓词配置为匹配数据字段为ValueType且value在给定范围内的指定字段。
- field:数据库表中的列名。
- low:指示与谓词匹配的最小值。
- high:指示与谓词匹配的最大值。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | notBetween(field: string, low: ValueType, high: ValueType): RdbPredicates | 配置RdbPredicates以匹配数据字段为ValueType且value超出给定范围的指定字段。
- field:数据库表中的列名。
- low:指示与谓词匹配的最小值。
- high:指示与谓词匹配的最大值。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | greaterThan(field: string, value: ValueType): RdbPredicatesgr | 配置谓词以匹配数据字段为ValueType且值大于指定值的字段。
- field:数据库表中的列名。
- value:指示要与谓词匹配的值。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | lessThan(field: string, value: ValueType): RdbPredicates | 配置谓词以匹配数据字段为valueType且value小于指定值的字段。
- field:数据库表中的列名。
- value:指示要与谓词匹配的值。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | greaterThanOrEqualTo(field: string, value: ValueType): RdbPredicates | 配置谓词以匹配数据字段为ValueType且value大于或等于指定值的字段。
- field:数据库表中的列名。
- value:指示要与谓词匹配的值。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | lessThanOrEqualTo(field: string, value: ValueType): RdbPredicates | 配置谓词以匹配数据字段为ValueType且value小于或等于指定值的字段。
- field:数据库表中的列名。
- value:指示要与谓词匹配的值。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | orderByAsc(field: string): RdbPredicates | 配置谓词以匹配其值按升序排序的列。
- field:数据库表中的列名。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | orderByDesc(field: string): RdbPredicates | 配置谓词以匹配其值按降序排序的列。
- field:数据库表中的列名。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | distinct(): RdbPredicates | 配置谓词以过滤重复记录并仅保留其中一个。
- RdbPredicates:返回可用于过滤重复记录的谓词。 | +| RdbPredicates | limitAs(value: number): RdbPredicates | 设置最大数据记录数的谓词。
- value:最大数据记录数。
- RdbPredicates:返回可用于设置最大数据记录数的谓词。 | +| RdbPredicates | offsetAs(rowOffset: number): RdbPredicates | 配置RdbPredicates以指定返回结果的起始位置。
- rowOffset:返回结果的起始位置,取值为正整数。
- RdbPredicates:返回具有指定返回结果起始位置的谓词。 | +| RdbPredicates | groupBy(fields: Array<string>): RdbPredicates | 配置RdbPredicates按指定列分组查询结果。
- fields:指定分组依赖的列名。
- RdbPredicates:返回分组查询列的谓词。 | +| RdbPredicates | indexedBy(indexName: string): RdbPredicates | 配置RdbPredicates以指定索引列。
- indexName:索引列的名称。
- RdbPredicates:返回具有指定索引列的RdbPredicates。 | +| RdbPredicates | in(field: string, value: Array<ValueType>): RdbPredicates | 配置RdbPredicates以匹配数据字段为ValueType数组且值在给定范围内的指定字段。
- field:数据库表中的列名。
- value:以ValueType型数组形式指定的要匹配的值。
- RdbPredicates:返回与指定字段匹配的谓词。 | +| RdbPredicates | notIn(field: string, value: Array<ValueType>): RdbPredicates | 将RdbPredicates配置为匹配数据字段为ValueType且值超出给定范围的指定字段。
- field:数据库表中的列名。
- value:以ValueType型数组形式指定的要匹配的值。
- RdbPredicates:返回与指定字段匹配的谓词。 | + +**查询结果集的使用** + +关系型数据库提供了查询返回的结果集ResultSet,其指向查询结果中的一行数据,供用户对查询结果进行遍历和访问。ResultSet对外API如下所示。 + +> ![icon-notice.gif](public_sys-resources/icon-notice.gif) **须知:** +> **注:结果集使用完后,请一定要调用close方法显式关闭。** + +**表7** 结果集API + +| 类名 | 接口名 | 描述 | +| -------- | -------- | -------- | +| ResultSet | goTo(offset:number): boolean | 从结果集当前位置移动指定偏移量。 | +| ResultSet | goToRow(position: number): boolean | 将结果集移动到指定位置。 | +| ResultSet | goToNextRow(): boolean | 将结果集向后移动一行。 | +| ResultSet | goToPreviousRow(): boolean | 将结果集向前移动一行。 | +| ResultSet | getColumnIndex(columnName: string): number | 根据指定的列名获取列索引。 | +| ResultSet | getColumnName(columnIndex: number): string | 根据指定的列索引获取列名。 | +| ResultSet | goToFirstRow(): boolean | 判断结果集当前位置是否在第一行。 | +| ResultSet | goToLastRow(): boolean | 判断结果集当前位置是否在最后一行。 | +| ResultSet | getString(columnIndex: number): string | 获取当前行指定列的值,以String类型返回。 | +| ResultSet | getBlob(columnIndex: number): Uint8Array | 获取当前行指定列的值,以字节数组形式返回。 | +| ResultSet | getDouble(columnIndex: number): number | 获取当前行指定列的值,以double型返回。 | +| ResultSet | isColumnNull(columnIndex: number): boolean | 检查当前行中指定列的值是否为null。 | +| ResultSet | close(): void | 关闭结果集。 | + +**数据库更改秘钥** + +用户可以对当前数据库进行加密。 + +数据库的加密仅限于初始使用一个数据库时就进行加密,使用过程中进行秘钥的变更,但不支持取消秘钥。 + +数据库初始时为加密库,则一直为加密库;初始时为未加密库,则一直为未加密库。 + +**表8** 数据库更改秘钥 + +| 类名 | 接口名 | 描述 | +| -------- | -------- | -------- | +| RdbStore | changeEncryptKey(newEncryptKey:Uint8Array, callback: AsyncCallback<number>):void; | 数据库更改秘钥接口,通过callback 可以异步处理返回结果。返回结果0成功,非0失败。 | +| RdbStore | changeEncryptKey(newEncryptKey:Uint8Array): Promise<number>; | 数据库更改秘钥接口,通过await 可以同步处理返回结果。返回结果0成功,非0失败。 | + + +## 开发步骤 + +1. 创建数据库。 + 1. 配置数据库相关信息,包括数据库的名称、存储模式、是否为只读模式等。 + 2. 初始化数据库表结构和相关数据。 + 3. 创建数据库。 + + 示例代码如下: + + ``` + import dataRdb from '@ohos.data.rdb'; + + const CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test (" + "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, " + "age INTEGER, " + "salary REAL, " + "blobType BLOB)"; + const STORE_CONFIG = {name: "rdbstore.db",} + + let rdbStore = await dataRdb.getRdbStore(STORE_CONFIG, 1); + await rdbStore.executeSql(CREATE_TABLE_TEST); + ``` + +2. 插入数据。 + 1. 构造要插入的数据,以ValuesBucket形式存储。 + 2. 调用关系型数据库提供的插入接口。 + + 示例代码如下: + + ``` + var u8 = new Uint8Array([1, 2, 3]) + const valueBucket = {"name": "Tom", "age": 18, "salary": 100.5, "blobType": u8,} + let insertPromise = rdbStore.insert("test", valueBucket) + ``` + +3. 查询数据。 + 1. 构造用于查询的谓词对象,设置查询条件。 + 2. 调用查询接口查询数据。 + 3. 调用结果集接口,返回查询结果。 + + 示例代码如下: + + ``` + let predicates = new dataRdb.RdbPredicates("test"); + predicates.equalTo("name", "Tom") + let resultSet = await rdbStore.query(predicates) + + resultSet.goToFirstRow() + const id = await resultSet.getLong(resultSet.getColumnIndex("id")) + const name = await resultSet.getString(resultSet.getColumnIndex("name")) + const age = await resultSet.getLong(resultSet.getColumnIndex("age")) + const salary = await resultSet.getDouble(resultSet.getColumnIndex("salary")) + const blobType = await resultSet.getBlob(resultSet.getColumnIndex("blobType")) + + resultSet.close() + ``` diff --git a/zh-cn/application-dev/database/database-relational-overview.md b/zh-cn/application-dev/database/database-relational-overview.md new file mode 100644 index 0000000000..f9a84f85a0 --- /dev/null +++ b/zh-cn/application-dev/database/database-relational-overview.md @@ -0,0 +1,41 @@ +# 关系型数据库概述 + +关系型数据库(Relational Database,RDB)是一种基于关系模型来管理数据的数据库。关系型数据库基于SQLite组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满足复杂的场景需要。 + +## 基本概念 + +- **关系型数据库** + + 基于关系模型来管理数据的数据库,以行和列的形式存储数据。 + +- **谓词** + + 数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。 + +- **结果集** + + 指用户查询之后的结果集合,可以对数据进行访问。结果集提供了灵活的数据访问方式,可以更方便的拿到用户想要的数据。 + +- **SQLite数据库** + + 一款遵守ACID的轻型开源关系型数据库管理系统。 + +## 运作机制 + +关系型数据库对外提供通用的操作接口,底层使用SQLite作为持久化存储引擎,支持SQLite具有的所有数据库特性,包括但不限于事务、索引、视图、触发器、外键、参数化查询和预编译SQL语句。 + +**图1** 关系型数据库运作机制 + +![how-rdb-works](figures/how-rdb-works.png) + +## 默认配置 + +- 如果不指定数据库的日志模式,那么系统默认日志方式是WAL(Write Ahead Log)模式。 +- 如果不指定数据库的落盘模式,那么系统默认落盘方式是FULL模式。 +- OpenHarmony数据库使用的共享内存默认大小是2MB。 + +## 约束与限制 + +- 数据库中连接池的最大数量是4个,用以管理用户的读操作。 + +- 为保证数据的准确性,数据库同一时间只能支持一个写操作。 \ No newline at end of file diff --git a/zh-cn/application-dev/database/figures/how-rdb-works.png b/zh-cn/application-dev/database/figures/how-rdb-works.png new file mode 100644 index 0000000000000000000000000000000000000000..e85411eef39281e3213d6b4697a8d32d2cecd9a2 GIT binary patch literal 21260 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