首页 > 其他分享 >HarmonyOS实战一原子化服务初尝试(ClockFACardDemo学习)

HarmonyOS实战一原子化服务初尝试(ClockFACardDemo学习)

时间:2022-12-12 17:01:52浏览次数:73  
标签:卡片 int private formId HarmonyOS 原子化 ohos import ClockFACardDemo



写在前面

  • 看到有一个活动,所以准备在学习下,拥抱国产操作系统, 之前学​​HarmonyOS​​​ 照着官网写了一个​​Holle World​​​​(关于HarmonyOS的环境搭建,基本目录结构,简单Holle World实现)​​
  • 博文​​主题​​​是关于​​服务卡片,原子化服务​​​的,关于这个,在​​HarmonyOS 2.0​​发布会上有看到有讲。
  • 博文由两部分内容构成: ​​服务卡片(原子化服务)的一些基本概念,​​​和​​官网Demo的代码学习​​。
  • 依旧,把​​HarmonyOS Developer​​的地址留在这里,博文好多都是文档里的东西,建议小伙伴看文档学习,对于英语很垃圾的我来讲,这回不用翻译啦,有中文版,没障碍。嗯,博文有理解不对的地方请小伙伴积极留言

时光不能倒流,如果人可以从80岁开始倒过来活的话,人生一定会更加精彩。--------任正非


在最新发布的Harmonyos 2版本的新系统中, "服务卡片"服务成为一大亮点:​​1

  • 全新的​​Harmonyos​​桌面简洁有序,上滑App生成服务卡片,在桌面即可呈现更丰富的信息。
  • 卡片内容​​实时更新​​,只需一管即可获取所需信息,省去了打开App的时间。
  • 卡片可大可小、可藏可显,还能够​​个性化定制​​,让每个桌面独一无二。
  • 同时,卡片也是​​原子化服务​​​的载体,在服务中心可以​​轻松获取​​​、​​随时分享​​​,​​无需下载​​​、​​安装​​,一步到位获取各种服务。

嗯,下面开始我们愉快的​​HarmonyOS​​​----​​服务卡片​​之旅吧!

什么是原子化服务

在学习​​服务卡片​​​之前,我们先来了解一下什么是​​原子化服务​

​原子化服务​​​是 ​​HarmonyOS​​​ 提供的一种​​面向未来​​​的​​服务提供方式​​​,是有​​独立入口​​​的(用户可通过​​点击​​​、​​碰一碰​​​、​​扫一扫​​​等方式​​直接触发​​​)、​​免安装​​​的(无需​​显式安装​​​,由系统程序框架​​后台安装​​​后即可使用)、可为用户提供一个或多个​​便捷服务​​​的用户程序形态。​​原子化服务​​​基于 ​​HarmonyOS API​​​ 开发,支持运行在​​1+8+N​​设备上,供用户在合适的场景、合适的设备上便捷使用。​2

例如:某传统方式的需要安装的​​“购物应用A​​​”,在按照​​原子化服务​​​理念调整设计后,成为由“商品浏览”“购物车”“支付”等多个​​便捷服务​​​组成的、可以​​免安装​​​的​​“购物原子化服务A​​”。

文档里说的有些官方,个人理解,​原子化服务​​本质还是​​终端应用​​​(我们先这样理解它,后面在具体描述),一个代替​​终端应用​​​提供新​​服务提供方式​​​的存在。抛去​​服务流转/分享​​​、​​设备控制​​​之类的​​分布式能力​​​不说,在​​设计​​​上类似于​​微信小程序​​​和​​流应用​​​的优点的结合体,在​​入口设计​​​等方面感觉像​​微信小程序​​​一样便捷,但是不需要载体(微信,浏览器等),在整体体验方面又像​​流应用​​​一样,不需要显示安装。但是(体验应该要好于流应用),个人理解不谈分布式能力,像是用​​瘦客户​​​的方式有了​​胖客户​​的体验。

所谓原子化服务,个人理解,即将原来的​​终端应用​​​以​​功能为粒度​​​细化(​​原子化​​​),分离成一个个​​服务​​,多个服务之间通信完成需求,不在依托于具体的终端应用。类似于一种极限的思想,细化功能粒度,逐渐减少对终端应用总体的依赖。

关于原子化服务的更多内容,小伙伴移步​​HarmonyOS Developer:什么是原子化服务​

