* Copyright (c) Huawei Technologies Co., Ltd. 2024-2025. All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Settings from '@ohos.settings';
import dataShare from '@ohos.data.dataShare';
import taskpool from '@ohos.taskpool';
import type common from '@ohos.app.ability.common';
import osAccount from '@ohos.account.osAccount';
import type { AsyncCallback, BusinessError } from '@ohos.base';
import { LogUtil } from './LogUtil';
import { CheckEmptyUtils } from './CheckEmptyUtils';
import { StringUtil } from './StringUtil';
import { AbilityContextManager } from '../ability/AbilityContextManager';
import dataSharePredicates from '@ohos.data.dataSharePredicates';
import DataShareResultSet from '@ohos.data.DataShareResultSet';
const TAG = 'SettingsDataUtils : ';
export interface queryDataListParm {
userId : number,
key : string,
defaultValue : string,
length : number
}
function getValueSync(key: string, defaultValue: string, domain: string, context: common.Context): string {
'use concurrent';
if (domain) {
return Settings.getValueSync(context, key, defaultValue ?? '', domain);
}
return Settings.getValueSync(context, key, defaultValue ?? '');
}
function setValueSync(key: string, value: string, domain: string, context: common.Context): void {
'use concurrent';
if (domain) {
Settings.setValueSync(context, key, value ?? '', domain);
}
Settings.setValueSync(context, key, value ?? '');
}
* 设置数据库工具类
*
* @since 2022-06-29
*/
export class SettingsDataUtils {
public static readonly settingsDataUrl = 'datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true&key=';
public static readonly settingsDataUserUrl = 'datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_';
public static readonly settingsDataUserSecurityUrl = 'datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_';
static getSettingsData(key: string, defaultValue: string, domain: string = null): string {
if (StringUtil.isEmpty(key)) {
LogUtil.warn(`${TAG} getSettingsData ${key} invalid`);
return '';
}
let context: common.Context | undefined = SettingsDataUtils.getContext();
if (CheckEmptyUtils.isEmpty(context)) {
LogUtil.error(`${TAG} getSettingsData ${key} failed, context is undefined`);
return defaultValue ?? '';
}
try {
if (domain) {
return Settings.getValueSync(context, key, defaultValue ?? '', domain);
}
return Settings.getValueSync(context, key, defaultValue ?? '');
} catch (error) {
LogUtil.error(`${TAG} getValueSync ${key} failed, ${error?.message}`);
}
return defaultValue ?? '';
}
static getSettingsDataWithContext(context: common.Context, key: string, defaultValue: string,
domain: string = null): string {
if (StringUtil.isEmpty(key)) {
LogUtil.warn(`${TAG} getSettingsData ${key} invalid`);
return '';
}
if (CheckEmptyUtils.isEmpty(context)) {
LogUtil.error(`${TAG} getSettingsData ${key} failed, context is undefined`);
return defaultValue ?? '';
}
if (domain) {
return Settings.getValueSync(context, key, defaultValue ?? '', domain);
}
return Settings.getValueSync(context, key, defaultValue ?? '');
}
private static getDataShareResultSetCallback(queryDataListParm : queryDataListParm,
resultValueMaps : Map<number, Map<string, string>>,
callback: (valueMaps: Map<string, string>) => void) : AsyncCallback<DataShareResultSet> {
try {
const dataShareResultSetCallback : AsyncCallback<DataShareResultSet> = (dataShareResultSetErr : BusinessError,
dataShareResultSet: DataShareResultSet) => {
if (dataShareResultSetErr) {
LogUtil.error(`${TAG} dataShareResultSet fail`);
return;
}
const index = 0;
dataShareResultSet.goToRow(index);
let targetString: string = dataShareResultSet.getString(index) ?? queryDataListParm.defaultValue;
LogUtil.info(`userId:${queryDataListParm.userId} get ${queryDataListParm.key} : ${targetString}`);
resultValueMaps.get(queryDataListParm.userId)?.set(queryDataListParm.key, targetString);
if (resultValueMaps.get(queryDataListParm.userId)?.size === queryDataListParm.length) {
callback(resultValueMaps.get(queryDataListParm.userId));
}
const isDataShareClosed: boolean = dataShareResultSet.isClosed;
if (!isDataShareClosed) {
LogUtil.info(`${TAG} close dataShareHelper`);
dataShareResultSet.close();
}
};
return dataShareResultSetCallback;
} catch (e) {
LogUtil.error(`${TAG} getDataShareResultSetCallback error: ${(e as BusinessError).code}`);
callback(resultValueMaps.get(queryDataListParm.userId));
return null;
}
}
public static getSettingsDataWithUserId(context: Context, userId: number, defaultData : Map<string, string>,
callback: (valueMaps: Map<string, string>) => void): void {
LogUtil.error(`${TAG} getSettingsDataWithUserId start`);
const uri = SettingsDataUtils.settingsDataUserSecurityUrl + userId + '?Proxy=true';
let resultValueMaps = new Map<number, Map<string, string>>();
resultValueMaps.set(userId, new Map<string, string>());
try {
const createDataShareHelperCallBack : AsyncCallback<dataShare.DataShareHelper> =
(err, dataShareHelper: dataShare.DataShareHelper) => {
if (err) {
LogUtil.error(`${TAG} dataShareGetValue err.message:${err.message} err.code:${err.code}`);
return;
}
for (let [key, defaultValue] of defaultData) {
const predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates();
const SETTING_COLUMN_KEYWORD = 'KEYWORD';
predicates.equalTo(SETTING_COLUMN_KEYWORD, key);
const columns = ['VALUE'];
const queryDataListParm : queryDataListParm = {
userId : userId,
key : key,
defaultValue : defaultValue,
length : defaultData.size
};
const dataShareResultSetCallback : AsyncCallback<DataShareResultSet> =
SettingsDataUtils.getDataShareResultSetCallback(queryDataListParm, resultValueMaps, callback);
dataShareHelper.query(uri, predicates, columns, dataShareResultSetCallback);
}
};
if (createDataShareHelperCallBack === null) {
callback(resultValueMaps.get(userId));
return;
}
dataShare.createDataShareHelper(context, uri, createDataShareHelperCallBack);
} catch (e) {
callback(resultValueMaps.get(userId));
LogUtil.error(`${TAG} getSettingsDataWithUserId error: ${(e as BusinessError).code}`);
}
}
static getSecureValue(key: string, defaultValue: string): string {
return SettingsDataUtils.getSettingsData(key, defaultValue, Settings.domainName.USER_SECURITY);
}
static async getSettingsDataAsync(key: string, defaultValue: string, domain: string = null): Promise<string> {
if (!key) {
LogUtil.warn(`${TAG} getSettingsDataAsync ${key} invalid`);
return '';
}
let context: common.Context | undefined = SettingsDataUtils.getContext();
if (CheckEmptyUtils.isEmpty(context)) {
LogUtil.error(`${TAG} getSettingsData ${key} failed, context is undefined`);
return defaultValue ?? '';
}
return String(await SettingsDataUtils.doTask(getValueSync, key, defaultValue, domain));
}
static setSettingsData(key: string, value: string, domain: string = null): boolean {
if (StringUtil.isEmpty(key)) {
LogUtil.warn(`${TAG} setSettingsData ${key} invalid`);
return false;
}
let context: common.Context | undefined = SettingsDataUtils.getContext();
if (CheckEmptyUtils.isEmpty(context)) {
LogUtil.error(`${TAG} setSettingsData ${key} failed, context is undefined`);
return false;
}
LogUtil.info(`${TAG} setSettingsData key: ${key}---${value}----${domain}`);
try {
if (domain) {
return Settings.setValueSync(context, key, value ?? '', domain);
} else {
return Settings.setValueSync(context, key, value ?? '');
}
} catch (e) {
LogUtil.error(`${TAG} setSettingsData ${key} error: ${e?.code}`);
return false;
}
}
static setSettingsDataAsync(key: string, value: string, domain: string = null): void {
if (StringUtil.isEmpty(key)) {
LogUtil.warn(`${TAG} setSettingsDataAsync ${key} invalid`);
return;
}
SettingsDataUtils.setSettingsDataAsyncWithContext(SettingsDataUtils.getContext(), key, value ?? '', domain);
}
static setSettingsDataAsyncWithContext(context: common.Context, key: string, value: string,
domain: string = null): void {
if (StringUtil.isEmpty(key)) {
LogUtil.warn(`${TAG} setValue ${key} invalid`);
return;
}
if (CheckEmptyUtils.isEmpty(context)) {
LogUtil.warn(`${TAG} setValue ${key} context invalid`);
return;
}
LogUtil.info(`${TAG} setSettingsDataAsync key: ${key}, value: ${value}`);
if (domain) {
Settings.setValue(context, key, value ?? '', domain);
} else {
Settings.setValue(context, key, value ?? '');
}
}
static setSecureValue(key: string, value: string): void {
SettingsDataUtils.setSettingsData(key, value, Settings.domainName.USER_SECURITY);
}
static setSettingsDataDomain(key: string, value: string, domainName: string): void {
SettingsDataUtils.setSettingsData(key, value, domainName);
}
static getSettingsDataDomain(key: string, defaultValue: string, domainName: string): string {
return SettingsDataUtils.getSettingsData(key, defaultValue, domainName);
}
static registerKeyObserver(key: string, observer: AsyncCallback<void>): boolean {
try {
return Settings.registerKeyObserver(SettingsDataUtils.getContext(), key,
Settings.domainName.DEVICE_SHARED, observer);
} catch (e) {
LogUtil.warn(`${TAG} Settings ${key} registerKeyObserver err`);
return false;
}
}
static unregisterKeyObserver(key: string): boolean {
return Settings.unregisterKeyObserver(SettingsDataUtils.getContext(), key, Settings.domainName.DEVICE_SHARED);
}
static registerKeyObserverUser(key: string, observer: AsyncCallback<void>): boolean {
try {
return Settings.registerKeyObserver(SettingsDataUtils.getContext(), key,
Settings.domainName.USER_PROPERTY, observer);
} catch (e) {
LogUtil.warn(`${TAG} Settings ${key} registerKeyObserver err`);
return false;
}
}
static unregisterKeyObserverUser(key: string): boolean {
return Settings.unregisterKeyObserver(SettingsDataUtils.getContext(), key, Settings.domainName.USER_PROPERTY);
}
static registerKeyObserverWithDomain(key: string, domainName: string, observer: AsyncCallback<void>): boolean {
return Settings.registerKeyObserver(SettingsDataUtils.getContext(), key, domainName, observer);
}
static unregisterKeyObserverWithDomain(key: string, domainName: string): boolean {
return Settings.unregisterKeyObserver(SettingsDataUtils.getContext(), key, domainName);
}
static registerKeyObserverWithDomainAndContext(context: common.Context, key: string, domainName: string,
observer: AsyncCallback<void>): boolean {
if (CheckEmptyUtils.isEmpty(context)) {
LogUtil.error(`${TAG} registerKeyObserverWithDomainAndContext ${key} failed, context is undefined`);
return false;
}
return Settings.registerKeyObserver(context, key, domainName, observer);
}
static unregisterKeyObserverWithDomainAndContext(context: common.Context, key: string, domainName: string): boolean {
if (CheckEmptyUtils.isEmpty(context)) {
LogUtil.error(`${TAG} unregisterKeyObserverWithDomainAndContext ${key} failed, context is undefined`);
return false;
}
return Settings.unregisterKeyObserver(context, key, domainName);
}
static getSupport(key: string, value: string): void {
SettingsDataUtils.setSettingsData(key, value);
}
static getSettingsUri(key: string): string {
if (!key) {
LogUtil.warn(TAG + 'getSettingsUri key invalid');
return '';
}
return SettingsDataUtils.settingsDataUrl + key;
}
static async getSettingsSecurityUri(key: string): Promise<string> {
try {
let accountManager: osAccount.AccountManager = osAccount.getAccountManager();
let id: number = await accountManager.getOsAccountLocalId();
let url =
`datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_${id}?Proxy=true&key=${key}`;
return url;
} catch (err) {
LogUtil.error(`${TAG} key: ${key} getOsAccountLocalId fail: ${err?.code}`);
return '';
}
}
static async getSettingsUserUri(key: string): Promise<string> {
try {
let accountManager: osAccount.AccountManager = osAccount.getAccountManager();
let id: number = await accountManager.getOsAccountLocalId();
let url: string = `${SettingsDataUtils.settingsDataUserUrl}${id}?Proxy=true&key=${key}`;
return url;
} catch (err) {
LogUtil.error(`${TAG} getOsAccountLocalId ${key} fail: ${err?.code}`);
return '';
}
}
static registerDataChange(dataHelper: dataShare.DataShareHelper, key: string, onDataChange: () => void): void {
if (!dataHelper || !onDataChange) {
LogUtil.warn(TAG + `registerDataChange ${key} params invalid`);
return;
}
let uri = this.getSettingsUri(key);
if (!uri) {
LogUtil.error(TAG + `registerDataChange ${key} uri invalid`);
return;
}
dataHelper.on('dataChange', uri, onDataChange);
}
static unRegisterDataChange(dataHelper: dataShare.DataShareHelper, key: string, offDataChange?: () => void): void {
if (!dataHelper) {
LogUtil.warn(TAG + `unRegisterDataChange ${key} params invalid`);
return;
}
let uri = this.getSettingsUri(key);
if (!uri) {
LogUtil.error(TAG + `unRegisterDataChange ${key} uri invalid`);
return;
}
if (offDataChange) {
dataHelper.off('dataChange', uri, offDataChange);
} else {
dataHelper.off('dataChange', uri);
}
}
static async createSecurityDataHelper(key: string): Promise<dataShare.DataShareHelper> | undefined {
let uri = await this.getSettingsSecurityUri(key);
if (!uri) {
LogUtil.error(TAG + `createDataHelper ${key} uri invalid`);
return undefined;
}
let pageContext: common.Context | undefined = SettingsDataUtils.getContext();
if (pageContext !== undefined) {
return dataShare.createDataShareHelper(pageContext, uri);
}
return undefined;
}
static registerSecurityDataChange(dataHelper: dataShare.DataShareHelper, key: string,
onDataChange: () => void): Promise<void> {
if (!dataHelper || !onDataChange) {
LogUtil.warn(`${TAG} registerDataChange ${key} params invalid`);
return;
}
this.getSettingsSecurityUri(key)
.then((uri) => {
dataHelper.on('dataChange', uri, onDataChange);
});
}
static unRegisterSecurityDataChange(dataHelper: dataShare.DataShareHelper, key: string,
offDataChange?: () => void): Promise<void> {
if (!dataHelper) {
LogUtil.warn(`${TAG} unRegisterSecurityDataChange ${key} params invalid`);
return;
}
this.getSettingsSecurityUri(key)
.then((uri) => {
if (offDataChange) {
dataHelper.off('dataChange', uri, offDataChange);
} else {
dataHelper.off('dataChange', uri);
}
});
}
static registerUserDataChange(dataHelper: dataShare.DataShareHelper, key: string, onDataChange: () => void): void {
if (!dataHelper || !onDataChange) {
LogUtil.warn(`${TAG} registerDataChange ${key} params invalid`);
return;
}
this.getSettingsUserUri(key)
.then((uri) => {
dataHelper.on('dataChange', uri, onDataChange);
});
}
static unRegisterUserDataChange(dataHelper: dataShare.DataShareHelper, key: string,
offDataChange?: () => void): void {
if (!dataHelper) {
LogUtil.warn(`${TAG} unRegisterSecurityDataChange ${key} params invalid`);
return;
}
this.getSettingsUserUri(key)
.then((uri) => {
if (offDataChange) {
dataHelper.off('dataChange', uri, offDataChange);
} else {
dataHelper.off('dataChange', uri);
}
});
}
static createDataHelper(key: string): Promise<dataShare.DataShareHelper> | undefined {
let uri = this.getSettingsUri(key);
if (!uri) {
LogUtil.error(TAG + `createDataHelper ${key} uri invalid`);
return undefined;
}
let pageContext: common.Context | undefined = SettingsDataUtils.getContext();
if (pageContext !== undefined) {
return dataShare.createDataShareHelper(pageContext, uri);
}
return undefined;
}
private static async doTask(func: Function, ...args: unknown[]): Promise<unknown> {
try {
let context: common.Context = SettingsDataUtils.getContext();
args.push(context);
const dbTask = new taskpool.Task(func, ...args);
return await taskpool.execute(dbTask);
} catch (err) {
LogUtil.showError(TAG, `doTask error when execute ${func.name}, ${err?.message}`);
}
return undefined;
}
public static getContext(): common.Context {
let context = AbilityContextManager.getContext();
if (CheckEmptyUtils.isEmpty(context)) {
context = AbilityContextManager.getExtContext();
}
if (CheckEmptyUtils.isEmpty(context)) {
context = AbilityContextManager.getBackgroundIntentContext();
}
if (CheckEmptyUtils.isEmpty(context)) {
context = AbilityContextManager.getStageContext();
LogUtil.showWarn(TAG, `get stage context`);
}
return context;
}
static setSettingsDataWithContext(context: common.Context, key: string, value: string, domain: string = null): void {
if (StringUtil.isEmpty(key) || !context) {
LogUtil.warn(`${TAG} setSettingsDataWithContext ${key} invalid or context is empty`);
return;
}
LogUtil.info(`${TAG} setSettingsDataWithContext key: ${key}`);
if (domain) {
Settings.setValueSync(context, key, value ?? '', domain);
} else {
Settings.setValueSync(context, key, value ?? '');
}
}
}