更新记录

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+ 依赖服务卡片能力

推荐调用模型

单卡片场景

如果项目只有一张卡片,可以直接调用:

  1. setAppGroup(),仅 iOS 必需,其余平台作为兼容接口
  2. setWidgetConfig()
  3. setWidgetData()
  4. reloadWidget()reloadAllWidgets()

多卡片场景

如果项目有多张卡片,推荐统一采用下面的模式:

  1. 先调用 setCurrentWidgetKind(kind)
  2. 再调用 setWidgetConfig() / setWidgetData() / reloadWidget()

这样业务层只维护一套 API,不需要自己再封装 small/medium/large 三套接口。

快速开始

1. 导入插件

uni-appuni-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 xuts 风格写法:

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 setupscript 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 IDProvisioning Profile
  • 业务层仍然使用逻辑 kind:
    • HlFormWidgetSmall
    • HlFormWidgetMedium
    • HlFormWidgetLarge
  • WidgetKit 实际注册到系统的是一个统一入口 HlFormWidget,三种尺寸由 family 区分
  • 无法通过代码直接把小组件添加到桌面,用户必须手动添加

Android

  • 插件已内置 AppWidgetProvider 模板与布局资源
  • 当前默认 kind:
    • HlAppWidgetTiny
    • HlAppWidgetSmall
    • HlAppWidget
    • HlAppWidgetLarge
  • addWidget(kind) 仅 Android 有效
  • 当前 Android 侧的 setWidgetConfig() 使用共享配置仓,适合单套模板快速演示

鸿蒙

  • 需要项目侧注册服务卡片
  • 当前推荐按多卡片名称区分:
    • HlFormWidgetSmall
    • HlFormWidgetMedium
    • HlFormWidgetLarge
  • 用户必须手动把卡片添加到桌面
  • reloadWidget() 会尝试刷新已发布卡片;如果卡片未上桌面,日志可能提示跳过
  • 详细接入步骤建议继续参考 docs/harmony-widget-setup.md

接入步骤

iOS 接入

  1. 准备主 App Bundle ID、Widget Bundle ID、App Group。
  2. 在 Apple Developer 后台分别创建:
    • 主 App App ID
    • Widget Extension App ID
    • App Group
    • 主 App Development Profile
    • Widget Extension Development Profile
  3. 在 Xcode 中为主 App 和 Widget Extension 同时开启同一个 App Group。
  4. 把 Widget Extension 产物导入插件目录:
    • uni_modules/hl-widget-uts/utssdk/app-ios/Plugins/HlWidget.appex
  5. 在项目侧补齐:
    • nativeResources/ios/ios-extension.json
    • nativeResources/ios/UniApp.entitlements
    • nativeResources/ios/*.mobileprovision

完整步骤见:

  • ios-widget-setup.md
  • utssdk/app-ios/Plugins/README.md

Android 接入

  1. 安装插件并重新制作 Android 自定义基座或重新打包。
  2. 使用插件内置 Provider / layout 模板。
  3. 业务层调用:
    • setCurrentWidgetKind()
    • setWidgetConfig()
    • reloadWidget()
  4. 如需引导用户添加桌面组件,可调用 addWidget(kind)

鸿蒙接入

  1. 在项目侧注册服务卡片。
  2. 约定每张卡片的 form name,与前端 kind 保持一致。
  3. 在页面中先调用 setCurrentWidgetKind(kind)
  4. 再调用 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 区分;业务层仍然使用 HlFormWidgetSmallHlFormWidgetMediumHlFormWidgetLarge 三个逻辑 kind。

3. 为什么 Android 可以代码添加,iOS / 鸿蒙不行?

因为系统能力不同:

  • Android 支持 requestPinAppWidget
  • iOS 不提供代码添加 Widget 的能力
  • 鸿蒙也不支持插件侧直接把卡片加到桌面

4. 为什么要区分 uni-appuni-app x

主要是运行环境、语言形态和类型约束不同,不是 API 名称不同:

  • 两者导入方式一致
  • 两者 API 名称一致
  • 两者都只能在 App 端使用
  • uni-app x 更强调 UTS 强类型写法
  • uni-app x 在 iOS Extension、原生打包链路上通常更依赖项目侧原生配置

5. 鸿蒙端除了页面调用,还需要补哪些配置?

至少还要检查:

  • 服务卡片注册是否完成
  • form name 与 setCurrentWidgetKind() 传入值是否一致
  • 卡片页面或 Ability 是否能读取同名配置仓

联系作者

如有未说明清楚的接入问题、平台适配问题或调试问题,欢迎进入交流群联系作者沟通。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

iOS 需要 Widget Extension 配置 App Group;Android 需要桌面小组件相关权限;鸿蒙需要服务卡片相关配置

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件通过 App Group 在 App 与小组件之间共享数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。