原子化服务​​具有如下基本要素 必须​​设计​​​和​​开发​​:

  • 基础信息
  • 服务卡片

简单了解一下​基础信息​​:即每个​​原子化服务​​​有独立的​​图标​​​、​​名称​​​、​​描述​​​、​​快照​​​。​​基础信息​​​应能够​​准确反映​​​服务提供方的​​特征​​​及​​服务的核心体验​​​,并与其他​​关联​​​的​​应用和服务​​​保持​​同步最新​​。

其他的没问题,我们重点看一下​快照​​这里:​​快照​​​为与原子化服务​​关联​​​的​​小尺寸服务卡片​​​的​​截图​​​。截图应为理想的​​服务状态​​​,让用户一眼可知​​服务内容​​。需提供直角图片,由展示快照的应用进行圆角裁切.,

HarmonyOS实战一原子化服务初尝试(ClockFACardDemo学习)_移动开发

​快照​​​为与原子化服务​​关联​​​的​​小尺寸服务卡片​​​的​​截图​​​.下面我们看看​​服务卡片​​是什么

什么是服务卡片,存在意义。

关于​​服务卡片​​​,我们看看​​HarmonyOS Developer​​​中设计文档是怎么讲的。​​https://developer.harmonyos.com/cn/docs/design/des-guides/service-widget-about-0000001144696239​

服务卡片介绍

将​​原子化服务/应用​​​的重要​​信息​​​以​​卡片​​​的形式​​展示​​​在桌面,用户可通过快捷​​手势​​​使用​​卡片​​​,通过​​轻量交互行为​​​实现​​服务直达​​​、​​减少层级跳转​​的目的。

HarmonyOS实战一原子化服务初尝试(ClockFACardDemo学习)_java_02


这是我的手机的时钟应用的​​类似的服务卡片​​​的这样一个东西,嗯,这个不算是服务卡片的。和​​实际的卡片还是有很大差距​​的.

HarmonyOS实战一原子化服务初尝试(ClockFACardDemo学习)_鸿蒙_03


这是​​P40模拟器​​​上的时钟,带有服务卡片选项的,​​真正的服务卡片​

​服务卡片​​​的​​核心理念​​​在于提供用户容易使用且一目了然的信息内容,将智慧化能力融入到服务卡片的体验中供用户​​选择​​​使用,同时满足在​​不同终端设备​​​上的​​展示和自适应​​。

服务卡片的构成

服务卡片的显示主要由​​内容主体​​​、​​归属的 App​​​ 名称构成,在临时态下会出现​​Pin钮​​​的操作特征,点击按钮用户可快捷将·​​卡片固定·​​在桌面显示。开发者应该借助卡片内容和卡片名称清晰地向用户传递所要提供的服务信息。

嗯,关于服务卡片的其他这里不多介绍,小伙伴了解更多移步到
​​​官方文档:https://developer.harmonyos.com/cn/docs/design/des-guides/service-widget-about-0000001144696239​​ 关于服务卡片的 交互设计,内容设计,视觉风格 等都有详细讲解。

简单实践-原子化服务之服务卡片初尝试

​检验真理的唯一标准是实践​​ ,说了这么多,编码试一下。先做出点东西来,然后我们在慢慢研究原理。嘻嘻。

官方给出一个java开发​​时钟卡片​​的例子。

这里,官方的​​Demo​​​很简单,​​文档很完整​​​小伙伴一看就明白。感兴趣的可以拉下来跑跑,我们看看具体的​​实现成果​

HarmonyOS实战一原子化服务初尝试(ClockFACardDemo学习)_java_04


主体结构分析

HarmonyOS支持应用以Ability为单位进行部署。​​Ability​​​可以分为​​FA(Feature Ability)​​​和​​PA(Particle Ability)​​两种类型

  • FA:​​Page Ability​​​:由上次的​​Holle Word​​​我们可以知道,在​​HarmonyOS​​​中,提供了​​Ability​​​和·​​AbilitySlice​​​·两个基础类, 一个​​有界面​​​的​​Ability​​​可以由一个或多个​​AbilitySlice​​​构成,​​AbilitySlice​​​主要用于​​承载单个页面​​​的具体​​逻辑实现​​​和​​界面UI​​​,是应用显示、运行和跳转的​​最小单元​​​。所以​​ClockCardSlice​​​为应用的主界面UI.,即这个Demo中只有一个​​Page AbilitySlice(ClockCardSlice)​​​。​​ClockCardSlice​​​是通过​​setMainRoute()​​​方法来指定,指定当前​​Ability​​的默认页面。
  • PA:​​Service Ability​​​: 由于时钟是需要实时更新的,所以需要​​Service Ability​​​来实时运行后台任务,即​​TimerAbility​​​为时钟更新的​​Service Ability​​​​layout文件夹​​:页面布局文件夹,由于时钟卡片Codelab涉及两个尺寸:22和24,因此需要新建两个.xml文件用于页面布局。
    ​​​config.json​​:配置文件,用于卡片和Service Ability的声明。

