# Eç±»åŠ å¯†æ•°æ®åº“的使用 ## åœºæ™¯ä»‹ç» ä¸ºäº†æ»¡è¶³æ•°æ®åº“的安全特性,å˜æœ‰æ•æ„Ÿä¿¡æ¯çš„应用会在[EL5](../reference/apis-ability-kit/js-apis-app-ability-contextConstant.md#areamode)ï¼ˆåŠ å¯†è·¯å¾„åˆ‡æ¢è¯·å‚考[获å–å’Œä¿®æ”¹åŠ å¯†åˆ†åŒº](../application-models/application-context-stage.md#获å–å’Œä¿®æ”¹åŠ å¯†åˆ†åŒº)EL1-EL4路径切æ¢ï¼‰è·¯å¾„下创建了一个E类数æ®åº“。在é”å±çš„情况下,满足一定æ¡ä»¶æ—¶ï¼Œä¼šè§¦å‘密钥的销æ¯ï¼Œæ¤æ—¶E类数æ®åº“ä¸å¯è¯»å†™ã€‚当é”å±è§£é”åŽï¼Œå¯†é’¥ä¼šæ¢å¤ï¼ŒE类数æ®åº“æ¢å¤æ£å¸¸è¯»å†™æ“ä½œã€‚è¿™æ ·çš„è®¾è®¡å¯ä»¥æœ‰æ•ˆé˜²æ¢ç”¨æˆ·æ•°æ®çš„泄露。 然而,在é”å±çš„情况下,应用程åºä»ç„¶å¯ä»¥ç»§ç»å†™å…¥æ•°æ®ï¼Œç”±äºŽæ¤æ—¶E类数æ®åº“ä¸å¯è¯»å†™ï¼Œå¯èƒ½ä¼šå¯¼è‡´æ•°æ®ä¸¢å¤±ã€‚为了解决这个问题,当å‰æ供了一ç§æ–¹æ¡ˆï¼šåœ¨é”å±çš„情况下,将数æ®å˜å‚¨åœ¨[EL2](../reference/apis-ability-kit/js-apis-app-ability-contextConstant.md#areamode)路径下的C类数æ®åº“ä¸ã€‚当解é”åŽï¼Œå†å°†æ•°æ®è¿ç§»åˆ°E类数æ®åº“ä¸ã€‚è¿™æ ·å¯ä»¥ç¡®ä¿æ•°æ®åœ¨é”å±æœŸé—´çš„安全性和完整性。 键值型数æ®åº“和关系型数æ®åº“å‡æ”¯æŒEç±»åŠ å¯†æ•°æ®åº“。 ## 实现机制 通过å°è£…Moverç±»ã€Storeç±»ã€SecretKeyObserver类和ECStoreManager类实现应用数æ®åº“å¯†é’¥åŠ é”和解é”状æ€ä¸‹E类数æ®åº“å’ŒC类数æ®åº“的切æ¢å’Œæ“作。 Mover类:æ供数æ®åº“æ•°æ®è¿ç§»æŽ¥å£ï¼Œåœ¨é”å±è§£é”åŽï¼Œè‹¥C类数æ®åº“ä¸æœ‰æ•°æ®ï¼Œä½¿ç”¨è¯¥æŽ¥å£å°†æ•°æ®è¿ç§»åˆ°E类数æ®åº“。 Store类:æ供了获å–æ•°æ®åº“,在数æ®åº“ä¸æ’入数æ®ã€åˆ 除数æ®ã€æ›´æ–°æ•°æ®å’ŒèŽ·å–当å‰æ•°æ®æ•°é‡çš„接å£ã€‚ SecretKeyObserver类:æ供了获å–当å‰å¯†é’¥çŠ¶æ€çš„接å£ï¼Œåœ¨å¯†é’¥é”€æ¯åŽï¼Œå…³é—E类数æ®åº“。 ECStoreManager类:用于管ç†åº”用的E类数æ®åº“å’ŒC类数æ®åº“。 ## é…ç½®æƒé™ 使用EL5路径下的数æ®åº“,需è¦é…ç½®ohos.permission.PROTECT_SCREEN_LOCK_DATAæƒé™ã€‚ ```ts // module.json5 "requestPermissions": [ { "name": "ohos.permission.PROTECT_SCREEN_LOCK_DATA" } ] ``` ## 键值型数æ®åº“Eç±»åŠ å¯† æœ¬ç« èŠ‚æ供键值型数æ®åº“çš„Eç±»åŠ å¯†æ•°æ®åº“使用方å¼ï¼Œæä¾›[Mover](#mover)ç±»ã€[Store](#store)ç±»ã€[SecretKeyObserver](#secretkeyobserver)类和[ECStoreManager](#ecstoremanager)类的具体实现,并在[EntryAbility](#entryability)å’Œ[index按键事件](#index按键事件)ä¸å±•ç¤ºè¿™å‡ 个类的使用方å¼ã€‚ ### Mover æ供数æ®åº“æ•°æ®è¿ç§»æŽ¥å£ï¼Œåœ¨é”å±è§£é”åŽï¼Œè‹¥C类数æ®åº“ä¸å˜åœ¨æ•°æ®ï¼Œä½¿ç”¨è¯¥æŽ¥å£å°†æ•°æ®è¿ç§»åˆ°E类数æ®åº“。 ```ts // Mover.ts import { distributedKVStore } from '@kit.ArkData'; export class Mover { async move(eStore: distributedKVStore.SingleKVStore, cStore: distributedKVStore.SingleKVStore): Promise<void> { if (eStore != null && cStore != null) { let entries: distributedKVStore.Entry[] = await cStore.getEntries('key_test_string'); await eStore.putBatch(entries); console.info(`ECDB_Encry move success`); } } } ``` ### Store æ供了获å–æ•°æ®åº“,在数æ®åº“ä¸æ’入数æ®ã€åˆ 除数æ®ã€æ›´æ–°æ•°æ®å’ŒèŽ·å–当å‰æ•°æ®æ•°é‡çš„接å£ã€‚ ```ts // Store.ts import { distributedKVStore } from '@kit.ArkData'; import { BusinessError } from '@kit.BasicServicesKit'; let kvManager: distributedKVStore.KVManager; export class StoreInfo { kvManagerConfig: distributedKVStore.KVManagerConfig; storeId: string; option: distributedKVStore.Options; } export class Store { async getECStore(storeInfo: StoreInfo): Promise<distributedKVStore.SingleKVStore> { try { kvManager = distributedKVStore.createKVManager(storeInfo.kvManagerConfig); console.info("Succeeded in creating KVManager"); } catch (e) { let error = e as BusinessError; console.error(`Failed to create KVManager.code is ${error.code},message is ${error.message}`); } if (kvManager !== undefined) { kvManager = kvManager as distributedKVStore.KVManager; let kvStore: distributedKVStore.SingleKVStore | null; try { kvStore = await kvManager.getKVStore<distributedKVStore.SingleKVStore>(storeInfo.storeId, storeInfo.option); if (kvStore != undefined) { console.info(`ECDB_Encry succeeded in getting store : ${storeInfo.storeId}`); return kvStore; } } catch (e) { let error = e as BusinessError; console.error(`An unexpected error occurred.code is ${error.code},message is ${error.message}`); } } } putOnedata(kvStore: distributedKVStore.SingleKVStore): void { if (kvStore != undefined) { const KEY_TEST_STRING_ELEMENT = 'key_test_string' + String(Date.now()); const VALUE_TEST_STRING_ELEMENT = 'value_test_string' + String(Date.now()); try { kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => { if (err !== undefined) { console.error(`Failed to put data. Code:${err.code},message:${err.message}`); return; } console.info(`ECDB_Encry Succeeded in putting data.${KEY_TEST_STRING_ELEMENT}`); }); } catch (e) { let error = e as BusinessError; console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); } } } getDataNum(kvStore: distributedKVStore.SingleKVStore): void { if (kvStore != undefined) { let resultSet: distributedKVStore.KVStoreResultSet; kvStore.getResultSet("key_test_string").then((result: distributedKVStore.KVStoreResultSet) => { console.info(`ECDB_Encry Succeeded in getting result set num ${result.getCount()}`); resultSet = result; if (kvStore != null) { kvStore.closeResultSet(resultSet).then(() => { console.info('Succeeded in closing result set'); }).catch((err: BusinessError) => { console.error(`Failed to close resultset.code is ${err.code},message is ${err.message}`); }); } }).catch((err: BusinessError) => { console.error(`Failed to get resultset.code is ${err.code},message is ${err.message}`); }); } } deleteOnedata(kvStore: distributedKVStore.SingleKVStore): void { if (kvStore != undefined) { kvStore.getEntries('key_test_string', (err: BusinessError, entries: distributedKVStore.Entry[]) => { if (err != undefined) { console.error(`Failed to get Entries.code is ${err.code},message is ${err.message}`); return; } if (kvStore != null && entries.length != 0) { kvStore.delete(entries[0].key, (err: BusinessError) => { if (err != undefined) { console.error(`Failed to delete.code is ${err.code},message is ${err.message}`); return; } console.info('ECDB_Encry Succeeded in deleting'); }); } }); } } updataOnedata(kvStore: distributedKVStore.SingleKVStore): void { if (kvStore != undefined) { kvStore.getEntries('key_test_string', async (err: BusinessError, entries: distributedKVStore.Entry[]) => { if (err != undefined) { console.error(`Failed to get Entries.code is ${err.code},message is ${err.message}`); return; } if (kvStore != null && entries.length != 0) { console.info(`ECDB_Encry old data:${entries[0].key},value :${entries[0].value.value.toString()}`) await kvStore.put(entries[0].key, "new value_test_string" + String(Date.now()) + 'new').then(() => { }).catch((err: BusinessError) => { console.error(`Failed to put.code is ${err.code},message is ${err.message}`); }); } console.info(`ECDB_Encry updata success`) }); } } } ``` ### SecretKeyObserver 该类æ供了获å–当å‰å¯†é’¥çŠ¶æ€çš„接å£ï¼Œåœ¨å¯†é’¥é”€æ¯åŽï¼Œå…³é—E类数æ®åº“。 ```ts // SecretKeyObserver.ts import { ECStoreManager } from './ECStoreManager'; export enum SecretStatus { Lock, UnLock } export class SecretKeyObserver { onLock(): void { this.lockStatuas = SecretStatus.Lock; this.storeManager.closeEStore(); } onUnLock(): void { this.lockStatuas = SecretStatus.UnLock; } getCurrentStatus(): number { return this.lockStatuas; } initialize(storeManager: ECStoreManager): void { this.storeManager = storeManager; } updatalockStatus(code: number) { if (code === SecretStatus.Lock) { this.onLock(); } else { this.lockStatuas = code; } } // åˆå§‹èŽ·å–é”å±çŠ¶æ€ private lockStatuas: number = SecretStatus.UnLock; private storeManager: ECStoreManager; } export let lockObserve = new SecretKeyObserver(); ``` ### ECStoreManager ECStoreManager类用于管ç†åº”用的E类数æ®åº“å’ŒC类数æ®åº“。支æŒé…置数æ®åº“ä¿¡æ¯ã€é…ç½®è¿ç§»å‡½æ•°çš„ä¿¡æ¯ï¼Œå¯æ ¹æ®å¯†é’¥çŠ¶æ€ä¸ºåº”用æ供相应的数æ®åº“å¥æŸ„,并æ供了关é—E类数æ®åº“ã€æ•°æ®è¿ç§»å®ŒæˆåŽé”€æ¯C类数æ®åº“ç‰æŽ¥å£ã€‚ ```ts // ECStoreManager.ts import { distributedKVStore } from '@kit.ArkData'; import { Mover } from './Mover'; import { BusinessError } from '@kit.BasicServicesKit'; import { StoreInfo, Store } from './Store'; import { SecretStatus } from './SecretKeyObserver'; let store = new Store(); export class ECStoreManager { config(cInfo: StoreInfo, other: StoreInfo): void { this.cInfo = cInfo; this.eInfo = other; } configDataMover(mover: Mover): void { this.mover = mover; } async getCurrentStore(screanStatus: number): Promise<distributedKVStore.SingleKVStore> { console.info(`ECDB_Encry GetCurrentStore start screanStatus: ${screanStatus}`); if (screanStatus === SecretStatus.UnLock) { try { this.eStore = await store.getECStore(this.eInfo); } catch (e) { let error = e as BusinessError; console.error(`Failed to GetECStore.code is ${error.code},message is ${error.message}`); } // 解é”çŠ¶æ€ èŽ·å–e类库 if (this.needMove) { if (this.eStore != undefined && this.cStore != undefined) { await this.mover.move(this.eStore, this.cStore); } this.deleteCStore(); console.info(`ECDB_Encry Data migration is complete. Destroy cstore`); this.needMove = false; } return this.eStore; } else { // åŠ é”çŠ¶æ€ èŽ·å–c类库 this.needMove = true; try { this.cStore = await store.getECStore(this.cInfo); } catch (e) { let error = e as BusinessError; console.error(`Failed to GetECStore.code is ${error.code},message is ${error.message}`); } return this.cStore; } } closeEStore(): void { try { let kvManager = distributedKVStore.createKVManager(this.eInfo.kvManagerConfig); console.info("Succeeded in creating KVManager"); if (kvManager != undefined) { kvManager.closeKVStore(this.eInfo.kvManagerConfig.bundleName, this.eInfo.storeId); this.eStore = null; console.info(`ECDB_Encry close EStore success`) } } catch (e) { let error = e as BusinessError; console.error(`Failed to create KVManager.code is ${error.code},message is ${error.message}`); } } deleteCStore(): void { try { let kvManager = distributedKVStore.createKVManager(this.cInfo.kvManagerConfig); console.info("Succeeded in creating KVManager"); if (kvManager != undefined) { kvManager.deleteKVStore(this.cInfo.kvManagerConfig.bundleName, this.cInfo.storeId); this.cStore = null; console.info("ECDB_Encry delete cStore success"); } } catch (e) { let error = e as BusinessError; console.error(`Failed to create KVManager.code is ${error.code},message is ${error.message}`); } } private eStore: distributedKVStore.SingleKVStore = null; private cStore: distributedKVStore.SingleKVStore = null; private cInfo: StoreInfo | null = null; private eInfo: StoreInfo | null = null; private needMove: boolean = false; private mover: Mover | null = null; } ``` ### EntryAbility 模拟应用å¯åŠ¨æœŸé—´ï¼Œæ³¨å†Œå¯¹COMMON_EVENT_SCREEN_LOCK_FILE_ACCESS_STATE_CHANGED公共事件的监å¬ï¼Œå¹¶é…置相应的数æ®åº“ä¿¡æ¯ã€å¯†é’¥çŠ¶æ€ä¿¡æ¯ç‰ã€‚ ```ts // EntryAbility.ets import { AbilityConstant, contextConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; import { distributedKVStore } from '@kit.ArkData'; import { ECStoreManager } from './ECStoreManager'; import { StoreInfo } from './Store'; import { Mover } from './Mover'; import { SecretKeyObserver } from './SecretKeyObserver'; import { commonEventManager } from '@kit.BasicServicesKit'; import { BusinessError } from '@kit.BasicServicesKit'; export let storeManager = new ECStoreManager(); export let e_secretKeyObserver = new SecretKeyObserver(); let mover = new Mover(); let subscriber: commonEventManager.CommonEventSubscriber; export function createCB(err: BusinessError, commonEventSubscriber: commonEventManager.CommonEventSubscriber) { if (!err) { console.info('ECDB_Encry createSubscriber'); subscriber = commonEventSubscriber; try { commonEventManager.subscribe(subscriber, (err: BusinessError, data: commonEventManager.CommonEventData) => { if (err) { console.error(`subscribe failed, code is ${err.code}, message is ${err.message}`); } else { console.info(`ECDB_Encry SubscribeCB ${data.code}`); e_secretKeyObserver.updatalockStatus(data.code); } }); } catch (error) { const err: BusinessError = error as BusinessError; console.error(`subscribe failed, code is ${err.code}, message is ${err.message}`); } } else { console.error(`createSubscriber failed, code is ${err.code}, message is ${err.message}`); } } let cInfo: StoreInfo | null = null; let eInfo: StoreInfo | null = null; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); let cContext = this.context; cInfo = { "kvManagerConfig": { context: cContext, bundleName: 'com.example.ecstoredemo', }, "storeId": "cstore", "option": { createIfMissing: true, encrypt: false, backup: false, autoSync: false, // kvStoreTypeä¸å¡«æ—¶ï¼Œé»˜è®¤åˆ›å»ºå¤šè®¾å¤‡ååŒæ•°æ®åº“ kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION, // 多设备ååŒæ•°æ®åº“:kvStoreType: distributedKVStore.KVStoreType.DEVICE_COLLABORATION, securityLevel: distributedKVStore.SecurityLevel.S3 } } let eContext = this.context.createModuleContext("entry"); eContext.area = contextConstant.AreaMode.EL5; eInfo = { "kvManagerConfig": { context: eContext, bundleName: 'com.example.ecstoredemo', }, "storeId": "estore", "option": { createIfMissing: true, encrypt: false, backup: false, autoSync: false, // kvStoreTypeä¸å¡«æ—¶ï¼Œé»˜è®¤åˆ›å»ºå¤šè®¾å¤‡ååŒæ•°æ®åº“ kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION, // 多设备ååŒæ•°æ®åº“:kvStoreType: distributedKVStore.KVStoreType.DEVICE_COLLABORATION, securityLevel: distributedKVStore.SecurityLevel.S3 } } console.info(`ECDB_Encry store area : estore:${eContext.area},cstore${cContext.area}`); // 监å¬COMMON_EVENT_SCREEN_LOCK_FILE_ACCESS_STATE_CHANGED事件 code == 1解é”状æ€ï¼Œcode==0åŠ é”çŠ¶æ€ try { commonEventManager.createSubscriber({ events: ['COMMON_EVENT_SCREEN_LOCK_FILE_ACCESS_STATE_CHANGED'] }, createCB); console.info(`ECDB_Encry success subscribe`); } catch (error) { const err: BusinessError = error as BusinessError; console.error(`createSubscriber failed, code is ${err.code}, message is ${err.message}`); } storeManager.config(cInfo, eInfo); storeManager.configDataMover(mover); e_secretKeyObserver.initialize(storeManager); } onDestroy(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); } onWindowStageCreate(windowStage: window.WindowStage): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); windowStage.loadContent('pages/Index', (err) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); }); } onWindowStageDestroy(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); } onForeground(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); } onBackground(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); } } ``` ### Index按键事件 使用Button按钮,通过点击按钮æ¥æ¨¡æ‹Ÿåº”用æ“作数æ®åº“,如æ’入数æ®ã€åˆ 除数æ®ã€æ›´æ–°æ•°æ®å’ŒèŽ·å–æ•°æ®æ•°é‡çš„æ“作ç‰ï¼Œå±•ç¤ºæ•°æ®åº“åŸºæœ¬çš„å¢žåˆ æ”¹æŸ¥èƒ½åŠ›ã€‚ ```ts // Index.ets import { storeManager, e_secretKeyObserver } from "../entryability/EntryAbility"; import { distributedKVStore } from '@kit.ArkData'; import { Store } from '../entryability/Store'; let storeOption = new Store(); let lockStatus: number = 1; @Entry @Component struct Index { @State message: string = 'Hello World'; build() { Row() { Column() { Button('åŠ é”/解é”').onClick((event: ClickEvent) => { if (lockStatus) { e_secretKeyObserver.onLock(); lockStatus = 0; } else { e_secretKeyObserver.onUnLock(); lockStatus = 1; } lockStatus ? this.message = "解é”" : this.message = "åŠ é”"; }).margin("5"); Button('store type').onClick(async (event: ClickEvent) => { e_secretKeyObserver.getCurrentStatus() ? this.message = "estroe" : this.message = "cstore"; }).margin("5"); Button("put").onClick(async (event: ClickEvent) => { let store: distributedKVStore.SingleKVStore = await storeManager.getCurrentStore(e_secretKeyObserver.getCurrentStatus()); storeOption.putOnedata(store); }).margin(5) Button("Get").onClick(async (event: ClickEvent) => { let store: distributedKVStore.SingleKVStore = await storeManager.getCurrentStore(e_secretKeyObserver.getCurrentStatus()); storeOption.getDataNum(store); }).margin(5) Button("delete").onClick(async (event: ClickEvent) => { let store: distributedKVStore.SingleKVStore = await storeManager.getCurrentStore(e_secretKeyObserver.getCurrentStatus()); storeOption.deleteOnedata(store); }).margin(5) Button("updata").onClick(async (event: ClickEvent) => { let store: distributedKVStore.SingleKVStore = await storeManager.getCurrentStore(e_secretKeyObserver.getCurrentStatus()); storeOption.updataOnedata(store); }).margin(5) Text(this.message) .fontSize(50) .fontWeight(FontWeight.Bold) } .width('100%') } .height('100%') } } ``` ## 关系型数æ®åº“Eç±»åŠ å¯† æœ¬ç« èŠ‚æ供关系型数æ®åº“çš„Eç±»åŠ å¯†æ•°æ®åº“使用方å¼ï¼Œæä¾›[Mover](#mover-1)类,[Store](#store-1)类,[SecretKeyObserver](#secretkeyobserver-1)类和[ECStoreManager](#ecstoremanager-1)类的具体实现,并在[EntryAbility](#entryability-1)å’Œ[index按键事件](#index按键事件-1)ä¸å±•ç¤ºè¿™å‡ 个类的使用方å¼ã€‚ ### Mover æ供数æ®åº“æ•°æ®è¿ç§»æŽ¥å£ï¼Œåœ¨é”å±è§£é”åŽï¼Œè‹¥C类数æ®åº“ä¸æœ‰æ•°æ®ï¼Œä½¿ç”¨è¯¥æŽ¥å£å°†æ•°æ®è¿ç§»åˆ°E类数æ®åº“。 ```ts // Mover.ts import { relationalStore } from '@kit.ArkData'; export class Mover { async move(eStore: relationalStore.RdbStore, cStore: relationalStore.RdbStore) { if (eStore != null && cStore != null) { let predicates = new relationalStore.RdbPredicates('employee'); let resultSet = await cStore.query(predicates); while (resultSet.goToNextRow()) { let bucket = resultSet.getRow(); await eStore.insert('employee', bucket); } } } } ``` ### Store æ供了获å–æ•°æ®åº“,在数æ®åº“ä¸æ’入数æ®ã€åˆ 除数æ®ã€æ›´æ–°æ•°æ®å’ŒèŽ·å–当å‰æ•°æ®æ•°é‡çš„接å£ã€‚å…¶ä¸StoreInfo类用于å˜å‚¨èŽ·å–æ•°æ®åº“相关信æ¯ã€‚ ```ts // Store.ts import { relationalStore } from '@kit.ArkData'; import { BusinessError } from '@kit.BasicServicesKit'; import { Context } from '@kit.AbilityKit'; export class StoreInfo { context: Context; config: relationalStore.StoreConfig; storeId: string; } let id = 1; const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS EMPLOYEE (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, AGE INTEGER, SALARY REAL, CODES BLOB)'; export class Store { async getECStore(storeInfo: StoreInfo): Promise<relationalStore.RdbStore> { let rdbStore: relationalStore.RdbStore | null; try { rdbStore = await relationalStore.getRdbStore(storeInfo.context, storeInfo.config); if (rdbStore.version == 0) { await rdbStore.executeSql(SQL_CREATE_TABLE); console.info(`ECDB_Encry succeeded in getting Store :${storeInfo.storeId}`); rdbStore.version = 1; } } catch (e) { let error = e as BusinessError; console.error(`An unexpected error occurred.code is ${error.code},message is ${error.message}`); } return rdbStore; } async putOnedata(rdbStore: relationalStore.RdbStore) { if (rdbStore != undefined) { const valueBucket: relationalStore.ValuesBucket = { ID: id++, NAME: 'Lisa', AGE: 18, SALARY: 100.5, CODES: new Uint8Array([1, 2, 3, 4, 5]), }; try { await rdbStore.insert("EMPLOYEE", valueBucket); console.info(`ECDB_Encry insert success`); } catch (e) { let error = e as BusinessError; console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); } } } async getDataNum(rdbStore: relationalStore.RdbStore) { if (rdbStore != undefined) { try { let predicates = new relationalStore.RdbPredicates('EMPLOYEE'); let resultSet = await rdbStore.query(predicates); let count = resultSet.rowCount; console.info(`ECDB_Encry getdatanum success count : ${count}`); } catch (e) { let error = e as BusinessError; console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); } } } async deleteAlldata(rdbStore: relationalStore.RdbStore) { if (rdbStore != undefined) { try { let predicates = new relationalStore.RdbPredicates('EMPLOYEE'); predicates.equalTo('AGE', 18); await rdbStore.delete(predicates); console.info(`ECDB_Encry delete Success`); } catch (e) { let error = e as BusinessError; console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); } } } async updataOnedata(rdbStore: relationalStore.RdbStore) { if (rdbStore != undefined) { try { let predicates = new relationalStore.RdbPredicates('EMPLOYEE'); predicates.equalTo('NAME', 'Lisa'); const valueBucket: relationalStore.ValuesBucket = { NAME: 'Anna', SALARY: 100.5, CODES: new Uint8Array([1, 2, 3, 4, 5]), }; await rdbStore.update(valueBucket, predicates); console.info(`ECDB_Encry update success`); } catch (e) { let error = e as BusinessError; console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); } } } } ``` ### SecretKeyObserver 该类æ供了获å–当å‰å¯†é’¥çŠ¶æ€çš„接å£ï¼Œåœ¨å¯†é’¥é”€æ¯åŽï¼Œå…³é—E类数æ®åº“。 ```ts // SecretKeyObserver.ts import { ECStoreManager } from './ECStoreManager'; export enum SecretStatus { Lock, UnLock } export class SecretKeyObserver { onLock(): void { this.lockStatuas = SecretStatus.Lock; this.storeManager.closeEStore(); } onUnLock(): void { this.lockStatuas = SecretStatus.UnLock; } getCurrentStatus(): number { return this.lockStatuas; } initialize(storeManager: ECStoreManager): void { this.storeManager = storeManager; } updatalockStatus(code: number) { if (this.lockStatuas === SecretStatus.Lock) { this.onLock(); } else { this.lockStatuas = code; } } private lockStatuas: number = SecretStatus.UnLock; private storeManager: ECStoreManager; } export let lockObserve = new SecretKeyObserver(); ``` ### ECStoreManager ECStoreManager类用于管ç†åº”用的E类数æ®åº“å’ŒC类数æ®åº“。支æŒé…置数æ®åº“ä¿¡æ¯ã€é…ç½®è¿ç§»å‡½æ•°çš„ä¿¡æ¯ï¼Œå¯æ ¹æ®å¯†é’¥çŠ¶æ€ä¸ºåº”用æ供相应的数æ®åº“å¥æŸ„,并æ供了关é—E类数æ®åº“ã€æ•°æ®è¿ç§»å®ŒæˆåŽé”€æ¯C类数æ®åº“ç‰æŽ¥å£ã€‚ ```ts // ECStoreManager.ts import { relationalStore } from '@kit.ArkData'; import { Mover } from './Mover'; import { BusinessError } from '@kit.BasicServicesKit'; import { StoreInfo, Store } from './Store'; import { SecretStatus } from './SecretKeyObserver'; let store = new Store(); export class ECStoreManager { config(cInfo: StoreInfo, other: StoreInfo): void { this.cInfo = cInfo; this.eInfo = other; } configDataMover(mover: Mover): void { this.mover = mover; } async getCurrentStore(screanStatus: number): Promise<relationalStore.RdbStore> { if (screanStatus === SecretStatus.UnLock) { try { this.eStore = await store.getECStore(this.eInfo); } catch (e) { let error = e as BusinessError; console.error(`Failed to GetECStore.code is ${error.code},message is ${error.message}`); } // 解é”çŠ¶æ€ èŽ·å–e类库 if (this.needMove) { if (this.eStore != undefined && this.cStore != undefined) { await this.mover.move(this.eStore, this.cStore); console.info(`ECDB_Encry cstore data move to estore success`); } this.deleteCStore(); this.needMove = false; } return this.eStore; } else { // åŠ é”çŠ¶æ€ èŽ·å–c类库 this.needMove = true; try { this.cStore = await store.getECStore(this.cInfo); } catch (e) { let error = e as BusinessError; console.error(`Failed to GetECStore.code is ${error.code},message is ${error.message}`); } return this.cStore; } } closeEStore(): void { this.eStore = undefined; } async deleteCStore() { try { await relationalStore.deleteRdbStore(this.cInfo.context, this.cInfo.storeId) } catch (e) { let error = e as BusinessError; console.error(`Failed to create KVManager.code is ${error.code},message is ${error.message}`); } } private eStore: relationalStore.RdbStore = null; private cStore: relationalStore.RdbStore = null; private cInfo: StoreInfo | null = null; private eInfo: StoreInfo | null = null; private needMove: boolean = false; private mover: Mover | null = null; } ``` ### EntryAbility 模拟在应用å¯åŠ¨æœŸé—´ï¼Œæ³¨å†Œå¯¹COMMON_EVENT_SCREEN_LOCK_FILE_ACCESS_STATE_CHANGED公共事件的监å¬ï¼Œå¹¶é…置相应的数æ®åº“ä¿¡æ¯ã€å¯†é’¥çŠ¶æ€ä¿¡æ¯ç‰ã€‚ ```ts // EntryAbility.ets import { AbilityConstant, contextConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; import { relationalStore } from '@kit.ArkData'; import { ECStoreManager } from './ECStoreManager'; import { StoreInfo } from './Store'; import { Mover } from './Mover'; import { SecretKeyObserver } from './SecretKeyObserver'; import { commonEventManager } from '@kit.BasicServicesKit'; import { BusinessError } from '@kit.BasicServicesKit'; export let storeManager = new ECStoreManager(); export let e_secretKeyObserver = new SecretKeyObserver(); let mover = new Mover(); let subscriber: commonEventManager.CommonEventSubscriber; export function createCB(err: BusinessError, commonEventSubscriber: commonEventManager.CommonEventSubscriber) { if (!err) { console.info('ECDB_Encry createSubscriber'); subscriber = commonEventSubscriber; try { commonEventManager.subscribe(subscriber, (err: BusinessError, data: commonEventManager.CommonEventData) => { if (err) { console.error(`subscribe failed, code is ${err.code}, message is ${err.message}`); } else { console.info(`ECDB_Encry SubscribeCB ${data.code}`); e_secretKeyObserver.updatalockStatus(data.code); } }); } catch (error) { const err: BusinessError = error as BusinessError; console.error(`subscribe failed, code is ${err.code}, message is ${err.message}`); } } else { console.error(`createSubscriber failed, code is ${err.code}, message is ${err.message}`); } } let cInfo: StoreInfo | null = null; let eInfo: StoreInfo | null = null; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); let cContext = this.context; cInfo = { context: cContext, config: { name: 'cstore.db', securityLevel: relationalStore.SecurityLevel.S3, }, storeId: "cstore.db" } let eContext = this.context.createModuleContext("entry"); eContext.area = contextConstant.AreaMode.EL5; eInfo = { context: eContext, config: { name: 'estore.db', securityLevel: relationalStore.SecurityLevel.S3, }, storeId: "estore.db", } // 监å¬COMMON_EVENT_SCREEN_LOCK_FILE_ACCESS_STATE_CHANGED事件 code == 1解é”状æ€ï¼Œcode==0åŠ é”çŠ¶æ€ console.info(`ECDB_Encry store area : estore:${eContext.area},cstore${cContext.area}`) try { commonEventManager.createSubscriber({ events: ['COMMON_EVENT_SCREEN_LOCK_FILE_ACCESS_STATE_CHANGED'] }, createCB); console.info(`ECDB_Encry success subscribe`); } catch (error) { const err: BusinessError = error as BusinessError; console.error(`createSubscriber failed, code is ${err.code}, message is ${err.message}`); } storeManager.config(cInfo, eInfo); storeManager.configDataMover(mover); e_secretKeyObserver.initialize(storeManager); } onDestroy(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); } onWindowStageCreate(windowStage: window.WindowStage): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); windowStage.loadContent('pages/Index', (err) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); }); } onWindowStageDestroy(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); } onForeground(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); } onBackground(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); } } ``` ### Index按键事件 使用Button按钮,通过点击按钮æ¥æ¨¡æ‹Ÿåº”用æ“作数æ®åº“,如æ’入数æ®ã€åˆ 除数æ®ã€æ›´æ–°æ•°æ®å’ŒèŽ·å–æ•°æ®æ•°é‡çš„æ“作ç‰ï¼Œå±•ç¤ºæ•°æ®åº“åŸºæœ¬çš„å¢žåˆ æ”¹æŸ¥èƒ½åŠ›ã€‚ ```ts // Index.ets import { storeManager, e_secretKeyObserver } from "../entryability/EntryAbility"; import { relationalStore } from '@kit.ArkData'; import { Store } from '../entryability/Store'; let storeOption = new Store(); let lockStatus: number = 1; @Entry @Component struct Index { @State message: string = 'Hello World'; build() { Row() { Column() { Button('åŠ é”/解é”').onClick((event: ClickEvent) => { if (lockStatus) { e_secretKeyObserver.onLock(); lockStatus = 0; } else { e_secretKeyObserver.onUnLock(); lockStatus = 1; } lockStatus ? this.message = "解é”" : this.message = "åŠ é”"; }).margin("5"); Button('store type').onClick(async (event: ClickEvent) => { e_secretKeyObserver.getCurrentStatus() ? this.message = "estroe" : this.message = "cstore"; console.info(`ECDB_Encry current store : ${this.message}`); }).margin("5"); Button("put").onClick(async (event: ClickEvent) => { let store: relationalStore.RdbStore = await storeManager.getCurrentStore(e_secretKeyObserver.getCurrentStatus()); storeOption.putOnedata(store); }).margin(5) Button("Get").onClick(async (event: ClickEvent) => { let store: relationalStore.RdbStore = await storeManager.getCurrentStore(e_secretKeyObserver.getCurrentStatus()); storeOption.getDataNum(store); }).margin(5) Button("delete").onClick(async (event: ClickEvent) => { let store: relationalStore.RdbStore = await storeManager.getCurrentStore(e_secretKeyObserver.getCurrentStatus()); storeOption.deleteAlldata(store); }).margin(5) Button("updata").onClick(async (event: ClickEvent) => { let store: relationalStore.RdbStore = await storeManager.getCurrentStore(e_secretKeyObserver.getCurrentStatus()); storeOption.updataOnedata(store); }).margin(5) Text(this.message) .fontSize(50) .fontWeight(FontWeight.Bold) } .width('100%') } .height('100%') } } ```