更新记录
1.0.0(2026-06-29)
初始版本发布 支持 iOS WidgetKit 桌面小组件(App Group 数据共享 + 刷新触发) 支持 Android AppWidgetProvider 桌面小组件(SharedPreferences 数据共享 + 广播更新) 支持鸿蒙 HarmonyOS 服务卡片支持(Preferences 数据存储 + formProvider 卡片刷新)
平台兼容性
uni-app(4.72)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-vue插件版本 | app-nvue | app-nvue插件版本 | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 鸿蒙插件版本 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | √ | 1.0.0 | √ | 1.0.0 | 4.4 | 1.0.0 | 12 | 1.0.0 | 12 | 1.0.0 |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
hl-widget-uts 桌面小组件插件
插件概述
插件目标不是屏蔽所有平台差异,而是把业务层最常用的能力统一起来:
- 设置当前操作目标卡片:
setCurrentWidgetKind() - 写入显示配置:
setWidgetConfig() - 写入共享数据:
setWidgetData() - 读取共享数据:
getWidgetData() - 触发刷新:
reloadWidget()/reloadAllWidgets()
适用环境
uni-app 与 uni-app x
| 维度 | uni-app | uni-app x |
|---|---|---|
可直接 import '@/uni_modules/hl-widget-uts' |
支持 | 支持 |
| 可在页面 / 组合式逻辑中调用 | 支持 | 支持 |
| 适用端 | App-Android / App-iOS / App-鸿蒙 | App-Android / App-iOS / App-鸿蒙 |
| H5 / 小程序 | 不支持 | 不支持 |
| iOS Widget Extension 接入 | 需要 | 需要 |
| Android Widget 布局与 Provider | 插件已提供模板 | 插件已提供模板 |
| 鸿蒙服务卡片注册 | 需要项目侧继续配置 | 需要项目侧继续配置 |
API 使用环境说明
uni-app:建议在.vue页面、composables、普通js/ts模块中调用。uni-app x:建议在uvue页面、<script lang="uts">、uts风格逻辑模块中调用。- 两者的导入路径和 API 名称保持一致,但
uni-app x示例应按强类型风格编写。 - 这是原生能力插件,只在
APP端有效,不能当作H5或小程序通用 API 使用。
推荐在业务代码中加平台判断:
// #ifdef APP
import * as HlWidget from '@/uni_modules/hl-widget-uts'
// #endif
平台支持
| 平台 | 最低版本 | 说明 |
|---|---|---|
| iOS | iOS 14.0+ | 依赖 WidgetKit |
| Android | minSdk 21 | requestPinAppWidget 受系统版本与桌面实现影响 |
| 鸿蒙 | HarmonyOS API 12+ | 依赖服务卡片能力 |
推荐调用模型
单卡片场景
如果项目只有一张卡片,可以直接调用:
setAppGroup(),仅 iOS 必需,其余平台作为兼容接口setWidgetConfig()setWidgetData()reloadWidget()或reloadAllWidgets()
多卡片场景
如果项目有多张卡片,推荐统一采用下面的模式:
- 先调用
setCurrentWidgetKind(kind) - 再调用
setWidgetConfig()/setWidgetData()/reloadWidget()
这样业务层只维护一套 API,不需要自己再封装 small/medium/large 三套接口。
快速开始
1. 导入插件
uni-app 与 uni-app x 的插件导入路径一致:
import * as HlWidget from '@/uni_modules/hl-widget-uts'
补充说明:
uni-app中可按普通JavaScript / TypeScript风格组织调用。uni-app x中建议显式声明参数类型、返回值类型和配置对象类型。- 当前插件已经通过
interface.uts暴露类型定义,uni-app x可直接按强类型方式引用。
2. 最小调用示例
import * as HlWidget from '@/uni_modules/hl-widget-uts'
function updateSmallCard() {
HlWidget.setAppGroup('group.com.halolion.widgetdemo')
HlWidget.setCurrentWidgetKind('HlFormWidgetSmall')
const configResult = HlWidget.setWidgetConfig({
title: '今日天气',
subtitle: '上海 · 多云',
body: '温度: 28°C\n湿度: 62%\n空气质量: 良',
imageName: null,
backgroundColor: '#1F4B99',
textColor: '#FFFFFF',
titleFontSize: null,
subtitleFontSize: null,
bodyFontSize: null,
extraData: '{"scene":"weather","size":"small"}'
})
const dataResult = HlWidget.setWidgetData(
'weather_info',
'{"temp":28,"humidity":62,"aqi":"良"}'
)
const reloadResult = HlWidget.reloadWidget('HlFormWidgetSmall')
console.log(configResult.message)
console.log(dataResult.message)
console.log(reloadResult.message)
}
3. uni-app 页面示例
import { onLoad } from '@dcloudio/uni-app'
import * as HlWidget from '@/uni_modules/hl-widget-uts'
onLoad(() => {
HlWidget.setAppGroup('group.com.halolion.widgetdemo')
HlWidget.setCurrentWidgetKind('HlFormWidgetMedium')
})
4. uni-app x 页面示例
下面示例进一步贴近 uni-app x 的 uts 风格写法:
import * as HlWidget from '@/uni_modules/hl-widget-uts'
import {
WidgetConfig,
WidgetResult
} from '@/uni_modules/hl-widget-uts'
function updateLargeCard(): WidgetResult {
const groupResult: WidgetResult = HlWidget.setAppGroup('group.com.halolion.widgetdemo')
if (groupResult.code != 0) {
return groupResult
}
const kindResult: WidgetResult = HlWidget.setCurrentWidgetKind('HlFormWidgetLarge')
if (kindResult.code != 0) {
return kindResult
}
const config: WidgetConfig = {
title: '经营看板',
subtitle: '本周概览',
body: '订单: 128\n成交额: 56300\n待发货: 9',
imageName: null,
backgroundColor: '#0E2A56',
textColor: '#FFFFFF',
titleFontSize: null,
subtitleFontSize: null,
bodyFontSize: null,
extraData: '{"scene":"dashboard"}'
}
const configResult: WidgetResult = HlWidget.setWidgetConfig(config)
if (configResult.code != 0) {
return configResult
}
return HlWidget.reloadWidget('HlFormWidgetLarge')
}
如果页面本身使用 script setup 或 script lang="uts",也建议保留这种显式类型标注,而不是完全按弱类型对象调用。
API 总览
App Group / 当前卡片
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
setAppGroup |
(identifier: string) |
WidgetResult |
iOS 必需;Android / 鸿蒙兼容保存 |
getAppGroup |
() |
string \| null |
获取当前 App Group |
setCurrentWidgetKind |
(kind: string) |
WidgetResult |
设置当前操作目标卡片 |
getCurrentWidgetKind |
() |
string |
获取当前操作目标卡片 |
数据读写
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
setWidgetData |
(key: string, value: string) |
WidgetResult |
写入当前卡片共享数据 |
getWidgetData |
(key: string) |
string \| null |
读取当前卡片共享数据 |
removeWidgetData |
(key: string) |
WidgetResult |
移除当前卡片某条数据 |
getAllWidgetData |
() |
UTSJSONObject |
读取当前卡片全部共享数据 |
clearAllWidgetData |
() |
WidgetResult |
清空当前卡片全部共享数据 |
显示配置
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
setWidgetConfig |
(config: WidgetConfig) |
WidgetResult |
写入显示配置并尝试刷新 |
getWidgetConfig |
() |
WidgetConfig \| null |
读取当前卡片显示配置 |
刷新 / 状态
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
reloadAllWidgets |
() |
WidgetResult |
刷新全部卡片 |
reloadWidget |
(kind: string) |
WidgetResult |
刷新指定卡片 |
isWidgetAvailable |
() |
boolean |
检查当前平台是否支持小组件 |
getWidgetInfo |
() |
WidgetInfo |
获取平台 / kind / App Group 信息 |
Android 专有
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
addWidget |
(kind: string) |
WidgetResult |
触发 Android 添加到桌面流程 |
类型说明
WidgetConfig
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
title |
string |
是 | 主标题 |
subtitle |
string |
是 | 副标题 |
body |
string |
是 | 正文 |
imageName |
string \| null |
否 | 图片资源标识 |
backgroundColor |
string \| null |
否 | 背景色,示例 #1F4B99 |
textColor |
string \| null |
否 | 文本颜色 |
titleFontSize |
number \| null |
否 | 标题字号 |
subtitleFontSize |
number \| null |
否 | 副标题字号 |
bodyFontSize |
number \| null |
否 | 正文字号 |
extraData |
string \| null |
否 | 扩展 JSON 字符串 |
WidgetResult
| 字段 | 类型 | 说明 |
|---|---|---|
code |
number |
0 表示成功 |
message |
string |
结果说明 |
data |
UTSJSONObject \| null |
附加数据 |
WidgetInfo
| 字段 | 类型 | 说明 |
|---|---|---|
appGroupIdentifier |
string |
当前 App Group |
widgetKind |
string |
当前卡片标识 |
platform |
string |
ios / android / harmony |
available |
boolean |
当前平台是否支持 |
三端差异说明
iOS
- 必须有独立的
Widget Extension - 必须有
App Group - 主 App 和 Extension 必须分别使用各自的
Bundle ID与Provisioning Profile - 业务层仍然使用逻辑 kind:
HlFormWidgetSmallHlFormWidgetMediumHlFormWidgetLarge
- WidgetKit 实际注册到系统的是一个统一入口
HlFormWidget,三种尺寸由 family 区分 - 无法通过代码直接把小组件添加到桌面,用户必须手动添加
Android
- 插件已内置
AppWidgetProvider模板与布局资源 - 当前默认 kind:
HlAppWidgetTinyHlAppWidgetSmallHlAppWidgetHlAppWidgetLarge
addWidget(kind)仅 Android 有效- 当前 Android 侧的
setWidgetConfig()使用共享配置仓,适合单套模板快速演示
鸿蒙
- 需要项目侧注册服务卡片
- 当前推荐按多卡片名称区分:
HlFormWidgetSmallHlFormWidgetMediumHlFormWidgetLarge
- 用户必须手动把卡片添加到桌面
reloadWidget()会尝试刷新已发布卡片;如果卡片未上桌面,日志可能提示跳过- 详细接入步骤建议继续参考
docs/harmony-widget-setup.md
接入步骤
iOS 接入
- 准备主 App Bundle ID、Widget Bundle ID、App Group。
- 在 Apple Developer 后台分别创建:
- 主 App App ID
- Widget Extension App ID
- App Group
- 主 App Development Profile
- Widget Extension Development Profile
- 在 Xcode 中为主 App 和 Widget Extension 同时开启同一个 App Group。
- 把 Widget Extension 产物导入插件目录:
uni_modules/hl-widget-uts/utssdk/app-ios/Plugins/HlWidget.appex
- 在项目侧补齐:
nativeResources/ios/ios-extension.jsonnativeResources/ios/UniApp.entitlementsnativeResources/ios/*.mobileprovision
完整步骤见:
ios-widget-setup.mdutssdk/app-ios/Plugins/README.md
Android 接入
- 安装插件并重新制作 Android 自定义基座或重新打包。
- 使用插件内置 Provider / layout 模板。
- 业务层调用:
setCurrentWidgetKind()setWidgetConfig()reloadWidget()
- 如需引导用户添加桌面组件,可调用
addWidget(kind)。
鸿蒙接入
- 在项目侧注册服务卡片。
- 约定每张卡片的 form name,与前端
kind保持一致。 - 在页面中先调用
setCurrentWidgetKind(kind)。 - 再调用
setWidgetConfig()/setWidgetData()/reloadWidget(kind)。
建议配合阅读:
- 项目根目录
docs/harmony-widget-setup.md
项目当前 iOS 配置示例
当前示例工程使用的是下面这套值:
| 类型 | 值 |
|---|---|
| Team ID | WV2C27YULD |
| 主 App Bundle ID | com.halolion.widgetdemo |
| Widget Bundle ID | com.halolion.widgetdemo.widget |
| App Group | group.com.halolion.widgetdemo |
| 项目内主 App profile | nativeResources/ios/halolion_widgetdemo.mobileprovision |
| 项目内 Widget profile | nativeResources/ios/halolion_widgetdemo_widget.mobileprovision |
调试建议
iOS
- 看
WidgetExtensionTemplate/HlTimelineProvider.swift是否读到了正确的 App Group 和配置 key - 看
reloadWidget()触发后桌面卡片是否已经被用户添加 - 如果归档报
ValidateEmbeddedBinary,先检查.appex是否被主工程重签
Android
- 看
AppWidgetProvider是否收到刷新广播 - 看当前
kind是否匹配正确的 Provider 类 - 若桌面未更新,先确认系统是否已经添加了对应 widget
鸿蒙
- 看
Hybrid.ets的日志输出 - 看目标卡片是否已发布到桌面
- 看
kind与 form name 是否一致 - 看
Preferences中按kind隔离的配置是否已写入
常见问题
1. 为什么 API 调用了,但 iOS 卡片没变化?
常见原因:
- 没先调用
setAppGroup() - App Group 不一致
- Widget Extension 没有正确嵌入打包
- 目标卡片尚未添加到桌面
2. 为什么 iOS 只能看到一个 Widget 入口?
这是当前 iOS 设计的预期。
系统里注册的是一个 HlFormWidget,小 / 中 / 大三种卡片通过 family 区分;业务层仍然使用 HlFormWidgetSmall、HlFormWidgetMedium、HlFormWidgetLarge 三个逻辑 kind。
3. 为什么 Android 可以代码添加,iOS / 鸿蒙不行?
因为系统能力不同:
- Android 支持
requestPinAppWidget - iOS 不提供代码添加 Widget 的能力
- 鸿蒙也不支持插件侧直接把卡片加到桌面
4. 为什么要区分 uni-app 和 uni-app x?
主要是运行环境、语言形态和类型约束不同,不是 API 名称不同:
- 两者导入方式一致
- 两者 API 名称一致
- 两者都只能在 App 端使用
uni-app x更强调UTS强类型写法uni-app x在 iOS Extension、原生打包链路上通常更依赖项目侧原生配置
5. 鸿蒙端除了页面调用,还需要补哪些配置?
至少还要检查:
- 服务卡片注册是否完成
- form name 与
setCurrentWidgetKind()传入值是否一致 - 卡片页面或 Ability 是否能读取同名配置仓
联系作者
如有未说明清楚的接入问题、平台适配问题或调试问题,欢迎进入交流群联系作者沟通。

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 276
赞赏 2
下载 12357152
赞赏 1926
赞赏
京公网安备:11010802035340号