关于 ​​Ability​​​ 的更多介绍PageAbility和ServiceAbility的​​生命周期​​​回调等知识,小伙伴移步​​HarmonyOS Developer:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-service-lifecycle-0000000000044472​

时钟FA卡片应用主要设计到​创建​​、​​更新​​​和​​删除​​​卡片,​​对象关系映射型数据库​​​的​​使用​​​以及如何​​启动计时器服务​​​,​​卡片布局​​等。下面我们就这几部分代码分析,学习。

对象关系映射型数据库的使用

​HarmonyOS​​​对象关系映射(Object Relational Mapping,ORM)数据库是一款​​基于SQLite(一款轻型的数据库,是遵守ACID的关系型数据库管理系统。)​​​的数据库框架,屏蔽了​​底层SQLite数据库的SQL操作​​​,针对​​实体​​​和​​关系​​​提供了​​增删改查​​​等一系列的​​面向对象接口​​​。应用开发者不必再去编写​​复杂的SQL语句​​​, 以​​操作对象​​​的形式来​​操作数据​​库,提升效率的同时也能聚焦于业务开发。

个人感觉和使用JPA有相同的地方,如果有使用过JPA的,那这个很容易理解。

​对象关系映射​​​数据库的​​三个​​主要组件:

  • 数据库:被开发者用​​@Database​​​注解,且继承了​​OrmDatabase​​​的类,对应关系型​​数据库​​。
  • 实体对象:被开发者用​​@Entity​​​注解,且继承了​​OrmObject​​​的类,对应关系型​​数据库中的表​​。
  • 对象数据操作接口:包括数据库操作的入口​​OrmContext类​​​和​​谓词接口(OrmPredicate​​)等。
package com.huawei.cookbooks.database;

import ohos.data.orm.OrmObject;
import ohos.data.orm.annotation.Entity;
import ohos.data.orm.annotation.PrimaryKey;

/**
* Card Table 存放对象关系映射数据库相关对象的目录。
*/
// TODO 定义一个对象关系映射的数据表
@Entity(tableName = "form")
public class Form extends OrmObject {
// TODO 声明主键
@PrimaryKey()
private Long formId;
private String formName;
private Integer dimension;

public Form(Long formId, String formName, Integer dimension) {
this.formId = formId;
this.formName = formName;
this.dimension = dimension;
}

public Form() { }

public Integer getDimension() {
return dimension;
}

public void setDimension(Integer dimension) {
this.dimension = dimension;
}

public Long getFormId() {
return formId;
}

public void setFormId(Long formId) {
this.formId = formId;
}

public String getFormName() {
return formName;
}

public void setFormName(String formName) {
this.formName = formName;
}
}
package com.huawei.cookbooks.database;

import ohos.data.orm.OrmDatabase;
import ohos.data.orm.annotation.Database;

/**
* Card Database 卡片数据库对象,用于创建卡片数据库。
*/
@Database(
entities = {Form.class},
version = 1)
public abstract class FormDatabase extends OrmDatabase { }
  • ​创建数据库​​​:开发者需要定义一个表示数据库的类,继承​​OrmDatabase​​​,再通过​​@Database​​​注解内的​​entities​​属性指定哪些数据模型类(表)属于这个数据库。
  • 属性:​​version:数据库版本号​​​。​​entities:数据库内包含的表​​。
  • ​创建数据表​​​。开发者可通过创建一个继承了​​OrmObject​​​并用​​@Entity​​注解的类,获取数据库实体对象,也就是表的对象。
  • ​tableName:表名​​​。​​primaryKeys:主键名,一个表里只能有一个主键,一个主键可以由多个字段组成​​​。​​foreignKeys:外键列表​​​。​​indices:索引列表​

建立数据库连接

