07服务卡片
服务卡片开发
1-创建卡片
- 创建卡片当前有两种入口:
- 创建工程时,选择
Application,可以在创建工程后右键新建卡片。 - 创建工程时,选择
Atomic Service(元服务),也可以在创建工程后右键新建卡片。

在已有的应用工程中,可以通过右键新建ArkTS卡片,具体的操作方式如下。
右键新建卡片。

说明
在
API 10及以上Stage模型的工程中,在Service Widget菜单可直接选择创建动态或静态服务卡片。创建服务卡片后,也可以在卡片的form_config.json配置文件中,通过isDynamic参数修改卡片类型:
isDynamic置空或赋值为"true",则该卡片为动态卡片;isDynamic赋值为"false",则该卡片为静态卡片。
2 根据实际业务场景,选择一个卡片模板。

3 在选择卡片的开发语言类型(Language)时,选择ArkTS选项,然后单击“Finish”,即可完成ArkTS卡片创建。

建议根据实际使用场景命名卡片名称,
ArkTS卡片创建完成后,工程中会新增如下卡片相关文件:卡片生命周期管理文件(EntryFormAbility.ets)、卡片页面文件(DemoCardCard.ets)和卡片配置文件(form_config.json)。

2-设置卡片数据
可以简单调整DemoCardCard卡片页面文件UI代码。先暂时展示默认数据:标题和描述。
@Entry
@Component
struct DemoCardCard {
// 卡片数据
readonly title: string = '标题:帝心卡片';
readonly description: string = '描述:学习卡片开发知识';
readonly actionType: string = 'router';
readonly abilityName: string = 'EntryAbility';
readonly message: string = 'add detail';
build() {
Column({ space: 30 }) {
Text(this.title)
.fontSize(14)
Text(this.description)
.fontSize(14)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.SpaceEvenly)
.onClick(() => {
postCardAction(this, {
action: this.actionType,
abilityName: this.abilityName,
params: {
message: this.message
}
});
})
}
}
展示卡片
长按应用图标/元服务右上角功能键,进行卡片添加。将卡片添加到桌面进行显示。值得注意的是,在添加卡片时,会自动触发卡片生命周期文件src/main/ets/entryformability/EntryFormAbility.ets中的onAddForm方法。
- 片在创建时,会触发
onAddForm生命周期,此时返回数据可以直接传递给卡片- 另外卡片在被卸载时,会触发
onRemoveForm生命周期
设置卡片数据
以上展示的卡片数据是在卡片页面文件中硬编码的静态数据,而卡片如果需要展示动态数据,则需要通过其他能力来获取。例如,EntryFormAbility/EntryAbility/应用或者元服务的页面文件
因为卡片不支持
import,所以没法通过引入@ohos.net.http等包来进行数据请求,因此需要通过借助外部能力获取数据后,再传入卡片内部进行展示
动态展示卡片数据的场景:
- 添加卡片到桌面时设置初始数据:在
EntryFormAbility的onAddForm生命周期函数中通过formBindingData.createFormBindingData(formData)绑定数据到卡片页面中。 - 在应用或者元服务页面获取完数据后,主动将数据更新到卡片中
添加卡片时设置卡片数据
在EntryFormAbility的onAddForm生命周期函数中通过formBindingData.createFormBindingData(formData)绑定到卡片页面中的数据默认会存储在LocalStorage中。因此卡片页面可以从LocalStorage中使用@LocalStorageProp取出数据。
EntryFormAbility.ets
// 添加卡片生命周期函数
onAddForm(want: Want) {
//绑定的数据要求:键值对类型的对象或者json
let formData:Record<string,string> = {
"title":"初始化数据",
"description":"数据绑定卡片成功,同时存储在localStorage中"
};
return formBindingData.createFormBindingData(formData);
}
DemoCardCard
const localStorageObj = new LocalStorage()
@Entry(localStorageObj)
@Component
struct DemoCardCard {
// 卡片数据
@LocalStorageProp('title') title: string = '标题:帝心卡片';
@LocalStorageProp('description') description: string = '描述:学习卡片开发知识';
readonly actionType: string = 'router';
readonly abilityName: string = 'EntryAbility';
readonly message: string = 'add detail';
build() {
Column({ space: 30 }) {
Text(this.title)
.fontSize(14)
Text(this.description)
.fontSize(14)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.SpaceEvenly)
.onClick(() => {
postCardAction(this, {
action: this.actionType,
abilityName: this.abilityName,
params: {
message: this.message
}
});
})
}
}

3-卡片内容更新
ArkTS卡片框架为提供方提供了updateForm接口,用来触发卡片的页面更新能力。
提供方主动刷新卡片流程示意:

