# 鸿蒙应用内添加服务卡片到桌面:formProvider.openFormManager 实战
## 一、背景
传统上,用户要添加鸿蒙服务卡片到桌面,需要长按桌面空白处 → 选择服务卡片 → 翻找目标应用 → 添加到桌面。这个路径对于普通用户来说不够直观,很多用户甚至不知道服务卡片的存在。
HarmonyOS 从 API version 18 开始提供了 `formProvider.openFormManager()` 方法,允许**在应用内直接拉起卡片管理页面**,用户只需点击「添加至桌面」即可完成操作。本文以新华字典应用为例,详细介绍这一功能的实现。
---
## 二、效果预览
用户在应用中点击标题栏右侧的 **➕** 按钮 → 系统弹出卡片管理页面 → 点击「添加至桌面」→ 桌面出现新华字典服务卡片,点击卡片即可打开应用。
```
┌──────────────────────┐ ┌──────────────────────┐
│ 新华字典 [➕] │ │ 卡片管理页面 │
│ │ → │ │
│ [🔍 请输入汉字...] │ │ ┌────────────────┐ │
│ │ │ │ 📖 新华字典 │ │
│ 查询结果... │ │ │ [添加至桌面] │ │
│ │ │ └────────────────┘ │
└──────────────────────┘ └──────────────────────┘
```
---
## 三、开发环境
| 工具 | 版本 |
|------|------|
| OpenHarmony SDK | 23(API 11) |
| 目标设备 | HarmonyOS 6.1.0 |
| 开发语言 | ArkTS |
> **注意**:`formProvider.openFormManager()` 从 API 18 开始可用。API 11 版本同样支持,但实际效果取决于设备系统版本。
---
## 四、实现步骤
### 4.1 添加依赖导入
在页面文件中导入所需模块:
```typescript
import { formProvider } from '@kit.FormKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';
import { Want } from '@kit.AbilityKit';
```
各模块的作用:
| 模块 | 用途 |
|------|------|
| `@kit.FormKit` | `formProvider` 提供 `openFormManager` 方法 |
| `@kit.BasicServicesKit` | `BusinessError` 用于错误类型判断 |
| `@kit.ArkUI` | `promptAction` 用于 Toast 提示 |
| `@kit.AbilityKit` | `Want` 定义跳转目标 |
### 4.2 实现 openFormManager 方法
```typescript
/**
* 打开卡片管理页面,将服务卡片添加到桌面
*/
openFormManager(): void {
const want: Want = {
bundleName: 'com.nutpi.myapplication',
abilityName: 'DictionaryFormAbility',
parameters: {
'ohos.extra.param.key.form_dimension': 2,
'ohos.extra.param.key.form_name': 'DictionaryForm',
'ohos.extra.param.key.module_name': 'entry'
},
};
try {
formProvider.openFormManager(want);
} catch (error) {
promptAction.openToast({
message: (error as BusinessError).message
});
}
}
```
### 4.3 Want 参数详解
| 参数 | 值 | 说明 |
|------|-----|------|
| `bundleName` | `com.nutpi.myapplication` | 应用的包名,与 `AppScope/app.json5` 中的 `bundleName` 一致 |
| `abilityName` | `DictionaryFormAbility` | FormExtensionAbility 的名称,与 `module.json5` 中注册的名称一致 |
| parameters.`form_dimension` | `2` | 默认卡片尺寸(1=1×2,2=2×2) |
| parameters.`form_name` | `DictionaryForm` | 卡片名称,与 `form_config.json` 中的 `name` 一致 |
| parameters.`module_name` | `entry` | 模块名 |
### 4.4 添加 UI 入口
在标题栏添加一个按钮,触发 `openFormManager`:
```typescript
Row() {
Text('新华字典')
.fontSize(22)
.fontWeight(FontWeight.Bold)
.fontColor('#1a1a2e')
.layoutWeight(1)
// 添加到桌面按钮
Button() {
Text('➕').fontSize(16)
}
.width(40)
.height(40)
.borderRadius(20)
.backgroundColor('#f0f0f5')
.margin({ right: 16 })
.onClick(() => {
this.openFormManager();
})
}
```
---
## 五、完整代码
```typescript
import { queryWord } from '../utils/WordApi';
import { WordItemData } from '../model/WordData';
import { formProvider } from '@kit.FormKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';
import { Want } from '@kit.AbilityKit';
@Entry
@Component
struct Index {
@State searchWord: string = '';
@State wordData: WordItemData | null = null;
@State isLoading: boolean = false;
@State errorMsg: string = '';
build() {
Column() {
Row() {
Text('新华字典')
.fontSize(22)
.fontWeight(FontWeight.Bold)
.fontColor('#1a1a2e')
.layoutWeight(1)
Button() {
Text('➕').fontSize(16)
}
.width(40).height(40).borderRadius(20)
.backgroundColor('#f0f0f5')
.margin({ right: 16 })
.onClick(() => { this.openFormManager(); })
}
.width('100%')
.padding({ top: 16, bottom: 8, left: 20 })
// ... 搜索和结果 UI ...
}
}
openFormManager(): void {
const want: Want = {
bundleName: 'com.nutpi.myapplication',
abilityName: 'DictionaryFormAbility',
parameters: {
'ohos.extra.param.key.form_dimension': 2,
'ohos.extra.param.key.form_name': 'DictionaryForm',
'ohos.extra.param.key.module_name': 'entry'
},
};
try {
formProvider.openFormManager(want);
} catch (error) {
promptAction.openToast({
message: (error as BusinessError).message
});
}
}
}
```
---
## 六、前置条件:卡片必须已正确配置
`openFormManager` 能够正确工作的前提是**服务卡片已经正确配置**。确保以下几点:
### 6.1 form_config.json 存在且正确
```json
{
"forms": [{
"name": "DictionaryForm",
"displayName": "新华字典",
"src": "./ets/form/FormWidget.ets",
"uiSyntax": "arkts",
"updateEnabled": true,
"defaultDimension": "1*2",
"supportDimensions": ["1*2", "2*2"]
}]
}
```
### 6.2 FormExtensionAbility 已注册
在 `module.json5` 中:
```json5
{
"extensionAbilities": [{
"name": "DictionaryFormAbility",
"srcEntry": "./ets/form/FormAbility.ets",
"type": "form",
"exported": true,
"metadata": [{
"name": "ohos.extension.form",
"resource": "$profile:form_config"
}]
}]
}
```
### 6.3 卡片名称保持一致
以下三个位置的卡片名称必须完全一致:
| 位置 | 字段 |
|------|------|
| `form_config.json` | `name: "DictionaryForm"` |
| `module.json5` | `name: "DictionaryFormAbility"` |
| `openFormManager` 参数 | `form_name: "DictionaryForm"` |
---
## 七、常见问题
### Q1:点击按钮后无反应?
**检查项**:
1. `form_config.json` 是否存在且格式正确
2. `module.json5` 中 FormExtensionAbility 的 `type: "form"` 和 `metadata` 配置是否正确
3. `openFormManager` 的 `bundleName` 是否与 `app.json5` 中的一致
### Q2:提示「未找到卡片信息」?
**可能原因**:`form_name` 与 `form_config.json` 中的 `name` 不一致。
**解决**:确保两个地方完全匹配。
### Q3:卡片管理页面空白?
**可能原因**:设备系统版本过低,不支持此 API。
**解决**:在 API 18+ 的设备上测试。低版本设备需要改用传统方式(桌面长按添加)。
---
## 八、用户体验建议
1. **加个引导**:首次打开应用时,可以通过弹窗提示用户「添加到桌面,快速查询」
2. **位置显眼**:按钮放在标题栏等用户容易注意到的位置
3. **加个 Toast 反馈**:添加成功或失败时给用户明确的反馈(已用 try-catch + promptAction 实现)
4. **配合使用教程**:可以做一个简单的引导页面,教会用户如何使用卡片
---
## 九、总结
`formProvider.openFormManager()` 是提升鸿蒙服务卡片使用率的利器。通过在应用内提供「添加到桌面」入口,用户可以更便捷地发现和使用服务卡片功能。
核心要点:
- 三步走:导入模块 → 配置 Want → 调用 `openFormManager`
- 三个名称必须一致:`form_config.json` / `module.json5` / `openFormManager` 参数
- 三个前提条件:form_config 存在 / FormExtensionAbility 注册 / 卡片名称匹配
---
## 项目地址
本文所有代码已开源:[https://gitcode.com/jianguoxu/myapplication](https://gitcode.com/jianguoxu/myapplication)
鸿蒙应用内添加服务卡片到桌面:formProvider.openFormManager 实战
不爱吃糖的程序媛2026-06-05 11:49
相关推荐
不爱吃糖的程序媛1 小时前
hionic框架设备信息获取:@ionic-native/device 插件在鸿蒙PC平台的适配实践小雨下雨的雨1 小时前
鸿蒙PC用Electron框架——Canvas蜡笔抖动效果实现技术深度解析tigershang2 小时前
华为“韬定律”:从“缩小尺寸”到“压缩时间”——后摩尔时代的规则重塑小雨下雨的雨2 小时前
蜡笔小画家鸿蒙PC用Electron框架 - 儿童学画蜡笔画技术实现详解坚果的博客2 小时前
【鸿蒙 PC三方库构建系统】README.OpenSource 文件深度解读川石课堂软件测试2 小时前
什么是埋点测试,app埋点测试怎么做?Swift社区2 小时前
鸿蒙 App 状态管理:实现原理 + 最佳实践网络与设备以及操作系统学习使用者2 小时前
多路由设备静态路由配置详解IT大白鼠2 小时前
GRE协议原理与华为设备配置实践