新增关系型数据库本地变更通知

Signed-off-by: sunlian <sunlian@kaihong.com>
This commit is contained in:
sunlian 2024-06-03 16:18:43 +08:00
parent 7117848332
commit b95d5d1103
17 changed files with 436 additions and 39 deletions

View File

@ -23,6 +23,7 @@ entry/src/main/ets/
| |---BasicDataSource.ets // 联系人列表懒加载数据
| |---BottomBtn.ets //
| |---ContactItem.ets // 联系人
| |---DataChangeDetailDialog // 联系人变更通知
| |---DeviceDialog.ets // 设备列表
| |---PopupMenu.ets // 设备选择
| |---QueryItem.ets // 联系人详情
@ -63,8 +64,8 @@ entry/src/main/ets/
1. 本示例的同步功能需要两台设备组网后测试;
2. 本示例仅支持标准系统上运行支持设备RK3568。
3. 本示例为Stage模型支持API10版本SDKSDK版本号(API Version 10 Release),镜像版本号(4.0 Release)
4. 本示例需要使用DevEco Studio 版本号(4.0 Release)及以上版本才可编译运行。
3. 本示例为Stage模型支持API12版本SDKSDK版本号(API Version 12 Release),镜像版本号(5.0 Release)
4. 本示例需要使用DevEco Studio 版本号(4.1 Release)及以上版本才可编译运行。
5. 本示例需要使用@ohos.distributedDeviceManager系统权限的系统接口。使用Full SDK时需要手动从镜像站点获取并在DevEco Studio中替换具体操作可参考[替换指南](https://docs.openharmony.cn/pages/v3.2/zh-cn/application-dev/quick-start/full-sdk-switch-guide.md/)。
### 下载

View File

@ -19,9 +19,8 @@
{
"name": "default",
"signingConfig": "default",
"compileSdkVersion": 10,
"compatibleSdkVersion": 10,
"runtimeOS": "OpenHarmony"
"compileSdkVersion": 12,
"compatibleSdkVersion": 12,
}
],
"signingConfigs": []

View File

