想了解更多内容,请访问:

创新互联建站是一家专注于网站设计、成都网站建设与策划设计,安康网站建设哪家好?创新互联建站做网站,专注于网站建设十余年,网设计领域的专业建站公司;建站业务涵盖:安康等地区。安康做网站价格咨询:18980820575
和华为官方合作共建的鸿蒙技术社区
https://harmonyos.
服务卡片(以下简称“卡片”)是FA(Feature Ability)的一种界面展示形式,将FA(Feature Ability)的重要信息或操作前置到卡片,以达到服务直达,减少体验层级目的。
卡片常用于嵌入到其他应用(当前只支持系统应用)中作为其界面的一部分显示,并支持拉起页面,发送消息等基础的交互功能。
本期Codelab,我们就来为大家介绍如何在HarmonyOS上开发一个时钟类服务卡片应用,该卡片开发使用Java开发语言,包含2×2、2×4两种布局的显示形态,我们先来看看它的显示效果。
下面我们将集中于卡片应用的创建、更新和删除,卡片数据库(用于存储卡片信息)的创建和使用以及卡片数据服务的使用和更新。
在开始敲代码之前,开发者们需要先下载安装Huawei DevEco Studio,可参照官网的指南进行操作:
https://developer.harmonyos.com/cn/docs/documentation/docguides/software_install0000001053582415
本Codelab主要在entry\src\main\java\目录下完成配置声明、页面布局、功能逻辑代码实现,整个工程的代码结构如下:
开发者需自行创建的文件夹,包含两个java文件——Form和FormDatabase。其中Form为卡片对象,用于存储卡片id,卡片名称以及卡片规格。FormDatabase为卡片数据库对象,用于创建卡片数据库。
仅包含ClockCardSlice文件,为应用主页面。
开发者需自行创建的文件夹,用于存放各类封装好的工具,在本Codelab中,包含ComponentProviderUtils、DatabaseUtils、DateUtils和LogUtils。其中,ComponentProviderUtils提供获取ComponentProvider对象的方法,用于更新卡片;DatabaseUtils提供对数据库相关操作的方法;DateUtils提供日期相关操作的方法;LogUtils封装日志工具类。
主程序入口,由DevEco Studio生成,用于重写创建、删除卡片等方法。
DevEco Studio生成,无需做任何变更。
一种Service Ability,需要开发者需自行创建,用于时钟更新。
页面布局文件夹,由于时钟卡片Codelab涉及两个尺寸:2×2和2×4,因此需要新建两个.xml文件用于页面布局。
配置文件,用于卡片和Service Ability的声明。
了解完工程代码结构,下面让我们来对重点步骤一一讲解。
在卡片应用开始开发前,我们需要在其配置文件config.json中进行以下几项声明,使系统能够识别该应用为一款卡片应用,并使之与系统进行绑定。
在卡片所在的"abilities"中需要配置“formsEnabled": true和"visible": true,使之能被识别为卡片。同时需要配置forms模块的细节,代码如下:
- "abilities": [
 - {
 - ....
 - "formsEnabled": true,//表示该Ability支持服务卡片显示
 - "visible": true,
 - "forms": [
 - {
 - "landscapeLayouts": [
 - "$layout:form_image_with_info_date_card_2_2",
 - "$layout:form_image_with_info_date_card_2_4"
 - ], //表示卡片外观规格对应的横向布局文件,仅当卡片类型为Java卡片时,需要配置该标签
 - "isDefault": true, //该卡片为默认卡片
 - "scheduledUpdateTime": "10:30",
 - "defaultDimension": "2*2", //卡片的默认外观规格,这里是2*2
 - "name": "DateCard", //卡片的类名
 - "description": "This is a service widget", //卡片的描述
 - "colorMode": "auto",
 - "type": "Java", //表示卡片的类型,这是一个java卡片
 - "supportDimensions": [
 - "2*2",
 - "2*4"
 - ], //表示卡片支持的外观规格,这里是2*2和2*4
 - "portraitLayouts": [
 - "$layout:form_image_with_info_date_card_2_2",
 - "$layout:form_image_with_info_date_card_2_4"
 - ], //表示卡片外观规格对应的竖向布局文件,仅当卡片类型为Java卡片时,需要配置该标签
 - "updateEnabled": true, //表示支持周期性刷新,可以在定时刷新
 - "updateDuration": 1, //表示卡片定时刷新的更新周期,单位为30分钟,这里为30分钟刷新一次
 - "formVisibleNotify": true
 - }
 - ]
 
有关forms模块相关属性说明,开发者可自行参见官网资料。
https://developer.harmonyos.com/cn/docs/documentation/docguides/abilityservicewidgetproviderjava0000001104082220
本篇Codelab为卡片应用设计了2×2和2×4两种布局风格,效果如下图:
其中,2×2布局分为四行,展示的内容从上到下分别为日期、时间说明内容、时间具体信息、星期,整体由DependentLayout布局内嵌套四个DirectionalLayout构成,每个DirectionalLayout内均使用Text组件进行展示,部分代码示例如下:
- xmlns:ohos="http://schemas.huawei.com/res/ohos"
 - ohos:height="match_parent"
 - ohos:width="match_parent"
 - ohos:background_element="#6A9F99"
 - ohos:remote="true">
 - ohos:height="match_content"
 - ohos:width="match_parent"
 - ohos:orientation="vertical">
 - ohos:id="$+id:title"
 - ohos:height="match_content"
 - ohos:width="match_parent"
 - ohos:alignment="horizontal_center"
 - ohos:orientation="horizontal"
 - ohos:top_margin="35fp">
 - ohos:id="$+id:time"
 - ohos:height="match_content"
 - ohos:width="match_parent"
 - ohos:alignment="horizontal_center"
 - ohos:below="$id:title"
 - ohos:orientation="horizontal"
 - ohos:top_margin="0.5fp">
 - ohos:height="match_content"
 - ohos:width="match_parent"
 - ohos:alignment="center"
 - ohos:below="$id:time"
 - ohos:margin="20fp"
 - ohos:orientation="horizontal">
 
2×4布局分为三行,将日期与星期合为一行,时间说明内容、时间具体信息各单列一行,整体由DependentLayout布局嵌套一个DependentLayout和两个DirectionalLayout构成。
其中DependentLayout布局中由一个Text组件和一个DirectionalLayout组成,DirectionalLayout中又嵌套七个Text组件。其余两个DirectionalLayout内均使用Text组件进行展示,部分代码示例如下:
- xmlns:ohos="http://schemas.huawei.com/res/ohos"
 - ohos:height="match_parent"
 - ohos:width="match_parent"
 - ohos:background_element="#6A9F99"
 - ohos:remote="true">
 - ohos:height="match_content"
 - ohos:width="match_parent"
 - ohos:orientation="horizontal">
 - ohos:height="match_content"
 - ohos:width="match_content"
 - ohos:align_parent_right="true"
 - ohos:orientation="horizontal"
 - ohos:top_margin="10fp">
 - ohos:id="$+id:title"
 - ohos:height="match_content"
 - ohos:width="match_parent"
 - ohos:alignment="horizontal_center"
 - ohos:orientation="horizontal"
 - ohos:top_margin="35fp">
 - ohos:id="$+id:time"
 - ohos:height="match_content"
 - ohos:width="match_parent"
 - ohos:alignment="horizontal_center"
 - ohos:below="$id:title"
 - ohos:orientation="horizontal">
 
本篇Codelab使用对象关系映射数据库来对卡片ID,卡片名字等信息进行存储。因此,我们需要创建一个数据库(FormDatabase)和一张表(Form)。
其中,对象关系映射 (ORM) 数据库类对应于关系数据库,在本Codelab中即FormDatabase.java,用于存储“Form”表,版本号为 “1”。
在使用 ORM 数据库之前,需要创建一个继承自OrmDatabase的数据库类,并使用 @Database 对其进行注释。示例代码如下:
- @Database(
 - entities = {Form.class},
 - version = 1)
 - public abstract class FormDatabase extends OrmDatabase { }
 
关于OrmDatabase相关开发信息,开发者可以自行参考官网资料。
https://developer.harmonyos.com/cn/docs/documentation/docreferences/ormdatabase0000001054838766
此外,我们定义一个对象关系映射 (ORM) 数据库中的实体类Form.java,对应数据库内的表名为“form”,包含了卡片id(formId),卡片名称(formName) 和卡片规格(dimension)三个字段。在ORM数据库中操作实体之前,需要创建一个继承自OrmObject的实体类,并用@Entity注解。示例代码如下:
- @Entity(tableName = "form")
 - public class Form extends OrmObject {
 - @PrimaryKey()
 - private Long formId;
 - private String formName;
 - private Integer dimension;
 - public Form(Long formId, String formName, Integer dimension) {
 - this.formId = formId;//卡片id
 - 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;
 - }
 - }
 
关于OrmObject相关开发信息,开发者可以自行参考官网资料。
https://developer.harmonyos.com/cn/docs/documentation/docreferences/ormobject0000001054120141
由于我们开发的时钟服务卡片需要每隔一秒进行刷新,为了方便处理时钟卡片刷新的定时任务,我们需要在目录下右键new>Ability>Empty Service Ability,创建了一个名为TimerAbility的Service Ability,作为卡片更新定时器,以每秒一次的频率更新:
- @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);
 - }
 
