头图

介绍

本示例使用[@ohos.data.relationalStore]接口和[@ohos.distributedDeviceManager] 接口展示了在eTS中分布式关系型数据库的使用,在增、删、改、查的基本操作外,还包括分布式数据库的数据同步同能。

效果预览

image.png

使用说明:

鸿蒙OS开发更多内容↓点击 《鸿蒙NEXT星河版开发学习文档》HarmonyOS与OpenHarmony技术
  1. 启动应用后点击“ + ”按钮可以添加联系人;
  2. 点击联系人可以进入编辑界面编辑联系人信息;
  3. 长按联系人进入多选状态,底部有“全选”、“取消”、“删除”、“退出”按钮,点击退出可以退出多选状态;
  4. 点击右上角更多按钮,点击“连接设备”,选择要同步数据的设备,连接成功后可以开始将本端数据同步到对端;
  5. 点击右上角更多按钮,点击“设置”可以进入设置界面设置数据同步方式,包括自动同步和手动同步。
    搜狗高速浏览器截图20240326151547.png

具体实现

鸿蒙开发技术更新在mau123789拿取前往是v喔
  • 数据库的增、删、改、查操作都在RdbModel中,源码参考[RdbModel.ets]:
/*

 * Copyright (c) 2023 Huawei Device 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 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 { ValuesBucket } from '@ohos.data.ValuesBucket';



const TAG = 'RdbModel'



export default class RdbModel {

  private rdbStore: data_rdb.RdbStore | undefined = undefined

  private tableName: string = ''

  private sqlCreateTable: string = ''

  private columns: Array<string> = []

  private distributedTable: string = ''

  private dataChangeCallback : Function| null = null

  private isCreateDbDone: boolean = false

  private context: common.UIAbilityContext



  constructor(tableName: string, sqlCreateTable: string, columns: Array<string>, context: common.UIAbilityContext) {

    this.tableName = tableName

    this.sqlCreateTable = sqlCreateTable

    this.columns = columns

    this.context = context



    this.getRdbStore()

  }



  // 初始化数据库

  async getRdbStore() {

    Logger.info(TAG, 'getRdbStore begin')

    if (this.isCreateDbDone) {

      Logger.info(TAG, 'getRdbStore isCreateDbDone')

      return

    }

    try {

      // 获取数据库存储对象

      this.rdbStore = await data_rdb.getRdbStore(this.context, STORE_CONFIG);

    } catch (err) {

      console.info(`getRdbStore err ${JSON.stringify(err)}`);

    }

    Logger.info(TAG, 'getRdbStore end')

    try {

      // 执行sql语句,联系人个各个属性设定

      if(this.rdbStore != undefined) {

        await this.rdbStore.executeSql(this.sqlCreateTable)

        console.info(`create tabe start ` + this.sqlCreateTable);

        // 设置分布式表,表明为contact

        await this.rdbStore.setDistributedTables([this.tableName])

      }

    } catch (e) {

      Logger.error(TAG, 'getRdbStore:' + JSON.stringify(e))

    }

    // 分布式数据库创建为完成

    this.isCreateDbDone = true

    Logger.info(TAG, 'create table done')

  }



  async insertData(contact: Contact) {

    let value1 = contact.name;

    let value2 = contact.gender;

    let value3 = contact.phone;

    let value4 = contact.remark;

    let value5 = contact.age;



    const valueBucket: ValuesBucket = {

      'name': value1,

      'gender': value2,

      'phone': value3,

      'remark': value4,

      'age': value5,

    }

    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}`)

    }

  }



  async updateData(contact: Contact) {

    let value1 = contact.name;

    let value2 = contact.gender;

    let value3 = contact.phone;

    let value4 = contact.remark;

    let value5 = contact.age;



    const valueBucket: ValuesBucket = {

      'name': value1,

      'gender': value2,

      'phone': value3,

      'remark': value4,

      'age': value5,

    }

    let predicates = new data_rdb.RdbPredicates(this.tableName)

    Logger.info(TAG, `updateData id=${contact.id}`)

    predicates.equalTo('id', contact.id)

    if (this.rdbStore != undefined) {

      let ret = await this.rdbStore.update(valueBucket, predicates)

      Logger.info(TAG, `updated row count: ${ret}`)

    }

  }



  async deleteContacts(contacts: Array<Contact>) {

    let predicates = new data_rdb.RdbPredicates(this.tableName)

    contacts.forEach((contact) => {

      predicates.or()

        .equalTo('id', contact.id)

    })

    if (this.rdbStore != undefined) {

      let rows = await this.rdbStore.delete(predicates)

      Logger.info(TAG, `delete rows: ${rows}`)

    }

  }



  async query(predicates: data_rdb.RdbPredicates): Promise<Array<Contact>> {

    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);

      Logger.info(TAG, 'result is ' + JSON.stringify(resultSet.rowCount))

      // 处理查询到的结果数组

      return this.getListFromResultSet(resultSet)

    }

    return []

  }



  async syncData(predicates: data_rdb.RdbPredicates) {

    Logger.info(TAG, 'syncData')

    if (this.rdbStore != undefined) {

      let result = await this.rdbStore.sync(data_rdb.SyncMode.SYNC_MODE_PUSH, predicates)

      for (let i = 0; i < result.length; i++) {

        Logger.info(TAG, `device=${result[i][0]}, status = ${result[i][1]}`)

      }

    }

  }



  async onDataChange(device: string, callback: Function) {

    Logger.info(TAG, `onDataChange enter,device=` + 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.dataChangeCallback = callback

    await this.pullData()

    if (this.rdbStore != undefined) {

      this.rdbStore.on('dataChange', data_rdb.SubscribeType.SUBSCRIBE_TYPE_REMOTE, async (devices) => {

        Logger.info(TAG, `on dataChange, callback`)

        await this.pullData()

      })

    }

  }



  async pullData() {

    Logger.info(TAG, `start pullData`)

    if (this.rdbStore != undefined) {

      await this.rdbStore.executeSql('delete from ' + this.tableName)

      let predicates = new data_rdb.RdbPredicates(this.distributedTable)

      let resultSet = await this.rdbStore.query(predicates, this.columns)

      let result = this.getListFromResultSet(resultSet)

      Logger.info(TAG, `on dataChange,result.length=${result.length}`)

      for (let i = 0; i < result.length; i++) {

        Logger.info(TAG, `on dataChange,insert${result[i].name}`)

        let predicate = new data_rdb.RdbPredicates(this.tableName)

        predicate.equalTo('name', result[i].name)

        let exit = await this.rdbStore.query(predicate, this.columns)

        exit.goToFirstRow()

        if (exit.rowCount === 0) {

          await this.insertData(result[i])

        } else {

          result[i].id = exit.getDouble(resultSet.getColumnIndex('id'))

          await this.updateData(result[i])

        }

      }

      if (this.dataChangeCallback != null) {

        this.dataChangeCallback(result)

      }

    }

  }



  offDataChange() {

    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`)

        }

      })

    }

  }



  // 处理数据格式

  getListFromResultSet(resultSet: data_rdb.ResultSet): Array<Contact> {

    // 声明结果变量

    let contacts: Array<Contact> = []

    // 进入结果集的第一行

    resultSet.goToFirstRow()

    // 如果没有结束就继续遍历

    while (!resultSet.isEnded) {

      // 读取各个属性,初始化临时变量contact

      let contact: Contact = new Contact(resultSet.getDouble(resultSet.getColumnIndex('id'))

        , resultSet.getString(resultSet.getColumnIndex('name'))

        , resultSet.getDouble(resultSet.getColumnIndex('gender'))

        , resultSet.getString(resultSet.getColumnIndex('phone'))

        , resultSet.getLong(resultSet.getColumnIndex('age'))

        , resultSet.getString(resultSet.getColumnIndex('remark')))

      if (!contacts.includes(contact)) {

        // 如果数据集合中没有这条数据就添加进去

        contacts.push(contact)

      }

      // 进入下一行

      resultSet.goToNextRow()

    }

    // 数据整合完毕就释放资源

    resultSet.close()

    Logger.info(TAG, 'contacts number is ' + contacts.length)

    // 返回整合的联系人数据

    return contacts

  }

}
  • 数据库操作:使用[@ohos.data.relationalStore] 接口的getRdbStore获得一个相关的操作型关系数据库RdbStore,通过这个RdbStore调用相关接口进行增删改查,RdbStore.insert数据插入,RdbStore.delete数据删除,RdbStore.update更新数据,RdbStore.query根据条件查询数据;
  • 数据同步:RdbStore.on注册数据库观察者,使用RdbStore.obtainDistributedTableName根据本地表名获取指定远程设备的分布式表名,数据发生变动时通过RdbStore.sync同步数据,不需要用时删除指定观察者使用RdbStore.off。
  • 连接设备管理在RemoteDeviceModel中,源码参考[RemoteDeviceModel.ets]:

    /*
    
     * Copyright (c) 2023 Huawei Device 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 deviceManager from '@ohos.distributedDeviceManager';
    
    import Logger from '../model/Logger'
    
    import { BUNDLE } from '../model/RdbConst'
    
    import { BusinessError } from '@ohos.base';
    
    
    
    let SUBSCRIBE_ID = 100
    
    const TAG: string = 'RemoteDeviceModel'
    
    class Data {
    
      device: deviceManager.DeviceBasicInfo = {
    
    deviceId: "",
    
    deviceName: "",
    
    deviceType: "",
    
    networkId: "",
    
      }
    
    }
    
    class RemoteDeviceModel {
    
      public deviceList: Array<deviceManager.DeviceBasicInfo> = [];
    
      public discoverList: Array<deviceManager.DeviceBasicInfo> = [];
    
      private callback: () => void = () => {};
    
      private authCallback: (device: deviceManager.DeviceBasicInfo) => void = (device: deviceManager.DeviceBasicInfo) => '';
    
      private deviceManager: deviceManager.DeviceManager | undefined = undefined
    
    
    
      registerDeviceListCallback(callback: () => void) {
    
    if (typeof (this.deviceManager) !== 'undefined') {
    
      this.registerDeviceListCallbackImplement(callback)
    
      return
    
    }
    
    Logger.info(TAG, 'deviceManager.createDeviceManager begin')
    
    try {
    
      let dmInstance = deviceManager.createDeviceManager(BUNDLE);
    
      Logger.info(TAG, `dmInstance= ${JSON.stringify (dmInstance)}`);
    
      this.deviceManager = dmInstance;
    
      this.registerDeviceListCallbackImplement(callback);
    
      Logger.info(TAG, `createDeviceManager callback returned, value= ${JSON.stringify(this.deviceManager)}`);
    
    } catch (error) {
    
      Logger.error(TAG, `createDeviceManager throw error, code: ${(error as BusinessError).code} message: ${(error as BusinessError).message}`);
    
    }
    
    Logger.info(TAG, 'deviceManager.createDeviceManager end');
    
      }
    
    
    
      deviceStateChangeActionOnline(device: deviceManager.DeviceBasicInfo) {
    
    this.deviceList[this.deviceList.length] = device
    
    Logger.info(TAG, `online, device list=${JSON.stringify(this.deviceList)}`)
    
    if (this.authCallback !== undefined) {
    
      this.authCallback(device)
    
      this.authCallback = () => {}
    
    }
    
      }
    
    
    
      deviceStateChangeActionReady(device: deviceManager.DeviceBasicInfo) {
    
    if (this.deviceList.length <= 0) {
    
      this.callback()
    
      return
    
    }
    
    let list: Array<deviceManager.DeviceBasicInfo> = new Array()
    
    for (let i = 0; i < this.deviceList.length; i++) {
    
      if (this.deviceList[i].deviceId !== device.deviceId) {
    
        list[i] = device
    
      }
    
    }
    
    this.deviceList = list
    
    Logger.info(TAG, `ready, device list=${JSON.stringify(this.deviceList)}`)
    
    this.callback()
    
      }
    
    
    
      deviceStateChangeActionOffline(device: deviceManager.DeviceBasicInfo) {
    
    if (this.deviceList.length <= 0) {
    
      this.callback()
    
      return
    
    }
    
    for (let j = 0; j < this.deviceList.length; j++) {
    
      if (this.deviceList[j].deviceId === device.deviceId) {
    
        this.deviceList[j] = device
    
        break
    
      }
    
    }
    
    Logger.info(TAG, `offline, device list=${JSON.stringify(this.deviceList)}`)
    
      }
    
    
    
      getLocalDevice(): string {
    
    Logger.info(TAG, `getLocalDevice`);
    
    if(this.deviceManager != undefined) {
    
      let deviceId: string = this.deviceManager.getLocalDeviceId();
    
      Logger.info(TAG, `local deviceInfo=${JSON.stringify(deviceId)}`);
    
      return deviceId;
    
    }
    
    return ''
    
      }
    
    
    
      registerDeviceListCallbackImplement(callback: () => void) {
    
    Logger.info(TAG, 'registerDeviceListCallback' + JSON.stringify(this.deviceManager))
    
    this.callback = callback
    
    if (this.deviceManager === undefined) {
    
      Logger.error(TAG, 'deviceManager has not initialized')
    
      this.callback()
    
      return
    
    }
    
    Logger.info(TAG, 'getTrustedDeviceListSync begin' + JSON.stringify(this.deviceManager));
    
    let list = this.deviceManager.getAvailableDeviceListSync();
    
    Logger.info(TAG, `getTrustedDeviceListSync end, deviceList=${JSON.stringify(list)}`)
    
    if (typeof (list) !== 'undefined' && typeof (list.length) !== 'undefined') {
    
      this.deviceList = list
    
    }
    
    this.callback()
    
    Logger.info(TAG, 'callback finished')
    
    this.deviceManager.on('deviceStateChange', (data) => {
    
      Logger.info(TAG, 'deviceStateChange on:' + JSON.stringify(data));
    
      if (data === null) {
    
        return
    
      }
    
      switch (data.action) {
    
        case deviceManager.DeviceStateChange.UNKNOWN:
    
          this.deviceStateChangeActionOnline(data.device)
    
          break
    
        case deviceManager.DeviceStateChange.AVAILABLE:
    
          this.deviceStateChangeActionReady(data.device)
    
          break
    
        case deviceManager.DeviceStateChange.UNAVAILABLE:
    
          this.deviceStateChangeActionOffline(data.device)
    
          break
    
        default:
    
          break
    
      }
    
    })
    
    this.deviceManager.on('discoverSuccess', (data: Data) => {
    
      if (data === null) {
    
        return
    
      }
    
      Logger.info(TAG, `discoverSuccess data=${JSON.stringify(data)}`);
    
      this.deviceFound(data);
    
    })
    
    this.deviceManager.on('discoverFailure', (data) => {
    
      Logger.info(TAG, `discoverFailure data=${JSON.stringify(data)}`);
    
    })
    
    this.deviceManager.on('serviceDie', () => {
    
      Logger.info(TAG, 'serviceDie')
    
    })
    
    this.startDeviceDiscovery()
    
      }
    
    
    
      deviceFound(data: Data) {
    
    if(data != undefined) {
    
      if (data.device != undefined) {
    
        for (let i = 0; i < this.discoverList.length; i++) {
    
          if (this.discoverList[i].deviceId === data.device.deviceId) {
    
            Logger.info(TAG, 'device founded ignored')
    
            return
    
          }
    
        }
    
        this.discoverList[this.discoverList.length] = data.device
    
        Logger.info(TAG, `deviceFound self.discoverList=${JSON.stringify(this.discoverList)}`);
    
        this.callback()
    
      }
    
    }
    
      }
    
    
    
      startDeviceDiscovery() {
    
    let discoverParam: Record<string, number> = {
    
      'discoverTargetType': 1
    
    };
    
    let filterOptions: Record<string, number> = {
    
      'availableStatus': 0
    
    };
    
    Logger.info(TAG, `startDeviceDiscovery${SUBSCRIBE_ID}`);
    
    try {
    
      if(this.deviceManager != undefined) {
    
        this.deviceManager.startDiscovering(discoverParam, filterOptions);
    
      }
    
    } catch (error) {
    
      Logger.error(TAG, `startDeviceDiscovery throw error, code: ${(error as BusinessError).code} message: ${(error as BusinessError).message}`);
    
    }
    
      }
    
    
    
      unregisterDeviceListCallback() {
    
    if(this.deviceManager != undefined) {
    
      Logger.info(TAG, `stopDeviceDiscovery${SUBSCRIBE_ID}`);
    
      this.deviceManager.stopDiscovering();
    
      this.deviceManager.off('deviceStateChange');
    
      this.deviceManager.off('discoverSuccess');
    
      this.deviceManager.off('discoverFailure');
    
      this.deviceManager.off('serviceDie');
    
    }
    
    this.deviceList = [];
    
    this.discoverList = [];
    
      }
    
    
    
      authenticateDevice(device: deviceManager.DeviceBasicInfo, callBack: (device: deviceManager.DeviceBasicInfo) => void) {
    
    Logger.info(TAG, `bindTarget${JSON.stringify(device)}`);
    
    for (let i = 0; i < this.discoverList.length; i++) {
    
      if (this.discoverList[i].deviceId !== device.deviceId) {
    
        continue
    
      }
    
      if (this.deviceManager === undefined) {
    
        return
    
      }
    
      try {
    
        if (this.deviceManager !== null) {
    
          this.deviceManager.bindTarget(device.deviceId, {
    
            bindType: 1,
    
            targetPkgName: BUNDLE,
    
            appName: 'Distributed distributedrdb',
    
          }, (err, data) => {
    
            if (err) {
    
              Logger.error(TAG, `authenticateDevice throw error, code: ${(err as BusinessError).code} message: ${(err as BusinessError).message}`);
    
              this.authCallback = () => {
    
              }
    
              return
    
            }
    
            Logger.debug(TAG, `authenticateDevice succeed: ${JSON.stringify(data)}`);
    
            this.authCallback = callBack;
    
          })
    
        }
    
      } catch (error) {
    
        Logger.error(TAG, `authenticateDevice throw error, code: ${(error as BusinessError).code} message: ${(error as BusinessError).message}`);
    
      }
    
    }
    
      }
    
    }
    
    
    
    export default new RemoteDeviceModel()
  • 设备同步:设备同步数据需要[ohos.permission.DISTRIBUTED_DATASYNC] 权限,在页面渲染前申请权限,源码参考[Index.ets],
/*

 * Copyright (c) 2022-2023 Huawei Device 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 data_rdb from '@ohos.data.relationalStore'

import common from '@ohos.app.ability.common'

import Want from '@ohos.app.ability.Want'

import router from '@ohos.router'

import Contact from '../model/Contact'

import ContactDataSource from '../common/BasicDataSource'

import LiteStore from '../model/LiteStore'

import Logger from '../model/Logger'

import RdbModel from '../model/RdbModel'

import { BottomBtn } from '../common/BottomBtn'

import { ContactItem } from '../common/ContactItem'

import { PopupMenu } from '../common/PopupMenu'

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'



const TAG: string = 'Index'



export interface stateType {

  popupMenu: boolean,

  isDistributed: boolean,

  isStage: boolean,

  selectedIndex: number,

  syncState: string,

  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

  @State contacts: ContactDataSource = new ContactDataSource([])

  @State isMultiCheck: boolean = false

  @State isSelectedAll: boolean = false

  @State state: stateType = {

    popupMenu: false,

    isDistributed: false,

    isStage: false,

    selectedIndex: 0,

    syncState: SyncState.ManualSync,

    distributedDevice: '',

    opacityValue: 1

  }



  async aboutToAppear() {

    Logger.info(TAG, 'aboutToAppear')

    await this.rdbModel.getRdbStore();

    await this.getData();

  }



  // 拉起应用后读取数据,暂定为分布式功能

  getWant() {

    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

        this.state.isDistributed = false

        this.state.selectedIndex = 0

        this.state.distributedDevice = ''

        this.rdbModel.offDataChange()

      }

      if (!this.state.isDistributed && want.parameters.isStage === 'Stage') {

        Logger.info(TAG, 'isStage = Stage')

        this.state.isStage = true

        this.state.isDistributed = true

        this.state.distributedDevice = want.parameters.dmsSrcNetworkId as string;

        let context = getContext(this) as common.UIAbilityContext

        context.startAbility({

          bundleName: BUNDLE,

          abilityName: ABILITY,

          deviceId: this.state.distributedDevice,

          parameters: {

            isStage: 'CONNECT'

          }

        })

        Logger.info(TAG, 'onDataChange')

        this.rdbModel.onDataChange(this.state.distributedDevice, (result: Array<Contact>)=> {

        this.contacts.dataArray = result

          this.contacts.notifyDataReload()

        })

      }

    }

  }



  async onPageShow() {

    try {

      // 初始化分部署数据库

      await this.rdbModel.getRdbStore()

      this.intervalId = setInterval(() => {

        // 手动侦听应用被拉起的动作

        this.getWant()

      }, 1000)

      // 读取数据库数据

      await this.getData()

    } catch (err) {

      Logger.error('onPageShow:' + JSON.stringify(err))

    }

  }



  async getData() {

    Logger.info(TAG, 'getData')

    // 初始化数据库的表,表名为contact

    let predicates = new data_rdb.RdbPredicates(TABLE_NAME)

    // 读取表中的数据

    this.contacts.replaceDataArray(await this.rdbModel.query(predicates));

    // 通知懒加载数据变更

    this.contacts.notifyDataReload()

    Logger.info(TAG, 'getData contacts count' + this.contacts.dataArray.length)

    // 读取Preferences中的数据

    let syncState = await this.liteStore.getValue()

    this.state.syncState = `${syncState}`

    if (!this.state.isStage && this.state.isDistributed && syncState === SyncState.AutomaticSync) {

      await this.syncData()

    }

  }



  showDeleteDialog() {

    let deleteContacts: Contact[] = []

    this.contacts.dataArray.forEach((contact) => {

      if (contact.isSelected) {

        deleteContacts.push(contact)

      }

    })

    if (deleteContacts.length == 0) {

      return

    }

    AlertDialog.show({

      message: $r('app.string.delete_contact'),

      primaryButton: {

        value: $r('app.string.sure'),

        fontColor: Color.Red,

        action: async () => {

          await this.rdbModel.deleteContacts(deleteContacts)

          await this.getData()

          this.quitMultiCheck()

        }

      },

      secondaryButton: {

        value: $r('app.string.cancel'),

        fontColor: Color.Blue,

        action: () => {

        }

      }

    })

  }



  handleClickContact(item: Contact, index: number) {

    Logger.info(TAG, `handleClickContact, item = ${JSON.stringify(item)}`)

    if (this.isMultiCheck) {

      let tempContacts = this.contacts.dataArray

      this.contacts.dataArray = []

      tempContacts[index].isSelected = !item.isSelected

      this.contacts.dataArray = tempContacts

      this.contacts.notifyDataReload()

    } else {

      router.pushUrl({

        url: 'pages/ContactEdit',

        params: { contact: item, isInsert: false }

      })

    }

  }



  refreshSelectState(isSelect: boolean) {

    this.contacts.dataArray.forEach((contact) => {

      contact.isSelected = isSelect

    })

    this.contacts.notifyDataReload()

  }



  quitMultiCheck() {

    this.isSelectedAll = false

    this.refreshSelectState(this.isSelectedAll)

    this.isMultiCheck = false

  }



  handleBottomBtnClick = (index: number) => {

    switch (index) {

      case 0:

        this.isSelectedAll = !this.isSelectedAll

        this.refreshSelectState(this.isSelectedAll)

        break

      case 1:

        this.showDeleteDialog()

        break

      case 2:

        this.quitMultiCheck()

        break

      default:

        break

    }

  }

  handleRightBtn = () => {

    this.state.popupMenu = true;

    this.state.opacityValue = 1;

  }

  syncData = () => {

    Logger.info(TAG, 'sync data')

    let predicates = new data_rdb.RdbPredicates(TABLE_NAME)

    predicates.inAllDevices()

    this.rdbModel.syncData(predicates)

  }



  build() {

    Stack({ alignContent: Alignment.BottomEnd }) {

      Column() {

        Stack() {

          if (this.state.isStage) {

            TitleBar()

          } else {

            TitleBar({ rightBtn: $r('app.media.more'), handleRightBtn: this.handleRightBtn })

          }

          if (this.state.isDistributed && !this.state.isStage && this.state.syncState === SyncState.ManualSync) {

            Row() {

              Blank()



              Image($r('app.media.ic_syncto'))

                .size({ width: 50, height: 60 })

                .onClick(this.syncData)

            }.width('80%')

          }

        }.width('100%')



        SearchBar()

        List() {

          LazyForEach(this.contacts, (item: Contact, index) => {

            ListItem() {

              ContactItem({ contact: item, isMultiCheck: $isMultiCheck })

            }

            .onClick(() => {

              this.handleClickContact(item, index)

            })

          }, (item: Contact) => JSON.stringify(item))

        }

        .width('100%')

        .layoutWeight(1)

        .padding({ left: 10, right: 10 })

        .divider({ strokeWidth: 1, color: Color.Gray, startMargin: 16, endMargin: 16 })

      }

      .width('100%')

      .height('100%')



      if (this.state.popupMenu) {

        PopupMenu({ state: $state, handleStartAbility: this.syncData })

      }



      BottomBtn({

        isMultiCheck: this.isMultiCheck,

        isSelectedAll: this.isSelectedAll,

        handleBottomBtnClick: this.handleBottomBtnClick

      })



      if (!this.isMultiCheck && !this.state.isStage) {

        Button() {

          Image($r('app.media.add'))

            .height('100%')

            .width('100%')

            .objectFit(ImageFit.Contain)

            .align(Alignment.End)

        }

        .id('btnAdd')

        .width(80)

        .height(80)

        .margin({ right: 20, bottom: 50 })

        .type(ButtonType.Circle)

        .backgroundColor('#0D9FFB')

        .onClick(() => {

          Logger.info(TAG, 'onClick')

          router.pushUrl({

            url: 'pages/ContactEdit',

            params: { contact: new Contact(0, '', 0, '', -1, ''), isInsert: true }

          })

        })

      }

    }

    .width('100%')

    .height('100%')

  }



  onBackPress() {

    Logger.info(TAG, 'onBackPress')

    let context = getContext(this) as common.UIAbilityContext

    context.startAbility({

      bundleName: BUNDLE,

      abilityName: ABILITY,

      deviceId: this.state.distributedDevice,

      parameters: {

        isStage: 'EXIT'

      }

    })

    this.rdbModel.offDataChange()

  }



  onPageHide() {

    Logger.info(TAG, 'onBackPress')

    clearInterval(this.intervalId)

  }

}

使用[@ohos.distributedDeviceManager]接口,首先通过createDeviceManager创建设备管理器实例,然后通过getTrustedDeviceListSync同步获取所有可信设备列表;

  • 设备连接:首先通过on方法注册设备状态,例如发现设备,设备连接失败,然后通过startDeviceDiscovery方法发现周边设备,然后选择连接设备,再用[startAbility]启动连接设备的应用。

烧脑猴
24 声望21 粉丝

5年JAVA,3年Android。现转入鸿蒙开发行业,每日分享一些鸿蒙技术!