@ -19,7 +19,8 @@
},
"targets": [
{
"name": "default"
"name": "default",
"runtimeOS": "OpenHarmony"
},
{
"name": "ohosTest",

View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
* 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 Contact from '../model/Contact';
import { TYPE_DELETE, TYPE_INSERT, TYPE_UPDATE } from '../model/RdbConst'
@CustomDialog
export struct DataChangeDetailDialog {
private controller?: CustomDialogController;
@State detailList: Array<Contact> = [];
build() {
Column() {
Text($r('app.string.change_detail'))
.fontSize(24)
.width('100%')
.textAlign(TextAlign.Center)
.fontColor(Color.Black)
.fontWeight(FontWeight.Bold)
.margin(8)
List() {
ForEach(this.detailList, (item: Contact, index: number) => {
ListItem() {
Column() {
if (item.type === TYPE_DELETE) {
Text($r('app.string.change_delete'))
.fontSize(20)
.width('80%')
.fontColor(Color.Black)
}
if (item.type === TYPE_UPDATE) {
Text($r('app.string.change_update'))
.fontSize(20)
.width('80%')
.fontColor(Color.Black)
}
if (item.type === TYPE_INSERT) {
Text($r('app.string.change_insert'))
.fontSize(20)
.width('80%')
.fontColor(Color.Black)
}
Column() {
Row() {
Text($r('app.string.id'))
.fontSize(20)
.width('40%')
.fontColor(Color.Black)
Text(item.id.toString())
.fontSize(20)
.width('40%')
.fontColor(Color.Black)
}
if (item.type !== TYPE_DELETE) {
Row() {
Text($r('app.string.contact_name'))
.fontSize(20)
.width('40%')
.fontColor(Color.Black)
Text(item.name)
.fontSize(20)
.width('40%')
.fontColor(Color.Black)
}
Row() {
Text($r('app.string.gender1'))
.fontSize(20)
.width('40%')
.fontColor(Color.Black)
if (item.gender == 0) {
Text($r('app.string.male'))
.fontSize(20)
.width('40%')
.fontColor(Color.Black)
} else {
Text($r('app.string.female'))
.fontSize(20)
.width('40%')
.fontColor(Color.Black)
}
}
Row() {
Text($r('app.string.phone'))
.fontSize(20)
.width('40%')
.fontColor(Color.Black)
Text(item.phone)
.fontSize(20)
.width('40%')
.fontColor(Color.Black)
}
Row() {
Text($r('app.string.remark'))
.fontSize(20)
.width('40%')
.fontColor(Color.Black)
Text(item.remark)
.fontSize(20)
.width('40%')
.fontColor(Color.Black)
}
Row() {
Text($r('app.string.age'))
.fontSize(20)
.width('40%')
.fontColor(Color.Black)
Text(item.age.toString())
.fontSize(20)
.width('40%')
.fontColor(Color.Black)
}
}
}
.margin(8)
.padding({ left: 12 })
}
}
})
}
.divider({ strokeWidth: 1, color: Color.Gray })
.width('80%')
.height('80%')
Button() {
Text($r('app.string.sure'))
.fontColor('#0D9FFB')
.width('90%')
.textAlign(TextAlign.Center)
.fontSize(20)
}
.key('sureBtn')
.type(ButtonType.Capsule)
.backgroundColor(Color.White)
.onClick(() => {
if (this.controller != null) {
this.controller.close()
}
})
}
.backgroundColor(Color.White)
.border({ color: Color.White, radius: 20 })
.padding(10)
}
}

View File

@ -24,12 +24,12 @@ import { GlobalContext } from '../model/GlobalContext';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
GlobalContext.getContext().setObject('context', this.context);
AppStorage.SetOrCreate('want', want);
AppStorage.setOrCreate('want', want);
}
async onWindowStageCreate(windowStage: Window.WindowStage): Promise<void> {
// Main window is created, set main page for this ability
windowStage.loadContent('pages/Index', (err, data:void) => {
windowStage.loadContent('pages/Index', (err, data: void) => {
if (err.code) {
Logger.error('Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;

View File

@ -22,8 +22,9 @@ export default class Contact {
remark: string;
age: number;
isSelected: boolean;
type: string | undefined;
constructor(id: number, name: string, gender: number, phone: string, age: number, remark: string) {
constructor(id: number, name: string, gender: number, phone: string, age: number, remark: string, type?: string) {
this.id = id;
this.name = name;
this.gender = gender;
@ -31,5 +32,6 @@ export default class Contact {
this.remark = remark;
this.age = age;
this.isSelected = false;
this.type = type;
}
}

View File

@ -25,4 +25,10 @@ export const STORE_CONFIG: data_rdb.StoreConfig = { name: 'contact.db', security
export const BUNDLE = 'ohos.samples.distributedrdb';
export const ABILITY = 'EntryAbility';
export const ABILITY = 'EntryAbility';
export const TYPE_INSERT = 'insert';
export const TYPE_UPDATE = 'update';
export const TYPE_DELETE = 'delete';

View File

@ -17,7 +17,7 @@ import data_rdb from '@ohos.data.relationalStore'
import common from '@ohos.app.ability.common'
import Contact from '../model/Contact'
import Logger from '../model/Logger'
import { STORE_CONFIG } from '../model/RdbConst'
import { STORE_CONFIG, TABLE_NAME, TYPE_INSERT, TYPE_UPDATE, TYPE_DELETE } from '../model/RdbConst'
import { ValuesBucket } from '@ohos.data.ValuesBucket';
const TAG = 'RdbModel'
@ -28,7 +28,8 @@ export default class RdbModel {
private sqlCreateTable: string = ''
private columns: Array<string> = []
private distributedTable: string = ''
private dataChangeCallback : Function| null = null
private dataChangeCallback: Function | null = null
private dataChangeDetailCallback: Function | null = null
private isCreateDbDone: boolean = false
private context: common.UIAbilityContext
@ -57,7 +58,7 @@ export default class RdbModel {
Logger.info(TAG, 'getRdbStore end')
try {
// 执行sql语句联系人个各个属性设定
if(this.rdbStore != undefined) {
if (this.rdbStore != undefined) {
await this.rdbStore.executeSql(this.sqlCreateTable)
console.info(`create tabe start ` + this.sqlCreateTable);
// 设置分布式表表明为contact
@ -85,7 +86,7 @@ export default class RdbModel {
'remark': value4,
'age': value5,
}
if(this.rdbStore != undefined) {
if (this.rdbStore != undefined) {
let ret = await this.rdbStore.insert(this.tableName, valueBucket, data_rdb.ConflictResolution.ON_CONFLICT_REPLACE)
Logger.info(TAG, `insert done:${ret}`)
}
@ -130,6 +131,7 @@ export default class RdbModel {
Logger.info(TAG, 'query start')
Logger.info(TAG, 'predicates is ' + JSON.stringify(predicates))
Logger.info(TAG, 'columns ' + JSON.stringify(this.columns))
if (this.rdbStore != undefined) {
// 默认查询所有列
let resultSet: data_rdb.ResultSet = await this.rdbStore.query(predicates, this.columns);
@ -171,6 +173,27 @@ export default class RdbModel {
}
}
async onDataChangeDetail(device: string, callback: Function) {
Logger.info(TAG, `onDataChangeDetail enterdevice=` + device + ` ,tableName = ` + this.tableName);
try {
if (this.rdbStore != undefined) {
this.distributedTable = await this.rdbStore.obtainDistributedTableName(device, this.tableName);
Logger.info(TAG, `obtainDistributedTableName,distributedTable=` + this.distributedTable);
}
}
catch (err) {
Logger.error(TAG, `ObtainDistributedTableName failed, code is ${err.code},message is ${err.message}`);
}
this.dataChangeDetailCallback = callback;
if (this.rdbStore != undefined) {
this.rdbStore.on('dataChange', data_rdb.SubscribeType.SUBSCRIBE_TYPE_LOCAL_DETAILS, async (changeInfo: Array<data_rdb.ChangeInfo>) => {
Logger.info(TAG, `on dataChange SUBSCRIBE_TYPE_REMOTE, callback`);
Logger.info(TAG, `on dataChange SUBSCRIBE_TYPE_REMOTE =` + JSON.stringify(changeInfo));
await this.pullDataDetail(changeInfo);
})
}
}
async pullData() {
Logger.info(TAG, `start pullData`)
if (this.rdbStore != undefined) {
@ -198,8 +221,61 @@ export default class RdbModel {
}
}
async pullDataDetail(changeInfo: Array<data_rdb.ChangeInfo>) {
Logger.info(TAG, `start pullDataDetail`);
if (this.rdbStore != undefined) {
if (changeInfo.length > 0) {
let result: Array<Contact> = [];
for (let i = 0; i < changeInfo.length; i++) {
let table: string = changeInfo[i].table;
if (table !== TABLE_NAME) {
return;
}
let inserted: Array<string> | Array<number> = changeInfo[i].inserted;
let updated: Array<string> | Array<number> = changeInfo[i].updated;
let deleted: Array<string> | Array<number> = changeInfo[i].deleted;
if (inserted.length > 0) {
let insertData: Array<Contact> = await this.getDetailByType(inserted, TYPE_INSERT);
insertData.forEach(element => {
result.push(element);
});
}
if (updated.length > 0) {
let updateData: Array<Contact> = await this.getDetailByType(updated, TYPE_UPDATE);
updateData.forEach(element => {
result.push(element);
});
}
if (deleted.length > 0) {
for (let index = 0; index < deleted.length; index++) {
result.push(new Contact(deleted[index] as number, '', 0, '', 0, '', TYPE_DELETE));
}
}
}
Logger.info(TAG, `result:` + JSON.stringify(result));
if (this.dataChangeDetailCallback !== null) {
this.dataChangeDetailCallback(result);
}
}
}
}
async getDetailByType(id: Array<string> | Array<number>, type: string): Promise<Array<Contact>> {
let predicates = new data_rdb.RdbPredicates(TABLE_NAME);
predicates.in('id', id);
let aData = await this.query(predicates);
Logger.info(TAG, `type:${type}`);
Logger.info(TAG, `aData:` + JSON.stringify(aData));
if (aData.length > 0) {
for (let i = 0; i < aData.length; i++) {
aData[i].type = type;
}
}
return aData;
}
offDataChange() {
if(this.rdbStore != undefined) {
if (this.rdbStore != undefined) {
this.rdbStore.off('dataChange', data_rdb.SubscribeType.SUBSCRIBE_TYPE_REMOTE, (devices) => {
for (let i = 0; i < devices.length; i++) {
Logger.info(TAG, `device=${devices[i]} off data changed`)
@ -208,6 +284,16 @@ export default class RdbModel {
}
}
offDataChangeDetail() {
if (this.rdbStore != undefined) {
this.rdbStore.off('dataChange', data_rdb.SubscribeType.SUBSCRIBE_TYPE_LOCAL_DETAILS, (devices) => {
for (let i = 0; i < devices.length; i++) {
Logger.info(TAG, `device=${devices[i]} off data changed`)
}
})
}
}
// 处理数据格式
getListFromResultSet(resultSet: data_rdb.ResultSet): Array<Contact> {
// 声明结果变量

View File

@ -29,6 +29,7 @@ import { SyncState } from '../model/LiteStore'
import { SearchBar } from '../common/SearchBar'
import { TitleBar } from '../common/TitleBar'
import { TABLE_NAME, BUNDLE, ABILITY, SQL_CREATE_TABLE, COLUMNS } from '../model/RdbConst'
import { DataChangeDetailDialog } from '../common/DataChangeDetailDialog';
const TAG: string = 'Index'
@ -41,12 +42,14 @@ export interface stateType {
distributedDevice: string,
opacityValue: number
}
@Entry
@Component
struct Index {
private liteStore = new LiteStore("sync_state", getContext(this) as common.UIAbilityContext)
private rdbModel = new RdbModel(TABLE_NAME, SQL_CREATE_TABLE, COLUMNS, getContext(this) as common.UIAbilityContext)
private intervalId: number = 0
private dialogController: CustomDialogController | null = null;
@State contacts: ContactDataSource = new ContactDataSource([])
@State isMultiCheck: boolean = false
@State isSelectedAll: boolean = false
@ -63,13 +66,19 @@ struct Index {
async aboutToAppear() {
Logger.info(TAG, 'aboutToAppear')
await this.rdbModel.getRdbStore();
await this.getData();
this.rdbModel.onDataChangeDetail(this.state.distributedDevice, (result: Array<Contact>) => {
this.showDataChangeDialog(result)
})
}
aboutToDisappear(): void {
this.rdbModel.offDataChangeDetail()
}
// 拉起应用后读取数据,暂定为分布式功能
getWant() {
let want = AppStorage.Get<Want>('want') as Want
if(want.parameters != undefined) {
let want = AppStorage.get<Want>('want') as Want
if (want.parameters != undefined) {
if (this.state.isDistributed && want.parameters.isStage === 'EXIT') {
Logger.info(TAG, 'isStage = EXIT')
this.state.isStage = false
@ -93,8 +102,8 @@ struct Index {
}
})
Logger.info(TAG, 'onDataChange')
this.rdbModel.onDataChange(this.state.distributedDevice, (result: Array<Contact>)=> {
this.contacts.dataArray = result
this.rdbModel.onDataChange(this.state.distributedDevice, (result: Array<Contact>) => {
this.contacts.dataArray = result
this.contacts.notifyDataReload()
})
}
@ -104,7 +113,7 @@ struct Index {
async onPageShow() {
try {
// 初始化分部署数据库
await this.rdbModel.getRdbStore()
//await this.rdbModel.getRdbStore()
this.intervalId = setInterval(() => {
// 手动侦听应用被拉起的动作
this.getWant()
@ -163,6 +172,21 @@ struct Index {
})
}
showDataChangeDialog(result: Array<Contact>) {
Logger.info(TAG, `showDataChangeDialog:` + JSON.stringify(result))
if (this.dialogController !== null) {
this.dialogController.close()
this.dialogController = null
}
this.dialogController = new CustomDialogController({
builder: DataChangeDetailDialog({
detailList: result,
}),
autoCancel: true
})
this.dialogController.open()
}
handleClickContact(item: Contact, index: number) {
Logger.info(TAG, `handleClickContact, item = ${JSON.stringify(item)}`)
if (this.isMultiCheck) {

View File

@ -50,7 +50,7 @@
],
"requestPermissions": [
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC"
"name": "ohos.permission.DISTRIBUTED_DATASYNC",
},
{
"name": "ohos.permission.ACCESS_SERVICE_DM"

View File

@ -16,6 +16,30 @@
"name": "check_device",
"value": "Check device"
},
{
"name": "change_detail",
"value": "Change Detail"
},
{
"name": "change_type",
"value": "Change Type"
},
{
"name": "change_delete",
"value": "Contract deleted"
},
{
"name": "change_insert",
"value": "Contract inserted"
},
{
"name": "change_update",
"value": "Contract updated"
},
{
"name": "id",
"value": "ID"
},
{
"name": "cancel",
"value": "Cancel"
@ -52,6 +76,10 @@
"name": "gender",
"value": "Gender:"
},
{
"name": "gender1",
"value": "Gender"
},
{
"name": "contact_name",
"value": "Name"

View File

@ -16,6 +16,30 @@
"name": "check_device",
"value": "Check device"
},
{
"name": "change_detail",
"value": "Change Detail"
},
{
"name": "change_type",
"value": "Change Type"
},
{
"name": "change_delete",
"value": "Contract deleted"
},
{
"name": "id",
"value": "ID"
},
{
"name": "change_insert",
"value": "Contract inserted"
},
{
"name": "change_update",
"value": "Contract updated"
},
{
"name": "cancel",
"value": "Cancel"
@ -56,6 +80,10 @@
"name": "gender",
"value": "Gender:"
},
{
"name": "gender1",
"value": "Gender"
},
{
"name": "contact_name",
"value": "Name"

View File

@ -16,6 +16,30 @@
"name": "check_device",
"value": "选择设备"
},
{
"name": "change_detail",
"value": "联系人数据变更通知"
},
{
"name": "change_delete",
"value": "删除联系人"
},
{
"name": "change_insert",
"value": "新增联系人"
},
{
"name": "change_update",
"value": "修改联系人"
},
{
"name": "id",
"value": "ID"
},
{
"name": "change_type",
"value": "类型"
},
{
"name": "cancel",
"value": "取消"
@ -52,6 +76,10 @@
"name": "gender",
"value": "性别:"
},
{
"name": "gender1",
"value": "性别"
},
{
"name": "phone",
"value": "电话"

View File

@ -24,11 +24,13 @@ const TAG = '[Sample_DistributedRdb]';
const BUNDLE = 'DistributedRdb_';
export default function abilityTest() {
let driver = Driver.create();
let delegator = AbilityDelegatorRegistry.getAbilityDelegator();
describe('ActsAbilityTest', () => {
it(BUNDLE + 'StartAbility_001', 0, async (done: Function) => {
it('DistributedRdb_StartAbility_001', 0, async (done: Function) => {
logger.info(TAG, `${BUNDLE}StartAbility_001 begin`);
let driver = Driver.create();
logger.info(TAG, `Driver.create: ${driver}`);
let delegator = AbilityDelegatorRegistry.getAbilityDelegator();
let want: Want = {
bundleName: "ohos.samples.distributedrdb",
abilityName: "EntryAbility"
@ -44,8 +46,10 @@ export default function abilityTest() {
/**
* 点击允许授权
*/
it(BUNDLE + 'ClickAcceptFunction_001', 0, async (done: Function) => {
it('DistributedRdb_ClickAcceptFunction_001', 0, async (done: Function) => {
logger.info(TAG, `${BUNDLE}ClickAcceptFunction_001 begin`);
let driver = Driver.create();
let delegator = AbilityDelegatorRegistry.getAbilityDelegator();
await driver.delayMs(1000);
logger.info(TAG, `${BUNDLE}ClickAcceptFunction_001 clickAccept`);
// 点击允许
@ -64,8 +68,9 @@ export default function abilityTest() {
/**
* 设置页面
*/
it(BUNDLE + 'Settings_001', 0, async (done: Function) => {
it('DistributedRdb_Settings_001', 0, async (done: Function) => {
logger.info(TAG, `${BUNDLE}Settings_001 begin`);
let driver = Driver.create();
await driver.delayMs(1000);
// 点击右上角更多按钮、弹出菜单
await driver.assertComponentExist(ON.id('rightBtn'));
@ -90,6 +95,8 @@ export default function abilityTest() {
await driver.delayMs(1000);
let isManual1 = await manualSwitch.isChecked();
let isAutomatic1 = await automaticSwitch.isChecked();
logger.info(TAG, `${BUNDLE}isManual1=${isManual1},isAutomatic1=${isAutomatic1}`);
await driver.pressBack();
logger.info(TAG, `${BUNDLE}Settings_001 end`);
@ -99,8 +106,9 @@ export default function abilityTest() {
/**
* 连接设备弹窗
*/
it(BUNDLE + 'SelectDeviceDialog_001', 0, async (done: Function) => {
it('DistributedRdb_SelectDeviceDialog_001', 0, async (done: Function) => {
logger.info(TAG, `${BUNDLE}SelectDeviceDialog_001 begin`);
let driver = Driver.create();
await driver.delayMs(1000)
// 点击右上角更多按钮、弹出菜单
await driver.assertComponentExist(ON.id('rightBtn'));
@ -125,8 +133,9 @@ export default function abilityTest() {
/**
* 添加联系人
*/
it(BUNDLE + 'AddContactFunction_001', 0, async (done: Function) => {
it('DistributedRdb_AddContactFunction_001', 0, async (done: Function) => {
logger.info(TAG, `${BUNDLE}AddContactFunction_001 begin`);
let driver = Driver.create();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('btnAdd'));
let btnAdd = await driver.findComponent(ON.id('btnAdd'));
@ -160,6 +169,11 @@ export default function abilityTest() {
let rightBtn = await driver.findComponent(ON.id('rightBtn'));
await rightBtn.click();
await driver.delayMs(1000);
let listChange: Component[] = await driver.findComponents(ON.type('ListItem'));
expect(listChange.length > 0).assertTrue();
let sureBtn = await driver.findComponent(ON.id('sureBtn'));
await sureBtn.click();
await driver.delayMs(1000);
let list: Component[] = await driver.findComponents(ON.type('ListItem'));
expect(list.length > 0).assertTrue();
logger.info(TAG, `${BUNDLE}AddContactFunction_001 end`);
@ -169,8 +183,9 @@ export default function abilityTest() {
/**
* 搜索联系人
*/
it(BUNDLE + 'SearchContactFunction_001', 0, async (done: Function) => {
it('DistributedRdb_SearchContactFunction_001', 0, async (done: Function) => {
logger.info(TAG, `${BUNDLE}SearchContactFunction_001 begin`);
let driver = Driver.create();
await driver.delayMs(1000)
// 点击搜索框
await driver.assertComponentExist(ON.id('searchBar'))
@ -198,8 +213,9 @@ export default function abilityTest() {
/**
* 添加联系人并解决联系人冲突(电话号码一样,联系人名称不一样)
*/
it(BUNDLE + 'AddContactConflictFunction_001', 0, async (done: Function) => {
it('DistributedRdb_AddContactConflictFunction_001', 0, async (done: Function) => {
logger.info(TAG, `${BUNDLE}AddContactConflictFunction_001 begin`);
let driver = Driver.create();
await driver.delayMs(500);
await driver.assertComponentExist(ON.id('btnAdd'));
let btnAdd = await driver.findComponent(ON.id('btnAdd'));
@ -235,6 +251,11 @@ export default function abilityTest() {
let rightBtn = await driver.findComponent(ON.id('rightBtn'));
await rightBtn.click();
await driver.delayMs(500);
await driver.delayMs(1000);
let listChange: Component[] = await driver.findComponents(ON.type('ListItem'));
expect(listChange.length > 0).assertTrue();
let sureBtn = await driver.findComponent(ON.id('sureBtn'));
await sureBtn.click();
let list: Component[] = await driver.findComponents(ON.type('ListItem'));
expect(list.length > 0).assertTrue();
@ -268,6 +289,11 @@ export default function abilityTest() {
await driver.assertComponentExist(ON.id('rightBtn'));
let rightBtn1 = await driver.findComponent(ON.id('rightBtn'));
await rightBtn1.click();
await driver.delayMs(1000);
let listChange2: Component[] = await driver.findComponents(ON.type('ListItem'));
expect(listChange2.length > 0).assertTrue();
let sureBtn2 = await driver.findComponent(ON.id('sureBtn'));
await sureBtn2.click();
await driver.delayMs(500);
let list1: Component[] = await driver.findComponents(ON.type('ListItem'));
expect(list1.length > 0).assertTrue();
@ -298,8 +324,9 @@ export default function abilityTest() {
/**
* 长按联系人进入多选、退出多选
*/
it(BUNDLE + 'LongClickFunction_001', 0, async (done: Function) => {
it('DistributedRdb_LongClickFunction_001', 0, async (done: Function) => {
logger.info(TAG, `${BUNDLE}LongClickFunction_001 begin`);
let driver = Driver.create();
await driver.delayMs(1000)
// 长按第一条,进入多选
let list: Component[] = await driver.findComponents(ON.type('ListItem'));
@ -318,8 +345,9 @@ export default function abilityTest() {
/**
* 进入多选后全选、删除
*/
it(BUNDLE + 'DeleteContactFunction_001', 0, async (done: Function) => {
it('DistributedRdb_DeleteContactFunction_001', 0, async (done: Function) => {
logger.info(TAG, `${BUNDLE}DeleteContactFunction_001 begin`);
let driver = Driver.create();
await driver.delayMs(1000)
// 长按第一条,进入多选
let list: Component[] = await driver.findComponents(ON.type('ListItem'));
@ -340,6 +368,11 @@ export default function abilityTest() {
let btnInDailog = await driver.findComponents(ON.type('Button'));
await btnInDailog[0].click();
await driver.delayMs(1000);
let listChange: Component[] = await driver.findComponents(ON.type('ListItem'));
expect(listChange.length > 0).assertTrue();
let sureBtn = await driver.findComponent(ON.id('sureBtn'));
await sureBtn.click();
await driver.delayMs(1000);
let list1: Component[] = await driver.findComponents(ON.type('ListItem'));
expect(list1 == null || list1.length == 0).assertTrue();
}

View File

@ -29,11 +29,11 @@
"abilities": [
{
"name": "TestAbility",
"srcEntrance": "./ets/testability/TestAbility.ets",
"srcEntry": "./ets/testability/TestAbility.ets",
"description": "$string:TestAbility_desc",
"icon": "$media:icon",
"label": "$string:TestAbility_label",
"visible": true,
"exported": true,
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"skills": [

View File

@ -1,6 +1,6 @@
{
"hvigorVersion": "3.0.2",
"hvigorVersion": "3.2.4",
"dependencies": {
"@ohos/hvigor-ohos-plugin": "3.0.2"
"@ohos/hvigor-ohos-plugin": "3.2.4"
}
}

File diff suppressed because one or more lines are too long