HarmonyOS实战一原子化服务初尝试(ClockFACardDemo学习)_java_05


提供对数据库相关操作的方法

package com.huawei.cookbooks.utils;

import com.huawei.cookbooks.database.Form;

import ohos.data.orm.OrmContext;
import ohos.data.orm.OrmPredicates;

import java.util.List;

/**
* Card Database Operations 提供对数据库相关操作的方法
*/
public class DatabaseUtils {
/**
* delete data
*
* @param formId form id
* @param connect data connection
*/
public static void deleteFormData(long formId, OrmContext connect) {
OrmPredicates where = connect.where(Form.class);
where.equalTo("formId", formId);
List<Form> query = connect.query(where);
if (!query.isEmpty()) {
connect.delete(query.get(0));
connect.flush();
}
}

/**
* add card info
*
* @param form card object
* @param connect data connection
*/
public static void insertForm(Form form, OrmContext connect) {
connect.insert(form);
connect.flush();
}
}

对于对象关系映射型数据库的学习,小伙伴移步HarmonyOS Developer学习,这个不在多介绍:​​https://developer.harmonyos.com/cn/docs/documentation/doc-guides/database-orm-guidelines-0000000000030063​

卡片应用初始化:启动卡片定时器服务

HarmonyOS实战一原子化服务初尝试(ClockFACardDemo学习)_新星计划_06

创建、删除卡片

我们想看看官方文档里怎么说。创建一个​​FormAbilit​​​y,覆写卡片​​相关回调函数​​。

  • onCreateForm(Intent intent)
  • onUpdateForm(long formId)
  • onDeleteForm(long formId)
  • onCastTempForm(long formId)
  • onEventNotify(Map<Long, Integer> formEvents)

在​​onCreateForm(Intent intent)​​​中,当卡片​​使用方​​​请求​​获取卡片​​​时,卡片​​提供方​​​会被​​拉起​​​并调用​​onCreateForm(Intent intent)​​​回调,​​intent​​​中会带有​​卡片ID​​​,​​卡片名称​​​,​​临时卡片标记​​​和​​卡片外观规格信息​​,分别通过

  • AbilitySlice.PARAM_FORM_IDENTITY_KEY、
  • AbilitySlice.PARAM_FORM_NAME_KEY、
  • AbilitySlice.PARAM_FORM_TEMORARY_KEY和
  • AbilitySlice.PARAM_FORM_DIMENSION_KEY按需获取。

提供方可以通过​​AbilitySlice.PARAM_FORM_CUSTOMIZE_KEY​​获取卡片使用方设置的自定义数据。

​卡片使用方​​​:显示卡片内容的宿主应用,控制卡片在宿主中展示的位置
​​​卡片提供方​​:提供卡片显示内容的HarmonyOS Service/HarmonyOS Application,控制卡片的显示内容、控件布局以及控件点击事件

public class FormAbility extends Ability {
......
@Override
public void onStart(Intent intent) {
super.onStart(intent);
......
}
@Override
protected ProviderFormInfo onCreateForm(Intent intent) {
long formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, 0);
String formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);
int specificationId = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, 0);
boolean tempFlag = intent.getBooleanParam(AbilitySlice.PARAM_FORM_TEMPORARY_KEY, false);

// 获取自定义数据
IntentParams intentParams = intent.getParam(AbilitySlice.PARAM_FORM_CUSTOMIZE_KEY);

HiLog.info(LABEL_LOG, "onCreateForm: " + formId + " " + formName + " " + specificationId);
// 开发者需要根据卡片的名称以及外观规格获取对应的xml布局并构造卡片对象,此处ResourceTable.Layout_form_ability_layout_2_2仅为示例
ProviderFormInfo formInfo = new ProviderFormInfo(ResourceTable.Layout_form_ability_layout_2_2, this);
// 获取卡片信息
String formData = getInitFormData(formName, specificationId);
ComponentProvider componentProvider = new ComponentProvider();
componentProvider.setText(ResourceTable.Id_title, "formData-" + formData);
formInfo.mergeActions(componentProvider);
......
HiLog.info(LABEL_LOG, "onCreateForm finish.......");
return formInfo;
}

@Override
protected void onDeleteForm(long formId) {
super.onDeleteForm(formId);
// 删除卡片实例数据,需要由开发者实现
deleteFormInfo(formId);
......
}

