鸿蒙OS开发案例:【Stage模型卡片】

电子说

1.3w人已加入

描述

Stage模型卡片

介绍

本示例展示了Stage模型卡片提供方的创建与使用。

用到了卡片扩展模块接口,[@ohos.app.form.FormExtensionAbility] 。

卡片信息和状态等相关类型和枚举接口,[@ohos.app.form.formInfo] 。

卡片提供方相关接口的能力接口,[@ohos.app.form.formProvider] 。

应用组件间的信息传递接口,[@ohos.app.ability.Want]。

效果预览

鸿蒙OS

鸿蒙OS

概念

Ability:Ability是应用所具备能力的抽象,也是应用程序的重要组成部分。Ability是系统调度应用的最小单元,是能够完成一个独立功能的组件。

鸿蒙OS

具体实现

1、在module.json5文件添加拓展能力,类型为卡片,并设置卡片入口srcEntrance和卡片元数据metadata。[源码参考] 例如:"metadata": [ { "name": "ohos.extension.form", "resource": "$profile:form_config" }。

/*

 * Copyright (c) 2022 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.

 */



{

  "module": {

    "name": "entry",

    "type": "entry",

    "srcEntrance": "./ets/Application/AbilityStage.ts",

    "description": "$string:entry_desc",

    "mainElement": "MainAbility",

    "deviceTypes": [

      "default",

      "tablet",

    ],

    "deliveryWithInstall": true,

    "installationFree": false,

    "pages": "$profile:main_pages",

    "uiSyntax": "ets",

    "abilities": [

      {

        "name": "ohos.samples.formextability.MainAbility",

        "srcEntrance": "./ets/MainAbility/MainAbility.ts",

        "description": "$string:MainAbility_desc",

        "icon": "$media:icon",

        "label": "$string:MainAbility_label",

        "visible": true,

        "skills": [

          {

            "entities": [

              "entity.system.home",

            ],

            "actions": [

              "action.system.home",

            ],

          },

        ],

        "startWindowIcon": "$media:icon",

        "startWindowBackground": "$color:white"

      },

    ],

    "extensionAbilities": [

      {

        "name": "FormAbility",

        "srcEntrance": "./ets/FormAbility/FormAbility.ts",

        "label": "$string:form_FormAbility_label",

        "description": "$string:form_FormAbility_desc",

        "type": "form",

        "metadata": [

          {

            "name": "ohos.extension.form",

            "resource": "$profile:form_config",

          },

        ],

      },

    ],

  },

}

2、初始化卡片:通过实现@ohos.app.form.FormExtensionAbility卡片操作类,在卡片对象首次被创建时,初始化卡片绑定数据为空,并将卡片状态设置为就绪状态READY。 例如:onCreate(){ formBindingData.createFormBindingData({}) onAcquireFormState(want) { return formInfo.FormState.READY }。
3、配置卡片:用js编写相应的卡片,将卡片配置到resources/base/profile/form_config, [源码参考]。

{

  "forms": [

    {

      "name": "widget",

      "description": "This is a service widget.",

      "src": "./js/widget/pages/index/index",

      "formConfigAbility": "ability://ohos.samples.formextability.MainAbility",

      "window": {

        "designWidth": 720,

        "autoDesignWidth": true

      },

      "colorMode": "auto",

      "isDefault": true,

      "updateEnabled": true,

      "scheduledUpdateTime": "10:30",

      "updateDuration": 0,

      "defaultDimension": "2*4",

      "supportDimensions": [

        "2*4",

        "4*4"

      ]

    }

  ]

}
  • 修改数据卡片的订阅条件的功能封装在ModifyConditionIndex.ets中,源码参考:[ModifyConditionIndex.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 base from '@ohos.base';

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

import dataShare from '@ohos.data.dataShare';

import formBindingData from '@ohos.app.form.formBindingData';

import formInfo from '@ohos.app.form.formInfo';

import formObserver from '@ohos.app.form.formObserver';

import formProvider from '@ohos.app.form.formProvider';

import Logger from '../../common/Logger';

import { getPersistentConditionID, savePersistentConditionID } from '../../common/StatePersistence';



const TAG = '[Sample_ModifyConditionIndex]';

let dataShareHelper: dataShare.DataShareHelper;

let conditionID = '110000';

let context: common.UIAbilityContext;



function updateCardDisplayContent(runningFormInfo: formInfo.RunningFormInfo): void {

  Logger.info(`TAG updateCardDisplayContent bundle: ${runningFormInfo.bundleName}`);

  let template: dataShare.Template = {

    predicates: {

      list: `select cityTemperature as cityTemperature, cityName as cityName from TBL00 where cityId = ${conditionID}`

    },

    scheduler: ''

  };

  dataShare.createDataShareHelper(context, 'datashareproxy://ohos.samples.formextability', { isProxy: true })

    .then((data: dataShare.DataShareHelper) = > {

      dataShareHelper = data;

      dataShareHelper.addTemplate('datashareproxy://ohos.samples.formextability/test', conditionID, template);

    });



  class ProxiesType {

    key: string = '';

    subscriberId: string = '';

  };



  let proxies = [{

    key: 'datashareproxy://ohos.samples.formextability/test',

    subscriberId: conditionID

  } as ProxiesType];

  let formData: string = '';

  Logger.info(TAG, `formData: ${JSON.stringify(formData)}`);

  let formBinding = formBindingData.createFormBindingData(formData);

  formBinding['proxies'] = proxies;

  formProvider.updateForm(runningFormInfo.formId, formBinding).then(() = > {

    Logger.info(TAG, `update Form OK formData is ${JSON.stringify(formBinding)}`);

  }).catch((err: base.BusinessError< void >) = > {

    Logger.error(TAG, `update Form Failed ${JSON.stringify(err)}`);

  });

}



function modifyCondition(): void {

  let formInstanceFilterArkTS: formInfo.FormProviderFilter = {

    bundleName: 'ohos.samples.formextability',

    abilityName: 'EntryFormAbility',

    formName: 'persistentWidget',

    moduleName: 'persistentProxyForm'

  };

  let formInstanceFilterJS: formInfo.FormProviderFilter = {

    bundleName: 'ohos.samples.formextability',

    abilityName: 'EntryFormAbility',

    formName: 'persistentWidgetJS',

    moduleName: 'persistentProxyForm'

  };

  formObserver.getRunningFormInfosByFilter(formInstanceFilterArkTS).then((data: Array< formInfo.RunningFormInfo >) = > {

    Logger.info(TAG, `getRunningFormInfosByFilter data: ${JSON.stringify(data)}`);

    AppStorage.SetOrCreate('runningFormInfo', JSON.stringify(data));

    data.forEach(updateCardDisplayContent);

  }).catch((err: base.BusinessError< void >) = > {

    Logger.error(TAG, `getRunningFormInfosByFilter err is ${JSON.stringify(err)}`);

  });

  formObserver.getRunningFormInfosByFilter(formInstanceFilterJS).then((data: Array< formInfo.RunningFormInfo >) = > {

    Logger.info(TAG, `getRunningFormInfosByFilter data: ${JSON.stringify(data)}`);

    AppStorage.SetOrCreate('runningFormInfo', JSON.stringify(data));

    data.forEach(updateCardDisplayContent);

  }).catch((err: base.BusinessError< void >) = > {

    Logger.error(TAG, `getRunningFormInfosByFilter err is ${JSON.stringify(err)}`);

  });

}



@Entry

@Component

struct IndexThi {

  @State persistentConditionID: string = '';

  @State persistentSwitchFlag: boolean = true;



  aboutToAppear() {

    context = getContext(this) as common.UIAbilityContext;

    this.persistentConditionID = getPersistentConditionID(context);

    if (typeof this.persistentConditionID !== 'string' || this.persistentConditionID === '') {

      this.persistentConditionID = '110000'

    }

    this.persistentSwitchFlag = this.persistentConditionID.localeCompare('110000') === 0;

    Logger.debug(TAG, `persistentSwitchFlag : ${JSON.stringify(this.persistentSwitchFlag)}`);

  }



  aboutToDisappear() {

    savePersistentConditionID(context, this.persistentConditionID);

  }



  build() {

    Row() {

      Column({ space: 150 }) {

        Text($r('app.string.subscription_conditions'))

          .fontColor('#182431')

          .fontSize(40)

          .lineHeight(41)

          .fontWeight('Bold')

        Column() {

          Text($r('app.string.modify_subscription_conditions'))

            .fontSize(28)

            .margin({ bottom: 20 })

          Row() {

            Flex({ justifyContent: FlexAlign.SpaceEvenly }) {

              Column() {

                Text($r('app.string.city_sy'))

                  .margin({ bottom: 10 })

                Radio({ value: 'sy', group: 'modifyConditionGroup' })

                  .checked(this.persistentSwitchFlag)

                  .height(24)

                  .width(24)

                  .radioStyle({

                    checkedBackgroundColor: $r('sys.color.ohos_id_color_text_primary_activated'),

                    uncheckedBorderColor: $r('sys.color.ohos_id_color_switch_outline_off'),

                    indicatorColor: $r('sys.color.ohos_id_color_foreground_contrary')

                  })

                  .onChange((isChecked: boolean) = > {

                    Logger.info('firstRadio status is ' + isChecked);

                    if (isChecked) {

                      conditionID = '110000';

                      this.persistentConditionID = conditionID;

                      modifyCondition();

                    }

                  })

              }



              Column() {

                Text($r('app.string.city_hz'))

                  .margin({ bottom: 10 })

                Radio({ value: 'hz', group: 'modifyConditionGroup' })

                  .checked(!this.persistentSwitchFlag)

                  .height(24)

                  .width(24)

                  .radioStyle({

                    checkedBackgroundColor: $r('sys.color.ohos_id_color_text_primary_activated'),

                    uncheckedBorderColor: $r('sys.color.ohos_id_color_switch_outline_off'),

                    indicatorColor: $r('sys.color.ohos_id_color_foreground_contrary')

                  })

                  .onChange((isChecked: boolean) = > {

                    Logger.info('secondRadio status is ' + isChecked);

                    if (isChecked) {

                      conditionID = '310000';

                      this.persistentConditionID = conditionID;

                      modifyCondition();

                    }

                  })

              }

            }

          }

          .width('70%')

        }

        .width('100%')

      }

    }

    .height('100%')

  }

}

及[ModifyConditionIndex.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 base from '@ohos.base';

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

import formBindingData from '@ohos.app.form.formBindingData';

import formInfo from '@ohos.app.form.formInfo';

import formObserver from '@ohos.app.form.formObserver';

import formProvider from '@ohos.app.form.formProvider';

import Logger from '../../common/Logger';

import { getProcessConditionID, saveProcessConditionID } from '../../common/StatePersistence';



const TAG = '[Sample_ModifyConditionIndex]';

let conditionID = '110000';

let context: common.UIAbilityContext;



function updateCardDisplayContent(runningFormInfo: formInfo.RunningFormInfo): void {

  Logger.info(TAG, `updateCardDisplayContent bundle: ${runningFormInfo.bundleName}`);

  let proxies:Array< formBindingData.ProxyData > = [

    {

      key: 'cityName',

      subscriberId: conditionID

    },

    {

      key: 'cityTemperature',

      subscriberId: conditionID

    }

  ];

  let formBinding = formBindingData.createFormBindingData();

  formBinding['proxies'] = proxies;

  formProvider.updateForm(runningFormInfo.formId, formBinding).then(() = > {

    Logger.info(TAG, `update Form OK formData is ${JSON.stringify(formBinding)}`);

  }).catch((err: base.BusinessError< void >) = > {

    Logger.error(TAG, `update Form Failed ${JSON.stringify(err)}`);

  });

}



function modifyCondition(): void {

  let formInstanceFilter: formInfo.FormProviderFilter = {

    bundleName: 'ohos.samples.formextability',

    moduleName: 'processProxyForm'

  };

  formObserver.getRunningFormInfosByFilter(formInstanceFilter).then((data: Array< formInfo.RunningFormInfo >) = > {

    Logger.info(TAG, `getRunningFormInfosByFilter data: ${JSON.stringify(data)}`);

    AppStorage.SetOrCreate('runningFormInfo', JSON.stringify(data));

    data.forEach(updateCardDisplayContent);

  }).catch((err: base.BusinessError< void >) = > {

    Logger.error(TAG, `getRunningFormInfosByFilter err is ${JSON.stringify(err)}`);

  });

}



@Entry

@Component

struct IndexThi {

  @State processConditionID: string = '';

  @State processSwitchFlag: boolean = true;



  aboutToAppear() {

    context = getContext(this) as common.UIAbilityContext;

    this.processConditionID = getProcessConditionID(context);

    if (typeof this.processConditionID !== 'string' || this.processConditionID === '') {

      this.processConditionID = '110000'

    }

    this.processSwitchFlag = this.processConditionID.localeCompare('110000') === 0;

    Logger.debug(TAG, `persistentSwitchFlag : ${JSON.stringify(this.processSwitchFlag)}`);

  }



  aboutToDisappear() {

    saveProcessConditionID(context, this.processConditionID);

  }



  build() {

    Row() {

      Column({ space: 150 }) {

        Text($r('app.string.subscription_conditions'))

          .fontColor('#182431')

          .fontSize(40)

          .lineHeight(41)

          .fontWeight('100%')

        Column() {

          Text($r('app.string.modify_subscription_conditions'))

            .fontSize(28)

            .margin({ bottom: 20 })

          Row() {

            Flex({ justifyContent: FlexAlign.SpaceEvenly }) {

              Column() {

                Text($r('app.string.city_sy'))

                  .margin({ bottom: 10 })

                Radio({ value: 'sy', group: 'modifyConditionGroup' })

                  .height(24)

                  .width(24)

                  .radioStyle({

                    checkedBackgroundColor: $r('sys.color.ohos_id_color_text_primary_activated'),

                    indicatorColor: $r('sys.color.ohos_fa_foreground_contrary'),

                    uncheckedBorderColor: $r('sys.color.ohos_id_color_switch_outline_off') })

                  .checked(this.processSwitchFlag)

                  .onChange((isChecked: boolean) = > {

                    Logger.info('firstRadio status is ' + isChecked);

                    if (isChecked) {

                      conditionID = '110000';

                      this.processConditionID = conditionID;

                      modifyCondition();

                    }

                  })

              }



              Column() {

                Text($r('app.string.city_hz'))

                  .margin({ bottom: 10 })

                Radio({ value: 'hz', group: 'modifyConditionGroup' })

                  .height(24)

                  .width(24)

                  .checked(!this.processSwitchFlag)

                  .radioStyle({

                    checkedBackgroundColor: $r('sys.color.ohos_id_color_text_primary_activated'),

                    indicatorColor: $r('sys.color.ohos_fa_foreground_contrary'),

                    uncheckedBorderColor: $r('sys.color.ohos_id_color_switch_outline_off') })

                  .onChange((isChecked: boolean) = > {

                    Logger.info('secondRadio status is ' + isChecked);

                    if (isChecked) {

                      conditionID = '310000';

                      this.processConditionID = conditionID;

                      modifyCondition();

                    }

                  })

              }

            }

          }

          .width('70%')

        }

        .width('100%')

      }

    }

    .height('100%')

  }

}
  • 使用modifyCondition来获取所有已经建立出的卡片对象。
  • 修改订阅条件:使用updateCardDisplayContent遍历所有卡片对象,并根据界面获取的订阅条件数据修改订阅条件。
    • 退出页面或应用后再次打开修改订阅条件页面,可以保留上次订阅的城市选择,源码参考:[StatePersistence.ts]
/*

 * 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 type common from '@ohos.app.ability.common';

import fs from '@ohos.file.fs';

import Logger from './Logger';



const TAG = '[Sample_StatePersistence]';

const DATA_SIZE = 6;

const PERSISTENT_FILE_NAME = '/Persistent.txt';



function getConditionIDtoFile(context: common.Context, fileName: string): string {

  Logger.debug(TAG, 'getConditionIDtoFile call');

  if (context === undefined || context === null || typeof fileName !== 'string' || fileName === '') {

    Logger.error(TAG, `getConditionIDtoFile failed, context : ${JSON.stringify(context)}`);

    return '';

  }



  try {

    let filePath = context.filesDir + fileName;

    let file = fs.openSync(filePath, fs.OpenMode.READ_ONLY);

    let buff = new ArrayBuffer(DATA_SIZE);

    let num = fs.readSync(file.fd, buff);

    let conditionID = String.fromCharCode.apply(null, new Uint8Array(buff));

    Logger.info(TAG, `getConditionIDtoFile : ${conditionID.length} ${conditionID}, ${num} ${filePath}`);

    fs.closeSync(file);

    return conditionID;

  } catch (err) {

    Logger.error(TAG, `getConditionIDtoFile err : ${JSON.stringify(err)}`);

    return '';

  }

}



function updateConditionIDtoFile(context: common.Context, conditionID: string, fileName: string): void {

  Logger.debug(TAG, 'updateConditionIDtoFile call');

  if (context === undefined || context === null ||

  typeof conditionID !== 'string' || conditionID === '' ||

  typeof fileName !== 'string' || fileName === '') {

    Logger.error(TAG, `updateConditionIDtoFile failed, conditionID : ${JSON.stringify(conditionID)}, context : ${JSON.stringify(context)}`);

    return;

  }



  try {

    let filePath = context.filesDir + fileName;

    let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);

    let num = fs.writeSync(file.fd, conditionID);

    fs.closeSync(file);

    Logger.info(TAG, `updateConditionIDtoFile : ${conditionID}, ${num} ${filePath}`);

  } catch (err) {

    Logger.error(TAG, `updateConditionIDtoFile err : ${JSON.stringify(err)}`);

  }

}



export function getPersistentConditionID(context: common.Context): string {

  return getConditionIDtoFile(context, PERSISTENT_FILE_NAME);

}



export function savePersistentConditionID(context: common.Context, conditionID: string): void {

  updateConditionIDtoFile(context, conditionID, PERSISTENT_FILE_NAME);

}

及[StatePersistence.ts]。

/*

 * 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 type common from '@ohos.app.ability.common';

import fs from '@ohos.file.fs';

import Logger from './Logger';



const TAG = '[Sample_StatePersistence]';

const DATA_SIZE = 6;

const PROCESS_FILE_NAME = '/Process.txt';



function getConditionIDtoFile(context: common.Context, fileName: string): string {

  Logger.debug(TAG, 'getConditionIDtoFile call');

  if (context === undefined || context === null || typeof fileName !== 'string' || fileName === '') {

    Logger.error(TAG, `getConditionIDtoFile failed, context : ${JSON.stringify(context)}`);

    return '';

  }



  try {

    let filePath = context.filesDir + fileName;

    let file = fs.openSync(filePath, fs.OpenMode.READ_ONLY);

    let buff = new ArrayBuffer(DATA_SIZE);

    let num = fs.readSync(file.fd, buff);

    let conditionID = String.fromCharCode.apply(null, new Uint8Array(buff));

    Logger.info(TAG, `getConditionIDtoFile : ${conditionID.length} ${conditionID}, ${num} ${filePath}`);

    fs.closeSync(file);

    return conditionID;

  } catch (err) {

    Logger.error(TAG, `getConditionIDtoFile err : ${JSON.stringify(err)}`);

    return '';

  }

}



function updateConditionIDtoFile(context: common.Context, conditionID: string, fileName: string): void {

  Logger.debug(TAG, 'updateConditionIDtoFile call');

  if (context === undefined || context === null ||

  typeof conditionID !== 'string' || conditionID === '' ||

  typeof fileName !== 'string' || fileName === '') {

    Logger.error(TAG, `updateConditionIDtoFile failed, conditionID : ${JSON.stringify(conditionID)}, context : ${JSON.stringify(context)}`);

    return;

  }



  try {

    let filePath = context.filesDir + fileName;

    let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);

    let num = fs.writeSync(file.fd, conditionID);

    fs.closeSync(file);

    Logger.info(TAG, `updateConditionIDtoFile : ${conditionID}, ${num} ${filePath}`);

  } catch (err) {

    Logger.error(TAG, `updateConditionIDtoFile err : ${JSON.stringify(err)}`);

  }

}



export function getProcessConditionID(context: common.Context): string {

  return getConditionIDtoFile(context, PROCESS_FILE_NAME);

}



export function saveProcessConditionID(context: common.Context, conditionID: string): void {

  updateConditionIDtoFile(context, conditionID, PROCESS_FILE_NAME);

}
  • 发布数据的功能封装在PublishIndex.ets及PushIndex.ets中,源码参考:[PublishIndex.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 base from '@ohos.base';

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

import dataShare from '@ohos.data.dataShare';

import dataSharePredicates from '@ohos.data.dataSharePredicates';

import formInfo from '@ohos.app.form.formInfo';

import formObserver from '@ohos.app.form.formObserver';

import prompt from '@ohos.promptAction';

import resourceManager from '@ohos.resourceManager';

import { ValuesBucket, ValueType } from '@ohos.data.ValuesBucket';

import Logger from '../../common/Logger';



const TAG = '[Sample_PublishIndex]';

let conditionCity: string;

let conditionID: ValueType = '110000';

let conditionData = '-30 ℃';

let context: common.UIAbilityContext;

let shenYang: string;

let hangZhou: string;

const formInstanceFilter: formInfo.FormProviderFilter = {

  bundleName: 'ohos.samples.formextability',

  moduleName: 'persistentProxyForm'

};



function updateRDB(context: common.UIAbilityContext): void {

  dataShare.createDataShareHelper(context, 'datashareproxy://ohos.samples.formextability', { isProxy: true })

    .then((data: dataShare.DataShareHelper) = > {

      Logger.info(TAG, `createDataShareHelper succeed, data :  ${JSON.stringify(data)}`);

      let dataShareHelper = data;

      let da = new dataSharePredicates.DataSharePredicates();

      da.equalTo('cityId', conditionID);

      let va: ValuesBucket = {

        cityName: conditionCity,

        cityTemperature: conditionData

      };

      try {

        let uri = 'datashareproxy://ohos.samples.formextability/test';

        dataShareHelper.update(uri, da, va, (err, data) = > {

          if (err !== undefined) {

            Logger.info(TAG, `update error1: code: ${err.code}, message: ${err.message} `);

            prompt.showToast(

              { message: `publish err: ${JSON.stringify(err)}`, duration: 5000 });

            return;

          }

          Logger.info(TAG, `update succeed, data : ${data}`);

          prompt.showToast(

            { message: `publish success ${conditionCity} ${conditionData}`, duration: 5000 });

        });

        dataShareHelper.notifyChange(uri);

      } catch (err) {

        Logger.info(TAG, `update error2: code: ${err.code}, message: ${err.message} `);

      }

    })

    .catch((err: base.BusinessError< void >) = > {

      Logger.info(TAG, `createDataShareHelper error: code: ${err.code}, message: ${err.message} `);

    });

}



function publish(): void {

  Logger.info(TAG, 'publish called');

  formObserver.getRunningFormInfosByFilter(formInstanceFilter).then((data: Array< formInfo.RunningFormInfo >) = > {

    Logger.info(TAG, `getRunningFormInfosByFilter data: ${JSON.stringify(data)}`);

    AppStorage.SetOrCreate('RunningFormInfo', JSON.stringify(data));

  }).catch((err: base.BusinessError< void >) = > {

    Logger.error(TAG, `getRunningFormInfosByFilter err is ${JSON.stringify(err)}`);

    prompt.showToast(

      { message: `publish err, getRunningFormInfosByFilter1 failed ${JSON.stringify(err)}`, duration: 5000 });

  });

}



@Entry

@Component

struct IndexSec {

  private inputText: string = '';



  aboutToAppear() {

    context = getContext(this) as common.UIAbilityContext;

    let syTemp = $r('app.string.city_sy');

    let hzTemp = $r('app.string.city_hz');

    let citySy: resourceManager.Resource = {

      bundleName: syTemp.bundleName,

      moduleName: syTemp.moduleName,

      id: syTemp.id

    };

    let cityHz: resourceManager.Resource = {

      bundleName: hzTemp.bundleName,

      moduleName: hzTemp.moduleName,

      id: hzTemp.id

    };

    shenYang = context.resourceManager.getStringSync(citySy);

    hangZhou = context.resourceManager.getStringSync(cityHz);

    conditionCity = shenYang;

  }



  @StorageLink('RunningFormInfo') RunningFormInfo: string = '';

  @State focus: boolean = false;



  build() {

    Row() {

      Column({ space: 200 }) {

        Column({ space: 5 }) {

          Text($r('app.string.modify_publish_data'))

            .fontColor('#182431')

            .fontSize(40)

            .lineHeight(41)

            .fontWeight('100%')

        }



        Column() {

          Column() {

            Row() {

              Text($r('app.string.selection_city'))

                .fontSize(30)

              Row() {

                Column() {

                  Text($r('app.string.city_sy'))

                    .fontSize(15)

                    .margin({ bottom: 10 })

                  Radio({ value: 'sy', group: 'cityGroup' })

                    .checked(true)

                    .height(24)

                    .width(24)

                    .radioStyle({

                      checkedBackgroundColor: $r('sys.color.ohos_id_color_text_primary_activated'),

                      uncheckedBorderColor: $r('sys.color.ohos_id_color_switch_outline_off'),

                      indicatorColor: $r('sys.color.ohos_id_color_foreground_contrary')

                    })

                    .onChange((isChecked: boolean) = > {

                      Logger.info(TAG, `sy status is ${JSON.stringify(isChecked)}`);

                      if (isChecked) {

                        conditionID = '110000';

                        conditionCity = shenYang;

                      }

                    })

                }



                Column() {

                  Text($r('app.string.city_hz'))

                    .fontSize(15)

                    .margin({ bottom: 10 })

                  Radio({ value: 'hz', group: 'cityGroup' })

                    .height(24)

                    .width(24)

                    .radioStyle({

                      checkedBackgroundColor: $r('sys.color.ohos_id_color_text_primary_activated'),

                      uncheckedBorderColor: $r('sys.color.ohos_id_color_switch_outline_off'),

                      indicatorColor: $r('sys.color.ohos_id_color_foreground_contrary')

                    })

                    .onChange((isChecked: boolean) = > {

                      Logger.info(TAG, `hz status is ${JSON.stringify(isChecked)}`);

                      if (isChecked) {

                        conditionID = '310000';

                        conditionCity = hangZhou;

                      }

                    })

                }

                .margin({ left: 20 })

              }

              .margin({ left: 10 })

            }



            Row() {

              Text($r('app.string.input_temperature'))

                .fontSize(30)

                .width(200)

                .height(60)

              TextInput({ text: '-30' })

                .fontSize(20)

                .fontColor($r('sys.color.ohos_id_color_text_primary'))

                .width(100)

                .height(40)

                .type(InputType.Normal)

                .borderRadius(16)

                .backgroundColor($r('sys.color.ohos_id_color_text_field_sub_bg'))

                .onChange((text) = > {

                  this.inputText = text;

                })

              Text('℃')

                .fontSize(30)

                .height(60)

            }

          }

          .alignItems(HorizontalAlign.Start)



          Button() {

            Text($r('app.string.published_data'))

              .fontColor($r('sys.color.ohos_id_color_foreground_contrary'))

              .fontSize($r('sys.float.ohos_id_text_size_button1'))

              .fontWeight(FontWeight.Bold)

          }

          .width(220)

          .height(40)

          .type(ButtonType.Capsule)

          .margin({ top: 20 })

          .borderRadius($r('sys.float.ohos_id_corner_radius_button'))

          .backgroundColor($r('sys.color.ohos_id_color_component_activated'))

          .onClick(() = > {

            if (Number(this.inputText) >= -40 && Number(this.inputText) <= 60) {

              Logger.info(TAG, `correct temperature is ${this.inputText}`);

              conditionData = this.inputText + ' ℃';

              publish();

              updateRDB(context);

            } else {

              Logger.info(TAG, `incorrect temperature is ${this.inputText}`);

              prompt.showToast({ message: 'Please enter the correct value from -40 to 60', duration: 5000 });

            }

          })

        }

        .height('30%')

      }

      .width('100%')

    }

    .height('100%')

  }

}

及[PushIndex.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 base from '@ohos.base';

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

import dataShare from '@ohos.data.dataShare';

import formInfo from '@ohos.app.form.formInfo';

import formObserver from '@ohos.app.form.formObserver';

import prompt from '@ohos.promptAction';

import Logger from '../../common/Logger';



const TAG = '[Sample_PushIndex]';

let context: common.UIAbilityContext;

let dataShareHelper: dataShare.DataShareHelper;

let uri = ('datashareproxy://ohos.samples.formextability');

let conditionCity = '';

let conditionID = '110000';

let conditionData = '-30 ℃';

let formInstanceFilter: formInfo.FormProviderFilter = {

  bundleName: 'ohos.samples.formextability',

  moduleName: 'processProxyForm'

};



function updateCardDisplayContent(runningFormInfo: formInfo.RunningFormInfo): void {

  Logger.info(TAG, `updateCardDisplayContent bundle: ${runningFormInfo.bundleName}`);

  dataShare.createDataShareHelper(context, uri, { isProxy: true }, (err, dataHelper) = > {

    Logger.info(TAG, `dataShareHelper err: ${err}`, `data: ${dataShareHelper}`);

    dataShareHelper = dataHelper;

    if (err !== undefined) {

      Logger.error(TAG, `createDataShareHelper error code: ${err.code}`, `message: ${err.message} `);

      prompt.showToast({ message: 'createDataShareHelper:' + err.message, duration: 5000 });

    } else {

      let publishedItemData: Array< dataShare.PublishedItem > = [

        { key: 'cityName', data: JSON.stringify(conditionCity), subscriberId: conditionID },

        { key: 'cityTemperature', data: JSON.stringify(conditionData), subscriberId: conditionID }

      ];

      dataShareHelper.publish(publishedItemData, 'ohos.samples.formextability').then((data: Object) = > {

        Logger.info(TAG, `publish success, data is ${JSON.stringify(data)}`);

        prompt.showToast(

          { message: `publish success ${conditionCity} ${conditionData}`, duration: 5000 });

      }).catch((err: base.BusinessError< void >) = > {

        Logger.error(TAG, `publish error: ${JSON.stringify(err)}`);

        prompt.showToast({ message: `publish err: ${JSON.stringify(err)}`, duration: 5000 });

      });

    }

  });

}



function publish(): void {

  Logger.info(TAG, 'publish called');

  formObserver.getRunningFormInfosByFilter(formInstanceFilter).then((data: Array< formInfo.RunningFormInfo >) = > {

    Logger.info(TAG, `getRunningFormInfosByFilter data: ${JSON.stringify(data)}`);

    AppStorage.SetOrCreate('runningFormInfo', JSON.stringify(data));

    data.forEach(updateCardDisplayContent);

  }).catch((err: base.BusinessError< void >) = > {

    Logger.error(TAG, `getRunningFormInfosByFilter err is ${JSON.stringify(err)}`);

    prompt.showToast(

      { message: `publish err, getRunningFormInfosByFilter failed ${JSON.stringify(err)}`, duration: 5000 });

  });

}



@Entry

@Component

struct IndexSec {

  @StorageLink('runningFormInfo') runningFormInfo: string = '';

  @State focus: boolean = false;



  aboutToAppear() {

    context = getContext(this) as common.UIAbilityContext;

    conditionCity = context.resourceManager.getStringSync($r('app.string.city_sy'));

  }



  build() {

    Row() {

      Column({ space: 200 }) {

        Column({ space: 5 }) {

          Text($r('app.string.modify_publish_data'))

            .fontColor('#182431')

            .fontSize(40)

            .lineHeight(41)

            .fontWeight('100%')

        }



        Column() {

          Column() {

            Row() {

              Text($r('app.string.selection_city'))

                .fontSize(30)

              Row() {

                Column() {

                  Text($r('app.string.city_sy'))

                    .fontSize(15)

                    .margin({ bottom: 10 })

                  Radio({ value: 'sy', group: 'cityGroup' })

                    .checked(true)

                    .height(24)

                    .width(24)

                    .radioStyle({

                      checkedBackgroundColor: $r('sys.color.ohos_id_color_text_primary_activated'),

                      indicatorColor: $r('sys.color.ohos_fa_foreground_contrary'),

                      uncheckedBorderColor: $r('sys.color.ohos_id_color_switch_outline_off') })

                    .onChange((isChecked: boolean) = > {

                      Logger.info(TAG, `sy status is ${JSON.stringify(isChecked)}`);

                      if (isChecked) {

                        conditionID = '110000';

                        conditionCity = context.resourceManager.getStringSync($r('app.string.city_sy'));

                      }

                    })

                }



                Column() {

                  Text($r('app.string.city_hz'))

                    .fontSize(15)

                    .margin({ bottom: 10 })

                  Radio({ value: 'hz', group: 'cityGroup' })

                    .height(24)

                    .width(24)

                    .radioStyle({

                      checkedBackgroundColor: $r('sys.color.ohos_id_color_text_primary_activated'),

                      indicatorColor: $r('sys.color.ohos_fa_foreground_contrary'),

                      uncheckedBorderColor: $r('sys.color.ohos_id_color_switch_outline_off') })

                    .onChange((isChecked: boolean) = > {

                      Logger.info(TAG, `hz status is ${JSON.stringify(isChecked)}`);

                      if (isChecked) {

                        conditionID = '310000';

                        conditionCity = context.resourceManager.getStringSync($r('app.string.city_hz'));

                      }

                    })

                }

                .margin({ left: 20 })

              }

              .margin({ left: 10 })

            }



            Row() {

              Text($r('app.string.input_temperature'))

                .fontSize(30)

                .width(200)

                .height(60)

              TextInput({ text: '-30' })

                .fontSize(20)

                .fontColor($r('sys.color.ohos_id_color_text_primary'))

                .width(100)

                .height(40)

                .type(InputType.Normal)

                .borderRadius(16)

                .backgroundColor($r('sys.color.ohos_id_color_text_field_sub_bg'))

                .onChange((text) = > {

                  conditionData = text;

                })

              Text('℃')

                .fontSize(30)

                .height(60)

            }

          }

          .alignItems(HorizontalAlign.Start)



          Button() {

            Text($r('app.string.published_data'))

              .fontColor($r('sys.color.ohos_id_color_foreground_contrary'))

              .fontSize($r('sys.float.ohos_id_text_size_button1'))

              .fontWeight(FontWeight.Bold)

          }

          .height(40)

          .width(220)

          .borderRadius($r('sys.float.ohos_id_corner_radius_button'))

          .backgroundColor($r('sys.color.ohos_id_color_component_activated'))

          .type(ButtonType.Capsule)

          .margin({ top: 20 })

          .onClick(() = > {

            if (Number(conditionData) >= -40 && Number(conditionData) <= 60) {

              Logger.info(TAG, `correct temperature is ${conditionData}`);

              publish();

            } else {

              Logger.info(TAG, `incorrect temperature is ${conditionData}`);

              prompt.showToast({ message: 'Please enter the correct value from -40 to 60', duration: 5000 });

            }

          })

        }

        .alignItems(HorizontalAlign.Center)

        .height('30%')

      }

      .width('100%')

    }

    .height('100%')

  }

}
更多鸿蒙开发应用知识已更新gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md参考前往。
  • [PublishIndex.ets]使用updateRDB来修改rdb数据库中的对应数据。
  • [PushIndex.ets]使用getRunningFormInfosByFilter获取已经建立出的卡片对象,并使用updateCardDisplayContent遍历所有卡片对象,使用createDataShareHelper创建DataShareHelper对象,并根据界面获取的数据信息使用publish进行数据的发布以实现发布数据的功能
  • 在dataShare模块中,建立rdb数据库,并提供对应update方法。
    • 在onCreate中初始化数据库中的数据。
    • 在update中实现对应的数据更新方法。
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分