同时,TimerAbility还承担着卡片更新的功能,我们将在下面详细介绍。
在正式进入时钟FA卡片的创建、更新及删除的开发之前,我们先来了解关于卡片开发的一些基本概念。
服务卡片整体框架主要包含三部分:卡片使用方、卡片管理服务和卡片提供方。
卡片使用方: 显示卡片内容的宿主应用,控制卡片在宿主中展示的位置。
卡片管理服务: 用于管理系统中所添加卡片的常驻代理服务,包括卡片对象的管理与使用,以及卡片周期性刷新等。
卡片提供方: 提供卡片显示内容的HarmonyOS服务/HarmonyOS应用,控制卡片的显示内容、控件布局以及控件点击事件。开发者开发卡片即为卡片提供方。
说明
卡片使用方和提供方不要求常驻运行,在需要添加/删除/请求更新卡片时,卡片管理服务会拉起卡片提供方获取卡片信息。
当卡片使用方请求获取卡片时,卡片提供方会被拉起并调用onCreateForm回调函数,intent中会带有卡片ID,卡片名称和卡片外观规格信息,分别通过AbilitySlice.PARAM_FORM_IDENTITY_KEY、AbilitySlice.PARAM_FORM_NAME_KEY和AbilitySlice.PARAM_FORM_DIMENSION_KEY获取,并根据卡片的名称以及外观规格获取对应的xml布局并构造卡片对象,完成卡片信息的创建。
在MainAbility中有如下示例代码:
- @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;
 - }
 