@Override
// 若卡片支持定时更新/定点更新/卡片使用方主动请求更新功能,则提供方需要覆写该方法以支持数据更新
protected void onUpdateForm(long formId) {
super.onUpdateForm(formId);
// 更新卡片信息,由开发者实现
......
}

@Override
protected void onCastTempForm(long formId) {
// 使用方将临时卡片转换为常态卡片触发,提供方需要做相应的处理,将数据持久化。
super.onCastTempForm (formId);
......
}

@Override
protected void onEventNotify(Map<Long, Integer> formEvents) {
// 使用方发起可见或者不可见通知触发,提供方需要做相应的处理,比如卡片可见时刷新卡片,仅系统应用能收到该回调。
super.onEventNotify(formEvents);
......
}
}

了解更多见​​Java卡片开发指导:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-service-widget-provider-java-0000001104082220​

我们看看Demo里怎么写的:覆盖了

  • ​onDeleteForm(当卡片被删除时,需要重写onDeleteForm方法,根据卡片id删除卡片实例数据:)​​和
  • ​onCreateForm·(当卡片使用方请求获取卡片时,卡片提供方会被拉起并调用onCreateForm回调函数,完成卡片信息的初始化)​
package com.huawei.cookbooks;

import com.huawei.cookbooks.database.Form;
import com.huawei.cookbooks.database.FormDatabase;
import com.huawei.cookbooks.slice.ClockCardSlice;
import com.huawei.cookbooks.utils.ComponentProviderUtils;
import com.huawei.cookbooks.utils.DatabaseUtils;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.ProviderFormInfo;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.ComponentProvider;
import ohos.data.DatabaseHelper;
import ohos.data.orm.OrmContext;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

/**
* Card Main Ability 主程序入口,由DevEco Studio生成,开发者需要重写创建、删除卡片等方法。
*/
public class MainAbility extends Ability {
private static final HiLogLabel LABEL_LOG = new HiLogLabel(0, 0, "com.huawei.cookbooks.MainAbility");
// TODO 卡片一
private static final int DEFAULT_DIMENSION_2X2 = 2;
// TODO 卡片二
private static final int DEFAULT_DIMENSION_2X4 = 3;
private static final String EMPTY_STRING = "";
private static final int INVALID_FORM_ID = -1;
private long formId;
// TODO 卡片对象
private ProviderFormInfo formInfo;
// TODO 数据库服务对象
private DatabaseHelper helper = new DatabaseHelper(this);
// TODO 数据库连接对象
private OrmContext connect;

/**
* TODO 项目启动方法,启动定时服务
* @param intent
*/
@Override
public void onStart(Intent intent) {
super.onStart(intent);
// TODO 建立数据库连接
connect = helper.getOrmContext("FormDatabase", "FormDatabase.db", FormDatabase.class);
// TODO 启动TimerAbility
Intent intentService = new Intent();
Operation operation =
new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName(getBundleName())
.withAbilityName(TimerAbility.class.getName())
.build();
intentService.setOperation(operation);
startAbility(intentService);
super.setMainRoute(ClockCardSlice.class.getName());
}
//当卡片使用方请求获取卡片时,卡片提供方会被拉起并调用onCreateForm回调函数,完成卡片信息的初始化
@Override
protected ProviderFormInfo onCreateForm(Intent intent) {
if (intent == null) {
return new ProviderFormInfo();
}
// 获取卡片id
formId = INVALID_FORM_ID;
if (intent.hasParameter(AbilitySlice.PARAM_FORM_IDENTITY_KEY)) {
formId = intent.getLongParam(AbilitySlice.PARAM_FORM_IDENTITY_KEY, INVALID_FORM_ID);
} else {
return new ProviderFormInfo();
}
// 获取卡片名称
String formName = EMPTY_STRING;
if (intent.hasParameter(AbilitySlice.PARAM_FORM_NAME_KEY)) {
formName = intent.getStringParam(AbilitySlice.PARAM_FORM_NAME_KEY);
}
// 获取卡片规格
int dimension = DEFAULT_DIMENSION_2X2;
if (intent.hasParameter(AbilitySlice.PARAM_FORM_DIMENSION_KEY)) {
dimension = intent.getIntParam(AbilitySlice.PARAM_FORM_DIMENSION_KEY, DEFAULT_DIMENSION_2X2);
}
int layoutId = ResourceTable.Layout_form_image_with_info_date_card_2_2;
if (dimension == DEFAULT_DIMENSION_2X4) {
layoutId = ResourceTable.Layout_form_image_with_info_date_card_2_4;
}
formInfo = new ProviderFormInfo(layoutId, this);
// 存储卡片信息
Form form = new Form(formId, formName, dimension);
ComponentProvider componentProvider = ComponentProviderUtils.getComponentProvider(form, this);
formInfo.mergeActions(componentProvider);
if (connect == null) {
connect =
helper.getOrmContext("FormDatabase", "FormDatabase.db", FormDatabase.class);
}
try {
DatabaseUtils.insertForm(form, connect);
} catch (Exception e) {
DatabaseUtils.deleteFormData(form.getFormId(), connect);
}
return formInfo;
}
// todo 当卡片被删除时,需要重写onDeleteForm方法,根据卡片id删除卡片实例数据:
@Override
protected void onDeleteForm(long formId) {
super.onDeleteForm(formId);
// 删除数据库中的卡片信息
DatabaseUtils.deleteFormData(formId, connect);
}
}