卡片提供方应用运行过程中,如果识别到有要更新卡片数据的诉求,可以主动通过
formProvider提供的updateForm接口更新卡片。
使用异步方式模拟在卡片提供方运行的过程中更新数据。添加卡片的过程中,会先显示初始化数据,定时结束会更新数据。
EntryFormAbility.ets
// 添加卡片生命周期函数
onAddForm(want: Want) {
//绑定的数据要求:键值对类型的对象或者json
let formData: Record<string, string> = {
"title": "初始化数据",
"description": "数据绑定卡片成功,同时存储在localStorage中"
};
// 卡片接收异步数据
setTimeout(() => {
// 准备新的待绑定的数据
formData = {
"title": "异步数据",
"description": "卡片更新数据:异步"
};
// 定义需要传递给卡片的数据对象
let bindData = formBindingData.createFormBindingData(formData)
console.log(`dxin => bindData ${JSON.stringify(bindData)}`)
// 获取当前添加到桌面的卡片id
let wantParams: Record<string, object> | undefined = want.parameters
console.log(`dxin =>wantParams ${JSON.stringify(wantParams)}`)
if (wantParams) {
let formId = wantParams[formInfo.FormParam.IDENTITY_KEY]
console.log(`dxin => formId ${formId}`)
// 更新数据到卡片上
formProvider.updateForm(formId.toString(), bindData)
.then(() => {
console.log(`dxin => 卡片数据更新成功 `)
})
.catch(() => {
console.log(`dxin => 卡片数据更新失败`)
})
} else {
console.log(`dxin => wantParams 获取失败。结果为undefined`)
}
}, 5000)
return formBindingData.createFormBindingData(formData);
}
卡片id被存储在want.parameters对象中。
片ID是字符串类型的数字。
want.parameters返回的wantParams对象格式。
{
"isDynamic": true,
"moduleName": "entry",
"ohos.extra.param.key.form_border_width": 0,
"ohos.extra.param.key.form_customize": [],
"ohos.extra.param.key.form_dimension": 2,
"ohos.extra.param.key.form_height": 513.5,
"ohos.extra.param.key.form_identity": "1767654127",
"ohos.extra.param.key.form_launch_reason": 1,
"ohos.extra.param.key.form_location": 2,
"ohos.extra.param.key.form_name": "demoCard",
"ohos.extra.param.key.form_obscured_mode": false,
"ohos.extra.param.key.form_rendering_mode": 0,
"ohos.extra.param.key.form_temporary": false,
"ohos.extra.param.key.form_width": 513.5,
"ohos.extra.param.key.module_name": "entry",
"ohos.inner.key.font_follow_system": true
}
获取卡片ID的方式也可以进行简写
// 获取当前添加到桌面的卡片id
let formId:string= want.parameters![formInfo.FormParam.IDENTITY_KEY].toString()
4-卡片事件
针对动态卡片,ArkTS卡片中提供了postCardAction接口用于卡片内部和提供方应用间的交互,当前支持router、message和call三种类型的事件,仅在卡片中可以调用。
动态卡片事件能力说明

动态卡片事件的主要使用场景如下:
router事件:可以使用router事件跳转到指定UIAbility,并通过router事件刷新卡片内容。- call事件:可以使用call事件拉起指定
UIAbility到后台,并通过call事件刷新卡片内容。message事件:可以使用message拉起FormExtensionAbility,并通过FormExtensionAbility刷新卡片内容。
router类型
拉起应用指定页面,可以做为快捷入口进行使用。

- 创建应用页面文件方便通过卡片入口拉起,模拟收集管家拉起不同页面

模拟手机管家的电池管理页面
@Entry
@Component
struct Battery {
build() {
Column() {
Text('电池管理页面').fontSize(30).fontColor('red')
}
.width('100%')
.height('100%')
}
}
模拟手机管家的骚扰拦截页面
@Entry
@Component
struct Intercept {
build() {
Column() {
Text('骚扰拦截页面').fontSize(30).fontColor('green')
}
.width('100%')
.height('100%')
}
}
- 在卡片页面准备不同的入口按钮。并在其点击事件中调用
postCardAction接口。传递不同的参数。以方便在EntryAbility中获取不同的参数,进行不同的页面跳转
模拟手机管家的卡片页面
Button('电池管理')
.onClick(() => {
postCardAction(this, {
action: 'router',
abilityName: 'EntryAbility',
params: {
targetPage: 'Battery'
}
});
})
Button('骚扰拦截')
.onClick(() => {
postCardAction(this, {
action: 'router',
abilityName: 'EntryAbility',
params: {
targetPage: 'Intercept'
}
});
})
- 卡片页面中
postCardAction接口使用router拉起页面时会跳转到提供方应用的指定UIAbility