服务卡片刷新机制分为两种,第一种是定时/定点更新,即在config.json中配置了定时/定点更新之后,卡片管理服务会定期拉起服务卡片刷新数据。第二种是主动更新,即开发者根据需要主动调用updateForm方法更新卡片。在本Codelab中,我们选择的是第二种方式。
我们在之前创建的TimerAbility.java中调用updateForm方法,从数据表Form中获取卡片信息,更新时分秒:
- private void updateForms() {
 - // 从数据库中获取卡片信息
 - OrmPredicates ormPredicates = new OrmPredicates(Form.class);
 - List
 - // 更新时分秒
 - if (formList.size() > 0) {
 - 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");
 - }
 - }
 - }
 - }
 
同时,组件同步展示时间更新。我们封装ComponentProviderUtils这个类,在卡片更新时候,通过调用updateForm方法,传入参数formId和componentProvider,以达到日期、时间和星期实时更新的效果,部分代码和效果如下:
- 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;
 - }
 - // 为时钟各个组件赋值
 - 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);
 - }
 
当卡片被删除时,需要重写onDeleteForm方法,我们将在MainAbility中根据卡片id删除卡片实例数据:
- @Override
 - protected void onDeleteForm(long formId) {
 - super.onDeleteForm(formId);
 - // 删除数据库中的卡片信息
 - DatabaseUtils.deleteFormData(formId, connect);
 
至此,我们完成了时钟卡片应用的开发,构建了一个2×2和2×4的卡片样式。
想了解更多内容,请访问:
和华为官方合作共建的鸿蒙技术社区
https://harmonyos.
                文章名称:HarmonyOS时钟服务卡片开发指南
                
                文章路径:http://www.csdahua.cn/qtweb/news30/48280.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网