## 1. 粘贴按钮改成与「地图」一样 原来只用系统默认样式,与旁边的「地图」按钮风格割裂。 安全控件支持 fontSize / fontColor / backgroundColor / borderRadius / padding (见 security_component.d.ts),所以可以完全对齐: 13 号字 · brand_text 色 · card_bg 底 · 圆角 12 · 高 44 与「地图」并排、同高、同样留白。文字内容由系统枚举决定 (`PasteDescription` 只有 `PASTE` 一个值,即「粘贴」)。 真机实测两个按钮并排: PasteButton [680,1802][837,1940] 文字='粘贴' Text(地图) [862,1802][1018,1940] 文字='地图' 同高同排,13 号字。 ## 2. 待办卡片列表对齐 App 内样式 用户指出:卡片里的待办样式(灰勾选框 + 色条)与 App 内待办列表不一致, 两套设计没必要。App 内 `Index.todoRow` 的样式是: - 勾选圈 **颜色跟随日历本**(未完成=空心环 2px,已完成=实心+✓) - 标题 15 号,已完成加删除线 - 副行 12 号 = 截止时间 · 日历本 - 行背景 card_bg,圆角 12,1px 边框 卡片侧改为同一套结构,只按卡片尺寸把号数收小: | 卡片 | 圈 | 标题 | 副行 | |---|---|---|---| | 4×4 / 6×4 | 18 | 13 | 10 | | 2×4 | 16 | 12 | 9 | 去掉原来的色条和灰色勾选框 —— 用日历本色圆圈,与 App 内视觉一致。 数据侧给 `TodoCardItem` 增加 `subText`(「截止时间 · 日历本」拼好的副行文字), 由数据层统一拼接,避免三张卡片各拼一遍导致不一致。 ## 一致性校验 逐行 diff 确认 4×4 与 6×4 的 `todoRow` **完全一致**(归一化类型名后逐字符相等); 2×4 结构相同,仅尺寸小一档。 ## 编译 `BUILD SUCCESSFUL` ## 未验证 粘贴按钮已确认渲染与布局(dump 坐标/文字),视觉观感需上机目视; 待办卡片需删除桌面旧卡片后重新添加才能看到新样式。
SyncCalendar(同步日历)
一款以同步为核心的鸿蒙原生日历应用,基于 HarmonyOS NEXT(ArkTS / Stage 模型)开发。对接标准 CalDAV 服务器(群晖、Nextcloud、Radicale、Baikal 等),让你的日程真正掌握在自己手里——不经过第三方云服务,数据始终同步在你自己的 NAS 上。
- 应用市场送审版本:0.2.0 | 仓库当前:0.2.0(versionCode 10200)
- 官网:https://synccalendar.yangyq.net | 问题反馈:https://feedlite.yangyq.net/?sw=synccalendar
- 开源协议:Apache License 2.0
📝 最近更新
v0.2.0(2026-11)
待办(VTODO)从只读升级为完整双向同步
- 新增
TodoService:新建 / 编辑 / 打勾完成 / 删除待办,全部推送回服务器 - 打过勾会改写
STATUS:COMPLETED+PERCENT-COMPLETE:100并 PUT - 修改前先 GET 原始
.ics,原地改写而不是整份重建 —— 保留服务器上本应用不认识的属性 - 日历本按类型区分「日历」与「待办」,待办在专属 Tab 中管理
同步核心修复(3 项高危)
- 删除 404:
remotePath改为保存服务器真实资源文件名。此前一直用encodeURIComponent(uid) + '.ics'去猜,遇到「文件名 ≠ UID」的服务器 (如用preg_replace改名的家书)会 DELETE 到不存在的路径 → 404 → 服务器上删不掉。 修复覆盖三条取值链路:REPORT 补拉、etag 未变的复用路径、以及 unchanged 分支的存量回填。 - 防复活:
applyRemote增加dirtyKeyed/dirtyDeletedUids白名单。 此前只把 dirty 行排除出索引,远端数据查不到就走"新增"分支又插一行, 导致同一事件出现两条、或"删了又回来"。 - 404/410 物理清库:删除请求返回 404/410 时视为服务器上已不存在, 继续清理本地行而不是直接 return —— 否则用户会看到"怎么删都删不掉"的日程。
反馈渠道迁移
- 从自建 PHP 论坛迁至多软件共用的 FeedLite,按软件分栏管理
v0.1.0(首个送审版本)
- CalDAV 全链路同步、月/周/列表视图、重复日程展开、系统日历镜像、桌面卡片、后台上层同步
✨ 功能特性
CalDAV 同步
- 完整协议链路:PROPFIND 发现日历本 → REPORT 全量拉取 → ETag 增量比对 → PUT / DELETE 双向推送
- 一个账号可挂载多个日历本,按需勾选同步范围;支持在线编辑账号、重选日历本、删除账号
- 解析 VEVENT / VTODO / VALARM / RRULE / EXDATE / RECURRENCE-ID,重复日程的单次覆盖实例也能正确还原
- 完整 VTODO 待办支持:新建 / 编辑 / 打勾完成 / 删除,均可双向推送回服务器
- 待办与日程分列:日历本按类型区分「日历」与「待办」,待办在专属 Tab 中管理
- 打勾完成会改写
STATUS:COMPLETED+PERCENT-COMPLETE:100并 PUT 回服务器 - 修改时先 GET 原始
.ics再原地改写,保留服务器上本应用不认识的属性
- 「重建日程数据」可强制整表重拉,用于修复提醒丢失等本地数据问题
日历视图与交互
- 月 / 周 / 列表 三种视图(顶部标签切换,也支持左右滑动手势);默认视图可在设置里指定
- 月视图三页 Swiper 左右翻月、显示农历(初一显示月名),点击查看当日日程
- 周视图支持按天左右滑动切换日期,跨月自动重载
- 列表视图按天分组、今日置顶,配合 List 虚拟化保证长列表流畅
- 日程显示方式两种:竖向时间轴(按时间刻度看一天的占用与冲突,带当前时间红线)/列表(快速扫读,适合长标题)
- 重复日程(RRULE)按规则完整展开:DAILY / WEEKLY / MONTHLY / YEARLY 及 INTERVAL、BYDAY、UNTIL、EXDATE 等
- 可选混合显示系统日历,并与 DAV 数据自动去重
- 点击日程里的「地点」可拉起高德 App 路线规划(系统地理编码 + WGS84→GCJ02 坐标转换,地址文本不落日志)
日程编辑与提醒
- 新建 / 编辑 / 删除日程并推送回服务器,支持全天日程、地点、描述、重复规则、多级提前提醒
- 地点搜索补全:在「地点」栏输入关键词即可列出匹配地点(华为 Map Kit / Site Kit),点一下填入完整地址;也可点「地图」进入系统地图界面搜索、拖动图钉选点。不申请任何定位权限,手动输入同样可用
- 一键导航:日程详情中点击「导航 ›」,用系统地理编码把地点地址换算为坐标后唤起高德地图;未安装则回退网页版。不申请定位权限(
getAddressesFromLocationName无需该权限),不会读取设备实时位置 - 必填项校验强提醒:未填标题等必填项时,以 Toast + 输入框标红 + 自动滚回定位三管齐下提示,不会出现"提示在屏幕外看不到"的情况
- 自动读取服务器端 VALARM 提醒(如"开始前 10 分钟")
- 基于系统级代理提醒(
reminderAgentManager)发送通知,App 被杀、手机重启后依然生效,通知可右滑删除 - 保存带提醒的日程时会在那一刻申请通知权限;被拒绝也不影响日程保存,之后可在设置页再开启
CalDAV 地址自动发现
- 只填服务器域名也能用:按标准
/.well-known/caldav自动发现端点,并在常见路径(Nextcloud、群晖等)中依次尝试 - 发现时只认
resourcetype含calendar的集合,避免把 DAV 根或分享链接误当成日历 - 失败时给出人话错误提示(如"正确形式通常为
https://域名/remote.php/dav/calendars/用户名/"),而不是抛原始状态码
系统日历镜像(可选增强,默认关闭)
镜像是可选项,App 本体不依赖它也能完整使用。开启后:
- 镜像到系统日历:把选中的 CalDAV 日历本写入系统日历,这样小艺语音、桌面日历卡片和手表也能看到你的日程。每个日历本在系统日历里是独立账户,可单独设色与隐藏
- 把系统日历的改动回写:你在系统日历里新建、修改、删除的日程,同步回指定的 CalDAV 日历本(相当于把本机日程备份到服务器)
- 采用星型架构:服务器 ↔ 本地库、本地库 ↔ 系统日历各做一次两方同步,不会互相污染
- 日历本用稳定的 bookId(
账号ID-资源路径哈希)标识,不随勾选顺序变化;取消勾选、目标失效时会自动关闭备份并把相关账户清理干净,绝不把日程写进你没选过的日历本 - 重复日程不写入系统
recurrenceRule,而是按时间窗口自行展开(过去 1 年 ~ 未来 2 年),保证RECURRENCE-ID覆盖与EXDATE排除精确对应
桌面服务卡片
- 四种规格:2×2 / 2×4 / 4×4 / 6×4,时间轴样式设计
- 按天分组展示未来日程,组内全天事件置顶;跨天日程智能归入"今天",标注"全天"
- 每条日程左侧竖条颜色与日历本一致,右侧显示所属日历本名
- 同步完成后自动刷新,
formId持久化保证 App 重启后推送不丢
后台同步与数据备份
- 前台自动同步:App 在前台时按设定间隔自动同步(可设 1 / 5 / 15 / 30 分钟)
- 后台自动同步:开启后由系统定时唤起同步,退到后台也会继续(受系统省电策略限制,最短约 2 小时一次)
- 回到前台 / 网络恢复补同步:切回应用、或从断网恢复到有网时,立即补同步一次,保证你打开日历时数据总是最新的
- 应用数据备份/恢复:接入 Backup 扩展能力,换机时可恢复账号与本地数据
说明:HarmonyOS 出于省电考虑,不允许普通应用在后台常驻并高频轮询 (长时任务
dataTransfer超过 10 分钟无进度即被系统取消,延迟任务存在小时级下限)。 本应用遵循系统机制,采用「前台按间隔同步 + 后台定时唤起 + 回前台/网络恢复即时补同步」的分层组合。
界面与适配
- 深色模式:全程使用资源引用(
$r('app.color.*')),深浅两套色板一一对应,跟随系统自动切换 - 沉浸式:系统状态栏与导航栏全透明,每页(含内置文档页)都做了安全区扩展
- 大屏与横竖屏:以窗口短边是否达到 840vp 作为大屏判据(而非屏幕方向),因此折叠屏展开态、平板可自由横竖屏切换,而在屏幕比例接近 1:1 的设备上旋转时布局保持一致
- 转场动效:所有页面使用系统转场,淡入淡出 + 弹簧曲线(
curves.springMotion),不做单帧直切、左右平移或上下位移
设置项一览
系统日历
- 镜像到系统日历(含「选择要镜像的日历本」)
- 把系统日历的改动回写
- 系统日历中的显示名称(三种命名格式可选)
- 混合显示系统日历(关闭后只显示 DAV 账号的日程)
- 清除系统日历数据(卸载前清理镜像数据,防止残留孤儿账户)
通用
- 默认视图(月 / 周 / 列表)
- 日程显示方式(竖向时间轴 / 列表)
- 自动同步间隔(1 / 5 / 15 / 30 分钟)
- 后台自动同步
- 通知权限
数据
- 重建日程数据(强制整表重拉)
- 重置账号库
- 日历本只读 / 静音(逐本设置)
关于
- 软件特性 · 使用帮助 · 问题反馈 · 隐私政策与用户协议
🔒 隐私
我们遵循"数据自持、最小必要"原则:
- 开发者不保存你的日程与账号数据(账号密码只存在本机,且以 AES-256-GCM 加密存储,密钥由系统 HUKS/TEE 保管、不可导出)
- 不收集通讯录、相册、剪贴板等信息,不含任何第三方统计或广告 SDK
- 页面从不展示他人邮箱;日志对日程标题、地点等敏感字段做脱敏处理
- 不申请定位权限:本应用从不读取设备实时位置。「一键导航」所需的坐标由系统地理编码服务按你填写的地址文本换算,故
module.json5中不含LOCATION/APPROXIMATELY_LOCATION - 地点关键词检索由 HarmonyOS 系统能力华为地图服务(Map Kit / Site Kit)提供,仅用于检索,不用于广告、画像或统计分析
- 权限按需申请:只有当你主动使用某个功能(如开启镜像、设置提醒)时才弹窗申请,启动、首启、同意隐私政策时都不会提前申请
- 权限被拒绝后,对应功能默认关闭,可随时在系统设置或本应用设置页重新开启
🛠 技术要点
- 架构:
SyncEngine同步引擎 +DavClient(HTTP / WebDAV)+EventDb(relationalStore 本地库)+CalendarDataService(多源合并展示) - 镜像:
SystemCalendarMirror(出站写入)+MirrorInbound(入站回写)+MirrorSnapshot(变更快照) - 后台调度:
BackgroundSyncRunner(后台同步唯一执行体)+BackgroundSyncService(延迟任务/短时任务)+NetworkSyncWatcher(网络恢复补同步) - 卡片:FormExtensionAbility + FormBindingData,JSON 数据驱动渲染
- 农历:
LunarUtil,1901–2099 压缩表推算 - 提醒:
ReminderService基于reminderAgentManager代理提醒 - 权限:INTERNET / READ_CALENDAR / READ_WHOLE_CALENDAR / WRITE_CALENDAR(仅镜像)/ PUBLISH_AGENT_REMINDER
- ⚠️ LOCATION 已于 0.1.0 移除:
geoLocationManager.getAddressesFromLocationName(地址→坐标)无 @permission 标注,地理编码不需要定位权限;应用也从不调用getCurrentLocation。 隐私政策/隐私标签里不得再声称读取位置。
- ⚠️ LOCATION 已于 0.1.0 移除:
🔐 权限清单与用途
| 权限 | 类型 | 用途 | 何时申请 |
|---|---|---|---|
ohos.permission.INTERNET |
系统授权 | 访问你填写的 CalDAV 服务器 | 安装即授予 |
ohos.permission.READ_CALENDAR |
user_grant | 读取本应用写入系统日历的日程 | 打开「混合显示」时 |
ohos.permission.READ_WHOLE_CALENDAR |
受限(需 ACL) | 读取系统日历中非本应用创建的日程,实现混合展示 | 同上 |
ohos.permission.WRITE_CALENDAR |
user_grant | 把 CalDAV 日历本镜像到系统日历 | 开启「镜像到系统日历」时 |
ohos.permission.PUBLISH_AGENT_REMINDER |
系统授权 | 发送日程提醒通知 | 保存带提醒的日程时 |
所有 user_grant 权限都只在用户主动操作对应功能时才弹窗,启动 / 首启 / 同意隐私政策时一律不申请。 拒绝后功能默认关闭,可随时在系统设置或本应用设置页重新开启。
🔑 自行编译并上架:权限要怎么处理
如果你 fork 本项目、修改后想上架华为应用市场,仅修改
module.json5是不够的。 下面这些权限需要额外动作,否则审核会被驳回、或安装后权限静默失效。
一、必须自己去申请的(本项目无法代劳)
以下权限绑定在华为开发者账号上,与本仓库代码无关。你必须用自己的账号重新走一遍:
| 权限 | 需要做什么 | 审核周期 | 被拒风险 |
|---|---|---|---|
READ_WHOLE_CALENDAR |
在 AGC → 我的应用 → 权限管理 提交 ACL 申请,说明为什么必须读取非本应用创建的日程 | 数个工作日 ~ 2 周 | 中。用途说明不充分会被驳回 |
PUBLISH_AGENT_REMINDER |
属受限开放权限,需在 AGC 申请 | 数个工作日 | 低 |
本项目已获批的 ACL 只对 bundleName = synccalendar.yangyq.net 生效。
一旦你改了 bundleName(几乎必然要改,否则会与本项目冲突),ACL 立即失效,必须用新包名重新申请。
二、ACL 是怎么落地的
ACL 不写在 module.json5 里,而是由 AGC 在审核通过后签发进 签名 Profile(.p7b)。
想确认手上这份 Profile 有没有带 ACL,可以这样查:
# 解出 profile 明文(p7b 本质是 PKCS#7 包裹的 JSON)
openssl smime -verify -inform DER -in your.release.p7b -noverify -out profile.json
# 查看 allowed-acls
python3 -c "import json;d=json.load(open('profile.json'));print(d.get('acls'))"
正常应输出类似:
{"allowed-acls": ["ohos.permission.READ_WHOLE_CALENDAR"]}
若 acls 为空或缺失,说明该 Profile 未获批 ACL —— 此时即使 module.json5 声明了权限,
装到普通用户手机上也会被系统拒绝,功能静默失效。
三、不想申请 ACL 怎么办
如果你不想走 ACL 流程(例如只是自用、或嫌审核慢),可以把 READ_WHOLE_CALENDAR 从
module.json5 中删掉,代价是:
- 「混合显示系统日历」只能看到本应用自己写入的日历(
READ_CALENDAR足够) - 看不到华为账号自带日历、其他 App 写入的日历
功能仍然可用,只是视图里少了其他来源的日程。这是一种被社区实践过的合规绕行方案。
四、其他与审核相关的注意点
- 应用图标:AGC 要求分层图标的后景图(
background.png)为 100% 不透明、无圆角(规范 7.1.1.4.3)。 本项目AppScope/resources/base/media/background.png已满足;若你要换图,务必重新校验 alpha 通道。 另外app_icon.png目前含透明像素,某些场景(如应用内展示)不受影响,但如要提交商店素材建议先转为不透明。 - Demo / 免账号体验:审核员通常没有你的 CalDAV 账号,无法测试核心功能,这是常见的驳回原因。 建议提供一个「一键载入演示数据」入口,或在上架备注中提供测试账号。
- 隐私政策一致性:隐私政策里声明的权限、数据流向必须与
module.json5完全一致。 本项目已移除 LOCATION,隐私政策中不得再出现"读取位置"之类表述。
目录结构
SyncCalendar/
├─ AppScope/ 应用级配置(包名、版本号)
└─ entry/src/main/
├─ ets/
│ ├─ common/ 核心能力
│ │ ├─ SyncEngine.ets 同步引擎(拉取 → 解析 → 落库 → 推送)
│ │ ├─ DavClient.ets CalDAV / WebDAV 协议客户端
│ │ ├─ EventDb.ets relationalStore 本地库
│ │ ├─ IcsUtil.ets ICS 解析与生成
│ │ ├─ RruleUtil.ets 重复规则展开
│ │ ├─ CalendarDataService.ets 多源合并、系统日历读取
│ │ ├─ SystemCalendarMirror.ets / MirrorInbound.ets / MirrorSnapshot.ets
│ │ ├─ ReminderService.ets 代理提醒
│ │ ├─ CardDataService.ets 卡片数据
│ │ ├─ AppSettings.ets / AccountStore.ets
│ │ └─ LunarUtil.ets / TimelineUtil.ets / DocViewer.ets / TipsPanel.ets …
│ ├─ pages/ Index / Accounts / AddAccount / CalendarList /
│ │ EditAccount / EventEdit / Settings + widget/*
│ ├─ entryability/ 主能力
│ ├─ entrybackupability/ 应用数据备份恢复
│ ├─ entryformability/ 桌面卡片
│ └─ syncwork/ 后台定时同步(WorkScheduler 扩展能力)
└─ resources/ base / dark 两套资源与颜色
📦 构建与运行
一、准备工程
- 安装 DevEco Studio(建议 5.0 及以上,需配套 HarmonyOS NEXT SDK)
- 用 DevEco Studio 打开工程根目录,等待自动同步(
ohpm install)完成 - 连接鸿蒙真机(需 HarmonyOS NEXT)或模拟器
二、首次构建:先补上签名配置(重要)
为什么需要自己配? 鸿蒙应用在编译安装与上架时都必须签名。工程根目录的
build-profile.json5里记录了 签名文件的绝对路径与加密口令,属于机器相关且敏感的凭据,因此该文件被.gitignore排除、不在仓库中。 你从仓库克隆下来的代码默认不含任何签名信息,直接编译会失败。下面是补全方法。
1. 需要准备哪些文件
签名一共涉及 4 个文件,全部放在仓库之外的某个目录里(例如 D:\DevEcoSign\):
| 文件 | 格式 | 说明 |
|---|---|---|
| 密钥库 | .p12 |
存放你的私钥与证书链,最关键、绝不能泄露 |
| 证书 | .cer |
与密钥库配套的应用证书 |
| Profile | .p7b |
授权档案,决定该包能装到哪些设备 / 能否上架 |
| (口令) | — | 密钥库口令、私钥口令(在生成时自己设定,请务必记牢) |
2. 这些文件怎么申请、怎么得到
有两种途径,按你的目的选一种:
途径 A:调试用(自用真机安装)—— 全自动,推荐
DevEco Studio 可以一键生成并自动完成签名配置,无需手工操作:
- 打开
File → Project Structure → Project → Signing Configs - 勾选
Automatically generate signature(自动生成签名) - 按提示登录你的华为开发者账号(需先在 AppGallery Connect 完成实名认证)
- 等待自动完成——DevEco 会替你:生成
.p12密钥库与.cer证书 → 向华为申请调试 Profile(.p7b) 并自动注册当前设备 → 把signingConfigs写入build-profile.json5 - 生成的文件默认落在
C:\Users\<你>\.ohos\config\下
这是最省事的方式,只要一个已实名认证的华为开发者账号即可,不需要额外审批。
途径 B:上架用(发布到应用市场)—— 需在 AGC 后台申请
若要打上架包(.app),必须使用发布证书 + 发布 Profile,需手动申请:
- 登录 AppGallery Connect,进入
用户与访问 → 证书管理,创建并下载:- 发布证书(
.cer)——需先在本机用keytool或 DevEco 生成一个.p12密钥库, 再上传其生成的 CSR 文件申请证书; - 发布 Profile(
.p7b)——在证书、APP ID 和 Profile → Profile中新建, 类型选 发布(Release),关联上面的证书与你的 App ID。
- 发布证书(
- 记住创建密钥库时设定的密钥库口令与私钥口令。
官方文档入口:AppGallery Connect → 帮助中心 → 「配置应用签名」 / 「证书管理」。
3. 在哪个文件里填写
在仓库根目录新建 build-profile.json5(就是被忽略的那份),填入你的签名信息。
可直接复制仓库中的模板 build-profile.example.json5 改名为 build-profile.json5 后使用,格式如下:
{
"app": {
"signingConfigs": [
{
// 调试配置:真机安装用这项
"name": "default",
"type": "HarmonyOS",
"material": {
"storeFile": "D:/DevEcoSign/your.p12", // ← 改成你的密钥库绝对路径
"storePassword": "<你的密钥库口令>", // ← 自动生成时是一段密文
"keyAlias": "your_key_alias", // ← 密钥别名(生成时指定)
"keyPassword": "<你的私钥口令>", // ← 同上
"signAlg": "SHA256withECDSA",
"profile": "D:/DevEcoSign/yourDebug.p7b", // ← 调试 Profile
"certpath": "D:/DevEcoSign/yourDebug.cer" // ← 配套证书
}
},
{
// 上架配置:打 .app 包用这项(真机安装勿用)
"name": "release",
"type": "HarmonyOS",
"material": {
"storeFile": "D:/DevEcoSign/your.p12",
"storePassword": "<你的密钥库口令>",
"keyAlias": "your_key_alias",
"keyPassword": "<你的私钥口令>",
"signAlg": "SHA256withECDSA",
"profile": "D:/DevEcoSign/yourRelease.p7b", // ← 发布 Profile
"certpath": "D:/DevEcoSign/yourRelease.cer" // ← 发布证书
}
}
],
"products": [
{
"name": "default",
"signingConfig": "default", // 用哪套签名:debug 用 "default",上架改 "release"
"targetSdkVersion": "26.0.0",
"compatibleSdkVersion": "6.1.1(24)",
"runtimeOS": "HarmonyOS",
"buildOption": {
"strictMode": { "caseSensitiveCheck": true, "useNormalizedOHMUrl": true }
}
}
],
"buildModeSet": [ { "name": "debug" }, { "name": "release" } ]
},
"modules": [
{ "name": "entry", "srcPath": "./entry",
"targets": [ { "name": "default", "applyToProducts": [ "default" ] } ] }
]
}
关键位置说明:
| 位置 | 作用 |
|---|---|
signingConfigs[].material.* |
四个签名文件的绝对路径与两个口令 |
products[0].signingConfig |
选哪套签名:真机安装填 "default",打上架包填 "release" |
⚠️
build-profile.json5已在.gitignore中,请勿提交。 若用「途径 A」自动生成,DevEco 会自动创建并填好该文件,你通常无需手写。 注意:entry/build-profile.json5是模块级普通构建配置(不含密钥),它在仓库中是需要保留的,两者不要混淆。
4. 一个更省事的替代做法
如果不想手写,也可以直接在 DevEco Studio 里操作:
File → Project Structure → Project → Signing Configs,勾选 Automatically generate signature
并登录华为开发者账号——DevEco 会自动把 build-profile.json5 生成好,随后直接编译即可。
三、编译运行
-
点击 DevEco Studio 的 Run ▶,或执行:
hvigorw assembleHap --mode module -p product=default -
安装后进入「≡ → 账号管理」,添加 CalDAV 服务器地址、用户名和密码
-
选择要同步的日历本,等待首次同步完成
-
长按桌面空白处 → 添加服务卡片,选择 SyncCalendar 的卡片规格
四、打上架包(App Pack)
应用市场上架需要提交 .app(App Pack),而不是 .hap(.hap 仅用于真机侧载):
hvigorw assembleApp --mode project -p product=default -p buildMode=release
-
产物:
build/outputs/default/SyncCalendar-default-signed.app -
前提:请先把
products[0].signingConfig改为"release"(用发布证书 + 发布 Profile), 否则会因签名不匹配而无法通过审核。 -
校验签名(可选,
-inForm zip不可省,否则会误报can not find codesign block):java -jar hap-sign-tool.jar verify-app -inForm zip \ -inFile SyncCalendar-default-signed.app \ -outCertChain out.cer -outProfile out.p7b出现
verify-app success即表示签名有效。
📷 截图
| 月视图 | 周视图 |
|---|---|
![]() |
![]() |
| 列表 / 时间轴 | 日程详情 |
|---|---|
![]() |
![]() |
| 设置 | 账号管理 |
|---|---|
![]() |
![]() |
| 桌面卡片 | 深色模式 |
|---|---|
![]() |
![]() |
🔗 相关链接
网站备案:鲁ICP备17014997号-6A
📄 开源说明
本项目仅供学习交流使用,采用 Apache License 2.0 协议,详见 LICENSE。
该项目使用人工智能辅助完成。







