Preferences
Today, as the mobile Internet is booming, mobile applications have brought great convenience to our lives. The essence of these conveniences lies in the interconnection of data. Therefore, data storage plays a very important role in application development, and HarmonyOS application development is no exception. This chapter takes the preferences of HarmonyOS as an example to introduce the data management capabilities of HarmonyOS.
What are preferences
Preferences provide applications with Key-Value
key-value data storage capabilities, allowing applications to persist lightweight data and add, delete, modify, and query data. Thedata in this storage object will be cached in memory so it can be accessed faster.
The characteristics of preferences are as follows:
-
Data stored in Key-Value format: Data is stored in the form of key-value pairs, where Key is the unique keyword and the corresponding Value is the actual data value.
-
Non-relational database: Unlike relational databases, preferences do not follow ACID properties (Atomicity, Consistency, Isolation, Durability), and there is no relationship between data.
-
Unique instance in process: Only one instance of a preference exists per file within a process. After the application obtains the instance, it can read data from it or store data in it. By calling the flush method, the data in the instance can be written back to the file.
-
Differences from relational databases:
Characteristics/properties Relational database Preferences Data storage format Table (relational) Key-Value (non-relational) ACID properties td> Follow ACID Do not follow ACID Data relationship There is an association between data tables No data relationship, independent Key-Value pairs Storage engine Use database engine, such as SQLite, etc. Stored in file Usage scene Complex scene Local database management under Perform simple operations on the data of Key-Value structure Data processing Complex query, transaction processing, etc. Simple access and persistence operations Restraints and limitations Connection pool size, number of simultaneous write operations, etc. Recommended number of data entries, Key type restrictions
Common interfaces for preferences
Interface | Function |
---|---|
< strong>put | Store data into preferences |
get | Get the data value in the preference through the specified Key |
has | Check whether the given Key is included in the preferences |
delete | Delete the data of the specified Key from the preferences |
flush | Write the data in the preferences back to the file to achieve data persistence |
Before use, you need to import the
@ohos.data.preferences
module, name the instance dataPreferences, and define two constants PREFERENCES_NAME and KEY_APP_FONT_SIZE.
// PreferencesUtil.ets import dataPreferences from '@ohos.data.preferences'; ... const PREFERENCES_NAME = 'myPreferences'; // Preference name const KEY_APP_FONT_SIZE = 'appFontSize'; // Preference Key field
It is necessary to obtain the preference instance in the
onCreate
method of entryAbility so that subsequent operations such as saving, reading, and deleting can be performed. Obtaining the instance requires context and file name PREFERENCES_NAME.
// entryAbility.ets onCreate(want, launchParam) {<!-- --> Logger.info(TAG, 'onCreate'); globalThis.abilityWant = want; //Create preferences PreferencesUtil.createFontPreferences(this.context); ... } // PreferencesUtil.ets createFontPreferences(context) {<!-- --> globalThis.getFontPreferences = (() => {<!-- --> // Get preference instance let preferences: Promise<dataPreferences.Preferences> = dataPreferences.getPreferences(context, PREFERENCES_NAME); return preferences; }); } </code><img class="look-more-preCode contentImg-no-view" src="//i2.wp.com/csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreBlack. png" alt="" title="">
Save data
In the onCreate method of entryAbility, call PreferencesUtil.saveDefaultFontSize to save the default data. First use the has method to determine whether the current key exists. If not, use the put method to save the user data. This method saves the key-value pair as a constant. KEY_APP_FONT_SIZE is used as key, user data fontSize is used as value, and then the data is saved to the file through the flush method.
// entryAbility.ets onCreate(want, launchParam) {<!-- --> Logger.info(TAG, 'onCreate'); globalThis.abilityWant = want; ... //Set the default font size PreferencesUtil.saveDefaultFontSize(Constants.SET_SIZE_STANDARD); } // PreferencesUtil.ets saveDefaultFontSize(fontSize: number) {<!-- --> globalThis.getFontPreferences().then((preferences) => {<!-- --> // Determine whether the saved key exists preferences.has(KEY_APP_FONT_SIZE).then(async (isExist) => {<!-- --> Logger.info(TAG, 'preferences has changeFontSize is ' + isExist); if (!isExist) {<!-- --> // save data await preferences.put(KEY_APP_FONT_SIZE, fontSize); preferences.flush(); } }).catch((err) => {<!-- --> Logger.error(TAG, 'Has the value failed with err: ' + err); }); }).catch((err) => {<!-- --> Logger.error(TAG, 'Get the preferences failed, err: ' + err); }); } </code><img class="look-more-preCode contentImg-no-view" src="//i2.wp.com/csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreBlack. png" alt="" title="">
Get data
In the onPageShow method of HomePage, call the PreferencesUtil.getChangeFontSize method to obtain user data, and call the get method to obtain it. This method reads through key-value pairs, with the constant KEY_APP_FONT_SIZE as the key, the default data fontSize as the value, and assigns the result. Give the variable fontSize and return the value through return.
// HomePage.ets onPageShow() {<!-- --> PreferencesUtil.getChangeFontSize().then((value) => {<!-- --> this.changeFontSize = value; Logger.info(TAG, 'Get the value of changeFontSize: ' + this.changeFontSize); }); } // PreferencesUtil.ets async getChangeFontSize() {<!-- --> let fontSize: number = 0; const preferences = await globalThis.getFontPreferences(); fontSize = await preferences.get(KEY_APP_FONT_SIZE, fontSize); return fontSize; }
Whether it contains the specified key
Use the has method to determine whether the preference contains the specified key to ensure that the specified key will not be saved repeatedly.
// PreferencesUtil.ets saveDefaultFontSize(fontSize: number) {<!-- --> globalThis.getFontPreferences().then((preferences) => {<!-- --> // Determine whether the saved key exists preferences.has(KEY_APP_FONT_SIZE).then(async (isExist) => {<!-- --> Logger.info(TAG, 'preferences has changeFontSize is ' + isExist); }).catch((err) => {<!-- --> Logger.error(TAG, 'Has the value failed with err: ' + err); }); }).catch((err) => {<!-- --> Logger.error(TAG, 'Get the preferences failed, err: ' + err); }); }
Data persistence
Use the flush method to save application data to files to extend the retention period of application data.
// PreferencesUtil.ets saveChangeFontSize(fontSize: number) {<!-- --> globalThis.getFontPreferences().then(async (preferences) => {<!-- --> // save data await preferences.put(KEY_APP_FONT_SIZE, fontSize); //Data persistence preferences.flush(); }).catch((err) => {<!-- --> Logger.error(TAG, 'put the preferences failed, err: ' + err); }); }
Delete data
To delete preference data, you need to obtain the preferences instance, use the delete method to delete the value corresponding to the specified key, and use the constant KEY_APP_FONT_SIZE as the key. Use the Promise asynchronous callback to determine whether the deletion is successful.
// PreferencesUtil.ets async deleteChangeFontSize() {<!-- --> const preferences: dataPreferences.Preferences = await globalThis.getFontPreferences(); // delete data let deleteValue = preferences.delete(KEY_APP_FONT_SIZE); deleteValue.then(() => {<!-- --> Logger.info(TAG, 'Succeeded in deleting the key appFontSize.'); }).catch((err) => {<!-- --> Logger.error(TAG, 'Failed to delete the key appFontSize. Cause: ' + err); }); }
Background notification management
The role of notification
Notifications are designed to allow users to get timely and useful new information in an appropriate way, helping users handle tasks efficiently. The application can send notification messages through the notification interface. The user can view the notification content through the notification bar, or click on the notification to open the application. The main usage scenarios of notifications are as follows:
- Display received short messages, instant messages, etc.
- Display application push messages, such as advertisements, version updates, etc.
- Displays currently ongoing events, such as downloads, etc.
Notifications will prompt users in different forms in different scenarios. For example, notifications will be displayed as icons on the status bar and notification details will be displayed on the notification bar. Important information can also be displayed as banner notifications floating at the top of the interface.
Create notification
This section will introduce the creation of several common types of notifications. Before creating notifications, you need to import the notificationManager
module. This module provides notification management capabilities, including publishing and unpublishing notifications, creation, acquisition, and removal. Notification channels and other capabilities.
import notification from '@ohos.notificationManager';
Basic type notification
Basic type notifications are mainly used to send short messages, prompt messages, advertising push, etc., and support normal text types, Long text type, Multiline text type and Image type, you can specify the content type of the notification through contentType
.
To publish a normal text type notification, you need to set the contentType to
ContentType.NOTIFICATION_CONTENT_BASIC_TEXT
.
import notification from '@ohos.notificationManager'; @Entry @Component struct NotificationDemo {<!-- --> publishNotification() {<!-- --> let notificationRequest: notification.NotificationRequest = {<!-- --> // Describe the notification request id: 1, // notification ID slotType: notification.SlotType.SERVICE_INFORMATION, content: {<!-- --> // Notification content contentType: notification.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // Ordinary text type notification normal: {<!-- --> // Basic type notification content title: 'Notification content title', text: 'Notification content details', additionalText: 'Notification additional content', // Notification additional content is a supplement to the notification content. } } } notification.publish(notificationRequest).then(() => {<!-- --> // Publish notification console.info('publish success'); }).catch((err) => {<!-- --> console.error(`publish failed, dcode:${<!-- -->err.code}, message:${<!-- -->err.message}`); }); } build() {<!-- --> Column() {<!-- --> Button('Send notification') .onClick(() => {<!-- --> this.publishNotification() }) } .width('100%') } } </code><img class="look-more-preCode contentImg-no-view" src="//i2.wp.com/csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreBlack. png" alt="" title="">
Parameter name | Function |
---|---|
notificationRequest |
Describes the request object of the notification, including various information of the notification. |
id |
The unique identifier of the notification, use To distinguish between different notifications. |
slotType |
The slot type of the notification, specify the notification in the notification bar. |
content |
Object containing notification content, specified The type and specific content of the notification. |
contentType |
Specify the content type of the notification, for example Normal text, long text, pictures, etc. |
normal |
Contains the details of normal text type notifications Content information. |
title |
The title of the ordinary text type notification. |
text |
Details of ordinary text type notifications . |
additionalText |
Additional content for ordinary text type notifications , a supplementary explanation of the content of the notice. |
publish |
notification.publish method, used to publish notifications. |
then |
Promise’s success callback, used for The action to perform after the notification is published successfully. |
catch |
Promise’s failure callback, used for Handle error conditions when notification publishing fails. |
onClick |
Button click event handler, Used to trigger a notification publishing action when the button is clicked. |
Publish image type notification
To publish a normal text type notification, you need to set the contentType to
ContentType.NOTIFICATION_CONTENT_PICTURE
.
import notification from '@ohos.notificationManager'; import image from '@ohos.multimedia.image'; @Entry @Component struct NotificationTest1 {<!-- --> async publishPictureNotification() {<!-- --> // Convert resource images into PixelMap objects let resourceManager = getContext(this).resourceManager; let imageArray = await resourceManager.getMediaContent($r('app.media.bigPicture').id); let imageResource = image.createImageSource(imageArray.buffer); let pixelMap = await imageResource.createPixelMap(); let notificationRequest: notification.NotificationRequest = {<!-- --> // Describe the notification request id: 1, content: {<!-- --> contentType: notification.ContentType.NOTIFICATION_CONTENT_PICTURE, picture: {<!-- --> title: 'Good things are on sale', // Notification content title text: 'Expand to view details', // Notification content expandedTitle: 'Today's Hot Recommendations', // Content title when the notification is expanded briefText: 'There must be something you like here', // The summary content of the notification is a summary of the content of the notification picture: pixelMap // Picture content of notification } } } notification.publish(notificationRequest).then(() => {<!-- --> // Publish notification console.info('publish success'); }).catch((err) => {<!-- --> console.error(`publish failed, dcode:${<!-- -->err.code}, message:${<!-- -->err.message}`); }); } build() {<!-- --> Column() {<!-- --> Button('Send large image notification') .onClick(() => {<!-- --> this.publishPictureNotification() }) } .width('100%') } } </code><img class="look-more-preCode contentImg-no-view" src="//i2.wp.com/csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreBlack. png" alt="" title="">
Parameter name | Function |
---|---|
notificationRequest |
Describes the request object of the notification, including various information of the notification. |
id |
The unique identifier of the notification, used to distinguish different notifications. |
content |
An object containing notification content, specifying the type and specific content of the notification. |
contentType |
Specify the content type of the notification, such as pictures, normal text, long text wait. |
picture |
Contains specific content information of the picture type notification. |
title |
The title of the picture type notification. |
text |
Details of the image type notification. |
expandedTitle |
The content title when the image type notification is expanded. |
briefText |
The summary content of the image type notification, a summary of the notification content. |
picture |
The picture content of the picture type notification. |
pixelMap |
Notified image content, through pixel map (pixelMap ) means. |
publish |
notification.publish method, used Post a notice. |
then |
Promise’s success callback, used to execute after the notification is released successfully. operate. |
catch |
Promise’s failure callback, used to handle errors when notification publishing fails Condition. |
onClick |
Button click event handler, used to trigger when the button is clicked Notification publishing operation. |
Progress type notification
Progress bar notifications are also a common type of notifications and are mainly used to display the progress of file download and transaction processing. Currently, the system template only supports progress bar templates.
-
Before publishing a progress type notification, you need to check whether the system supports the progress bar template.
notification.isSupportTemplate('downloadTemplate').then((data) => {<!-- --> console.info(`[ANS] isSupportTemplate success`); let isSupportTpl: boolean = data; // The value of isSupportTpl is true to indicate that the downloadTemplate template class notification is supported, and false to indicate that it is not supported. // ... }).catch((err) => {<!-- --> console.error(`[ANS] isSupportTemplate failed, error[${<!-- -->err}]`); });
-
Construct a progress bar template. The name field currently needs to be configured as downloadTemplate.
let template = {<!-- --> name: 'downloadTemplate', data: {<!-- --> progressValue: 60, // current progress value progressMaxValue: 100 // Maximum progress value } } let notificationRequest = {<!-- --> id: 1, content: {<!-- --> contentType: notification.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, normal: {<!-- --> title: 'File download: music.mp4', text: 'senTemplate', additionalText: '60%' } }, template: template } // Publish notification notification.publish(notificationRequest).then(() => {<!-- --> console.info(`publish success`); }).catch(error => {<!-- --> console.error(`[ANS] publish failed, code is ${<!-- -->error.code}, message is ${<!-- -->error.message}`); }) </code><img class="look-more-preCode contentImg-no-view" src="//i2.wp.com/csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreBlack. png" alt="" title="">
Update notification
After sending the notification, call notification.publish again using the same notification ID you used before to update the notification. If the previous notification was closed, a new notification will be created.
Removal notification
//Cancel a published notification by notification ID notification.cancel(notificationId) // Cancel all published notifications notification.cancelAll()
Notification channel
Through the notification channel, you can let notifications have different presentation forms. For example, social notifications are displayed with banners and have prompt sounds, while general notifications are not displayed with banners. You can use slotType
to fulfill.
Notification channel type | Show notification icon | Show banner | Beep sound | Applicable scenarios |
---|---|---|---|---|
SlotType.SOCIAL_COMMUNICATION | Yes | Yes | Yes | Social applications, such as messaging, social media, etc., require users to pay attention and respond in a timely manner. |
SlotType.SERVICE_INFORMATION | Yes | No | Yes | Service applications, such as background service status, system information, etc., do not require overly conspicuous prompts. |
SlotType.CONTENT_INFORMATION | Yes | No | No | Content-related applications, such as news, article updates, etc., users are more concerned about the content of notifications rather than timely responses. |
SlotType.OTHER_TYPES | No | No | No | There is no need to display the icon in the status bar, and the notification content does not need to attract the user’s attention. |
Backend agent reminder
This section describes the basic operations of using background agent reminder (reminderAgentManager
) to add, publish, delete and modify reminders in HarmonyOS applications.
There are mainly the following types of background agent reminders:
- Countdown
- calendar
- Alarm clock
Add usage rights
"module": {<!-- --> ... "requestPermissions": [ {<!-- --> "name": "ohos.permission.PUBLISH_AGENT_REMINDER" } ] }
Added permission to use background proxy reminders in the application’s module
configuration.
Import reminderAgent module
import reminderAgent from '@ohos.reminderAgentManager';
Import the background agent reminder module through the @ohos.reminderAgentManager
module and name it reminderAgent
.
Add reminder
export class ReminderService {<!-- --> public addReminder(alarmItem: ReminderItem, callback?: (reminderId: number) => void) {<!-- --> let reminder = this.initReminder(alarmItem); reminderAgent.publishReminder(reminder, (err, reminderId) => {<!-- --> if (callback != null) {<!-- --> callback(reminderId); } }); } }
Use the reminderAgent.publishReminder
method to publish a new reminder. The specific information of the reminder is defined by the ReminderRequestAlarm
type.
Delete Reminder
export class ReminderService {<!-- --> public deleteReminder(reminderId: number) {<!-- --> reminderAgent.cancelReminder(reminderId); } }
Use the reminderAgent.cancelReminder
method to delete a reminder with the specified reminderId
.
Modification reminder
public async setAlarmRemind(alarmItem: AlarmItem) {<!-- --> let index = await this.findAlarmWithId(alarmItem.id); if (index !== Constants.DEFAULT_NUMBER_NEGATIVE) {<!-- --> this.reminderService.deleteReminder(alarmItem.id); } else {<!-- --> // Process logic for adding new reminders } this.reminderService.addReminder(alarmItem, (newId) => {<!-- --> alarmItem.id = newId; // Logic for handling new reminders }) }
When modifying a reminder, first call the deleteReminder
method to delete the old reminder, and then call the addReminder
method to add a new reminder.