更新卡片

卡片数据服务:为了方便处理·​​时钟卡片​​​刷新的​​定时任务​​​,我们创建了一个​​Service Ability​​​,​​定时​​​去​​更新​​​卡片信息,在​​TimerAbility.java​​中

package com.huawei.cookbooks;

import com.huawei.cookbooks.database.Form;
import com.huawei.cookbooks.database.FormDatabase;
import com.huawei.cookbooks.utils.ComponentProviderUtils;
import com.huawei.cookbooks.utils.DatabaseUtils;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.FormException;
import ohos.aafwk.content.Intent;
import ohos.agp.components.ComponentProvider;
import ohos.data.DatabaseHelper;
import ohos.data.orm.OrmContext;
import ohos.data.orm.OrmPredicates;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.rpc.IRemoteObject;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
* Time PA 时钟更新Service Ability。
*/
public class TimerAbility extends Ability {
private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "Demo");
private static final long SEND_PERIOD = 1000L;
private DatabaseHelper helper = new DatabaseHelper(this);
private OrmContext connect;

@Override
public void onStart(Intent intent) {
HiLog.info(LABEL_LOG, "TimerAbility::onStart");
connect = helper.getOrmContext("FormDatabase", "FormDatabase.db", FormDatabase.class);
startTimer();
super.onStart(intent);
}

// 卡片更新定时器,每秒更新一次
private void startTimer() {
Timer timer = new Timer();
timer.schedule(
new TimerTask() {
@Override
public void run() {
updateForms();
}
},
0,
SEND_PERIOD);
}

private void updateForms() {
// 从数据库中获取卡片信息
OrmPredicates ormPredicates = new OrmPredicates(Form.class);
List<Form> formList = connect.query(ormPredicates);
// 更新时分秒
if (formList.size() <= 0) {
return;
}
for (Form form : formList) {
// 遍历卡片列表更新卡片
ComponentProvider componentProvider = ComponentProviderUtils.getComponentProvider(form, this);
try {
Long updateFormId = form.getFormId();
updateForm(updateFormId, componentProvider);
} catch (FormException e) {
// 删除不存在的卡片
DatabaseUtils.deleteFormData(form.getFormId(), connect);
HiLog.error(LABEL_LOG, "onUpdateForm updateForm error");
}
}
}

@Override
public void onBackground() {
super.onBackground();
HiLog.info(LABEL_LOG, "TimerAbility::onBackground");
}

@Override
public void onStop() {
super.onStop();
HiLog.info(LABEL_LOG, "TimerAbility::onStop");
}
}

​有关卡片组件的更新​​​,封装了​​ComponentProviderUtils​​​这个类,在卡片更新时候,通过调用​​updateForm​​​方法,传入参数​​formId​​​和​​componentProvider​​.

HarmonyOS实战一原子化服务初尝试(ClockFACardDemo学习)_java_07

package com.huawei.cookbooks.utils;

import com.huawei.cookbooks.ResourceTable;
import com.huawei.cookbooks.database.Form;

import ohos.agp.components.ComponentProvider;
import ohos.agp.utils.Color;
import ohos.app.Context;

import java.util.Calendar;

/**
* Component ProviderUtils 提供获取ComponentProvider对象的方法,用于卡片组件的更新。
*/
public class ComponentProviderUtils {
// 当前星期颜色
private static Color nowWeekColor = new Color(Color.rgb(255, 245, 238));

// 原色星期
private static Color primaryWeekColor = new Color(Color.rgb(192, 192, 192));

private static final int WEEK_DAYS = 7;
private static final int STRING_LENGTH = 2;
private static final int DIM_VERSION = 3;
private static final int SUNDAY = 1;
private static final int MONDAY = 2;
private static final int TUESDAY = 3;
private static final int WEDNESDAY = 4;
private static final int THURSDAY = 5;
private static final int FRIDAY = 6;
private static final int SATURDAY = 7;

/**
* Obtain the day of the week
*
* @return week
*/
public static int getWeekDayId() {
Calendar calendar = Calendar.getInstance();
int week = calendar.get(Calendar.DAY_OF_WEEK);
int result = getWeekIdResult(week);
return result;
}

/**
* get week component id
*
* @param week week
* @return component id
*/
private static int getWeekIdResult(int week) {
int result = ResourceTable.Id_mon;
switch (week) {
case SUNDAY:
result = ResourceTable.Id_sun;
break;
case MONDAY:
result = ResourceTable.Id_mon;
break;
case TUESDAY:
result = ResourceTable.Id_tue;
break;
case WEDNESDAY:
result = ResourceTable.Id_wed;
break;
case THURSDAY:
result = ResourceTable.Id_thu;
break;
case FRIDAY:
result = ResourceTable.Id_fri;
break;
case SATURDAY:
result = ResourceTable.Id_sat;
break;
default:
result = ResourceTable.Id_sun;
break;
}
return result;
}

/**
* Obtains the ComponentProvider object
*
* @param form form info
* @param context context
* @return component provider
*/
public static ComponentProvider getComponentProvider(Form form, Context context) {
int layoutId = ResourceTable.Layout_form_image_with_info_date_card_2_2;
if (form.getDimension() == DIM_VERSION) {
layoutId = ResourceTable.Layout_form_image_with_info_date_card_2_4;
}
ComponentProvider componentProvider = new ComponentProvider(layoutId, context);
setComponentProviderValue(componentProvider);
return componentProvider;
}

/**
* Time converted to string
*
* @param time time
* @return time string
*/
private static String int2String(int time) {
String timeString;
if (String.valueOf(time).length() < STRING_LENGTH) {
timeString = "0" + time;
} else {
timeString = time + "";
}
return timeString;
}

/**
* Set the value of componentProvider
*
* @param componentProvider component provider
*/
private static void setComponentProviderValue(ComponentProvider componentProvider) {
Calendar now = Calendar.getInstance();
int hour = now.get(Calendar.HOUR_OF_DAY);
int min = now.get(Calendar.MINUTE);
int second = now.get(Calendar.SECOND);
String hourString = int2String(hour);
String minString = int2String(min);
String secondString = int2String(second);
componentProvider.setText(ResourceTable.Id_date, DateUtils.getCurrentDate("yyyy-MM-dd"));
componentProvider.setText(ResourceTable.Id_hour, hourString);
componentProvider.setText(ResourceTable.Id_min, minString);
componentProvider.setText(ResourceTable.Id_sec, secondString);

// 获取当前星期
int weekDayId = getWeekDayId();
componentProvider.setTextColor(weekDayId, nowWeekColor);

// 将前一天的星期改回原色
int lastWeekId = getLastWeekDayId();
componentProvider.setTextColor(lastWeekId, primaryWeekColor);
}

/**
* obtain previous day of the week
*
* @return previous day of the week
*/
public static int getLastWeekDayId() {
Calendar calendar = Calendar.getInstance();
int week = calendar.get(Calendar.DAY_OF_WEEK);
int lastWeek;
if (week == 1) {
lastWeek = WEEK_DAYS;
} else {
lastWeek = week - 1;
}
return getWeekIdResult(lastWeek);
}
}

对于服务卡片我们就先学的这里,​​学完了Demo​​​,小伙伴是不是蠢蠢欲动呢?自己写一个类似的Demo应该是在可能完成的​​范围之内​​的,感兴趣的小伙伴赶快试试吧。之后我准备基于官方的一个Demo(一个音频播放器),搞一个服务卡片。嗯,时间关系,今天就先搞到这里。

标签:卡片,int,private,formId,HarmonyOS,原子化,ohos,import,ClockFACardDemo
From: https://blog.51cto.com/u_13474506/5931185

相关文章