React Native 鸿蒙权限审计实战:让每一项权限都有人认领

声明与使用怎么对账、最小权限集怎么算才不自相矛盾、审核必查的 reason 和 usedScene 怎么补齐——这篇文章用一个纯 JS 的权限审计工具,把这三个问题一次讲透。

仓库地址:https://atomgit.com/lqjmac/react-native-permission-guard
版本地址:https://atomgit.com/oh-react-native/ohos_react_native/tree/0.84-main
三方库框架:https://atomgit.com/oh-react-native

0. 环境与实测设备

项版本/型号
DevEco Studio26.0.0.851(HarmonyOS SDK 7.0.0 / API 26)
React Native0.84.1
RNOH0.84.3(@react-native-oh/react-native-harmony,示例宿主同版本)
react-native-harmony-permission-guard1.0.0(本仓库)
Node.js20.19.5(审计核心是纯 JS,不依赖 RN 运行时)
测试node:test 14/14:module.json5 解析(引号 key、嵌套 usedScene)、最小集、隐含权限、风险分、Markdown、最小清单
实测环境HUAWEI ALN-AL00,HarmonyOS 7.0.0.109(SP6C00E105R4P3)

1. 权限清单为什么越来越长?——这个问题是怎么找上我的

起因其实很简单。接手一个 RN 鸿蒙应用做发布前自查,我打开 module.json5 看了一眼 requestPermissions——六个权限,INTERNET、定位、相机、麦克风、通讯录、分布式同步,心里想"都是常见项,应该没问题"。直到应用市场审核的打回意见摆到面前:缺 reason、缺 usedScene;再一问业务,麦克风和通讯录根本没有任何功能在用——它们是两年前从别的工程抄模板抄过来的。

想清理,才发现这件事在 RN 里格外难:RN 的权限调用通常发生在原生模块或 HAR 里,纯 JS 侧的代码根本看不出"这个页面到底用了哪些系统能力"。人工对着源码猜,猜不全;只跑静态扫描,扫不到原生层;等应用市场打回再改,一轮审核一周就过去了。还有一个更隐蔽的坑:用了精确定位却没申请 APPROXIMATELY_LOCATION,授权流程不完整——这类"配套权限"的缺失,靠肉眼基本不可能发现。

所以这个题目的边界其实很清楚:把"声明"和"使用"放在一张表里对账,具体拆成三件事:

  • 三路输入怎么合一(module.json5 声明、使用台账、源码证据扫描,这是核心);
  • 最小权限集怎么算才不自相矛盾(隐含权限、系统 Picker 的证据判定);
  • 结果怎么变成可执行的动作(六类 finding、可粘贴的最小清单、退出码卡 CI)。

下面是干完之后的完整记录,包括我踩的每一个坑。

2. 效果展示

按老规矩,先给效果再讲原理。示例应用的报告页分四个 Tab——总览、声明、发现、清单——正好是审计结论的四个层次。报告数据来自 example/fixtures/bad 里一份故意写坏的 module.json5(六条权限声明,问题齐全),宿主 example/harmony 里的 module.json5 则是修正后的可打包版本,两相对照。

第一页是总览,结论一行都不含糊:

在这里插入图片描述

右上角红色"未通过",核心数字是"声明 6 条 → 建议保留 4 条",下面一行给出动作明细:“移除 3 · 补充 1 · 精简 50% · 风险分 26 → 14”,再往下是红字"3 项高危,CI 会失败"和依据——“6 条声明中 3 条有使用证据;最小集合 1 条补充权限”。"待处理"区把三条高危逐条列出:声明了未使用的权限 MICROPHONE、READ_CONTACTS、DISTRIBUTED_DATASYNC(都是 PG-PRM-001)。页面底部是三个明细入口:声明清单 6 条、审计发现 7 条、最小权限清单 4 条。

第二页是声明清单,每条权限都带上了它的"供词":

在这里插入图片描述

六条声明逐条列出,右侧是结论。三条保留的都有证据链:INTERNET(reason 未填,但证据是 api-client、App.tsx#api)、LOCATION($string:location_reason,证据 nearby-store、App.tsx#nearby)、CAMERA(证据 scan-code、App.tsx#scan);三条标红"建议移除"的,理由清一色是"无使用证据"——MICROPHONE、READ_CONTACTS 带着写好的 reason 却没人认领,DISTRIBUTED_DATASYNC 连 reason 都没填。注意 INTERNET 的"未填写 reason"只是它自己的小问题(PG-PRM-003 类),不影响"保留"的结论——用没用和材料齐不齐,是两本账。

第三页是审计发现,七条按级别排序:

在这里插入图片描述

高危三条全是 PG-PRM-001,但每条的解释都带着这个权限的"人设":麦克风——“录音/语音通话才需要,必须逐次说明用途”;通讯录——“能用联系人 Picker 就不要申请全量读取”;分布式同步——“只有多设备协同才需要,普通 App 不应申请”。中危四条是材料问题:PG-PRM-003 缺 reason(“user_grant 权限必须写清楚’为什么需要’,否则应用市场审核与系统弹窗都会出问题”)、PG-PRM-004 缺 usedScene(“决定权限在哪个 Ability/场景生效,缺省会扩大授权范围”)。Tab 上的过滤计数(全部 7 / 高危 3 / 中危 4)和内容严格对得上。

第四页是清单——审计的最终交付物:

在这里插入图片描述

一段可直接粘贴的 requestPermissions:INTERNET、LOCATION、CAMERA、APPROXIMATELY_LOCATION 四条。下面一行说明很关键:“页面只列权限名;reason / usedScene 由 CLI 按授权类型补齐,user_grant 的 $string: 占位需补资源”——工具不越俎代庖替你编理由,但把骨架和占位都备好。"本次变更"区用 diff 风格列出移除三条、补充一条,页脚是版本与复现命令(node lib/cli/permission-audit.js --project example/fixtures/bad)——页面上的每一个数字都能用一条命令复现。

3. 对账到底从哪来:声明、台账、证据

写代码之前得先把原理捋好。

整个审计是"三进一出"的结构——三路输入并成一张对账表,输出一份可执行报告:

module.json5 的 requestPermissions  ──┐  当前声明了什么
permissions.usage.json(使用台账)  ──┤  哪个功能用了哪个权限(owner 维护)
src/**/*.{ts,tsx,js,jsx} 源码扫描  ──┘  API 调用痕迹(自动,按 API 判定)
                  │
    最小集 = 声明 ∩ 使用 → 并上"用了但没声明" → 补隐含权限
                  │
    六类 finding(PG-PRM-001~006) + 风险分(26 → 14)
                  │
    ├─ Markdown / JSON 报告(--fail-on 命中即退出码 2,卡 CI)
    └─ --write-patch:可直接粘贴的 requestPermissions 片段

为什么必须有台账? 这是 RN 场景的特殊性:权限调用通常发生在原生模块或 HAR 里,纯 JS 静态扫描根本看不到。台账(permissions.usage.json)是业务 owner 维护的"人的证词"——哪个功能用了哪个权限、证据在哪个文件。它不是多余的手工劳动,而是机器扫不到的那部分世界唯一的信息来源。

为什么扫描不能信到全信? 判定按 API 而不是按 import:cameraPicker、PhotoViewPicker、contact.selectContacts 这类系统 Picker 不需要权限,因此不计入证据——否则"换成 Picker 就能删掉的权限"会被最小集一直保留,最小化就永远最小不下去。最终的使用集合取台账与扫描的并集:台账防动态调用的漏报,扫描防台账的过期,两边互为兜底。

为什么要有风险分? 22 条权限目录每条标注 high / medium / low(高危 5 分、中危 3 分、低危 1 分),审计前后各算一次——示例里 26 → 14,一半的风险敞口直接来自砍掉那三条没人用的权限。但要清楚它的定位:风险分只是团队内部排序工具,不能替代应用市场审核。

各条路线对照一下:

方式依据RN 鸿蒙工程的盲区
人工 review module.json5记忆JS 侧看不到原生调用,全靠想
纯源码扫描import / API权限调用在原生 HAR 里扫不到;系统 Picker 误报
应用市场审核反馈提审之后打回才改,一轮审核一周起
商业合规平台全量重、贵、要接入,小团队用不起
本库 CLI + 报告页声明 + 台账 + 扫描三方对账最小集 + 风险分 + 退出码,纯 JS 离线秒级

能力边界照 README 的设计取舍说清楚:不自动改 module.json5(默认只出报告与建议,--write-patch 才生成片段——工具悄悄改权限清单这件事本身就是风险);不申请权限(审计与运行时分离,库不碰 abilityAccessCtrl,权限申请仍在应用自己的 ArkTS 代码里);风险分不是合规结论。了解了这个边界,你就知道它管的是"声明的账",不是"运行的权"。

4. 工程怎么搭:一个纯 JS 内核,三副面孔

先看整体结构。审计核心是纯 JS(不依赖 RN 运行时),同一份内核服务三个入口——CLI 给 CI、JS API 给工具链集成、报告页给人:

react-native-permission-guard/
├─ lib/
│  ├─ index.js / index.d.ts       # 审计核心:解析、对账、最小集、风险分、清单
│  └─ cli/permission-audit.js     # CLI:参数、源码扫描、退出码
├─ ohos/                          # ArkTS 权限目录 HAR(权限中文名/风险级/配套关系)
├─ test/                          # node:test 14 项 + fixture
├─ example/                       # RN 示例:App.tsx 四 Tab 报告页
│  ├─ fixtures/bad/               # 故意写坏的 module.json5 + 台账(复现 7 条 finding)
│  └─ harmony/                    # 完整 RNOH 宿主(module.json5 为修正版)
├─ docs/                          # 文章与截图
└─ package.json / CHANGELOG.md / README.OpenHarmony*.md

在这里插入图片描述

这次设计最关键的决定有三个:

审计核心是纯 JS。 不 import 任何 RN 或原生模块——node lib/cli/permission-audit.js 直接跑,node:test 直接测核心函数,任何装了 Node 的 CI 都能离线执行。鸿蒙相关的部分只剩一份 ArkTS 权限目录 HAR(22 条权限的中文名、授权类型、风险级、配套关系),它也只是数据。

不自动改 module.json5。 这是权限工具和普通格式化工具的分界线:权限清单是应用市场的审核材料,工具悄悄增删它等于替开发者做了安全决策。默认只出报告与建议;--write-patch 生成可粘贴片段,改不改、怎么改,决定权在人。

演练样本内置。 example/fixtures/bad 里是一份故意写坏的清单(六条权限,缺失 reason / usedScene、声明了未使用、缺配套权限的毛病全占),一条命令复现全部 7 条 finding——报告页上的每个数字都有来处。

对使用方来说,CLI 是这样的:

node node_modules/react-native-harmony-permission-guard/lib/cli/permission-audit.js \
  --project . \
  --format md \
  --out build/security/permissions.md \
  --fail-on high

JS API 是这样的:

const guard = require('react-native-harmony-permission-guard');

const declared = guard.parseModuleJson5(moduleJsonText);
const used = guard.parseUsageLedger(usageJson);
const report = guard.audit({ declared, used });

console.log(report.stats);      // { declared: 6, minimal: 4, ... }
console.log(report.findings);   // 逐条 finding
console.log(guard.buildMinimalManifest(report, report.declared));

5. 把代码讲透

5.1 最小集先行:一次排序,避免自相矛盾

audit() 里最值得学的是执行顺序——先算最小集,再出 finding。核心注释把理由写得清清楚楚:

// lib/index.js - audit()
// 先算最小集:声明 ∩ 使用,再并上"用了但没声明"的,最后补隐含权限。
// 先算出来,后面的 finding 才能和补丁保持一致,不会出现
// "建议移除 LOCATION"和"建议新增 APPROXIMATELY_LOCATION"同时出现。
const minimal = Array.from(new Set(
  declared
    .filter(function (item) { return usedNames.has(item.name); })
    .map(function (item) { return item.name; })
    .concat(Array.from(usedNames))
));

这个顺序问题我在第一版就踩了:先按声明逐条出 finding,再算补丁,结果 LOCATION 因为"台账没提"被建议移除,而配套规则又要求"补上 APPROXIMATELY_LOCATION"——报告自己打自己的脸。修复就是调整顺序:最小集是唯一事实源,所有 finding、风险分、补丁片段都从它派生。报告的每一部分互相咬合,这是审计工具可信的前提。

5.2 六类 finding:对账的六种破绽

声明与使用对账,破绽恰好六类,每类一个 PG-PRM-* 编号:

编号级别破绽动作
PG-PRM-001high/medium声明了未使用的权限remove
PG-PRM-002high使用了未声明的权限(真机会直接抛 201 权限拒绝)add
PG-PRM-003mediumuser_grant 权限缺 reason(审核打回、弹窗没文案)补材料
PG-PRM-004medium缺 usedScene(决定权限在哪个 Ability/场景生效,缺省扩大授权范围)补材料
PG-PRM-005medium缺少配套权限(如精确定位缺 APPROXIMATELY_LOCATION)add
PG-PRM-006medium未收录权限(目录里不认识,请人工确认)人工

每条的 severity 不是拍脑袋:001 按该权限自身的风险级定(麦克风这种高危权限没人用就是 high,低危权限没人用只是 medium);002 恒为 high,因为它上线即故障。detail 里写的解释也全部来自权限目录——"能用联系人 Picker 就不要申请全量读取"这类建议是目录数据的一部分,不是硬编码在 finding 里的字符串。

5.3 权限目录与隐含权限:先粗后精

权限目录(22 条)是审计的"字典",每条带四个字段——授权类型(system_grant / user_grant)、风险级、中文名、说明,部分条目还有 implies:

'ohos.permission.LOCATION': {
  grant: 'user',
  risk: 'high',
  label: '精确位置',
  note: '必须与 APPROXIMATELY_LOCATION 一起申请,先粗后精。',
  implies: ['ohos.permission.APPROXIMATELY_LOCATION']
},
'ohos.permission.APPROXIMATELY_LOCATION': {
  grant: 'user',
  risk: 'medium',
  label: '模糊位置',
  note: '城市级定位,优先用它替代精确位置。'
},

implies 驱动隐含权限补全:最小集里出现精确位置而模糊位置缺席时,自动补上并记录 impliedBy——这正是示例里"补充 1 条"的来源(申请了 LOCATION 却没申请 APPROXIMATELY_LOCATION,精确授权流程不完整)。找到不认识的权限也不瞎猜,PG-PRM-006 交人工确认——字典覆盖不到的,宁可麻烦人,不可假装懂。

5.4 风险分与可粘贴清单:按授权类型说话

风险分是三值加权:高危 5、中危 3、低危 1,声明集合和最小集合各算一次——riskBefore: 26 → riskAfter: 14,"精简 50%“的数字就是这两个分数的比值。它给团队排优先级用,README 特意声明"不是合规结论”。

最小清单(--write-patch)的生成规则体现的是对授权类型的尊重:

requestPermissions: [
  { name: 'ohos.permission.INTERNET' },
  { name: 'ohos.permission.LOCATION' },
  { name: 'ohos.permission.CAMERA' },
  { name: 'ohos.permission.APPROXIMATELY_LOCATION' },
]

system_grant 权限(如 INTERNET)不需要 reason/usedScene,清单就不写;user_grant 缺 reason 的生成 $string: 占位——占位而不是编文案,理由必须由开发者自己填(页脚说明原话:“user_grant 的 $string: 占位需补资源”);Ability 名用 --ability 配置而不写死 EntryAbility。生成的片段能直接粘进 module.json5,但粘完之后的审核材料,人还得过一遍。

5.5 台账与扫描:并集与证据分级

使用集合的组装是"台账 ∪ 扫描":台账条目形如 { id: 'scan-code', permission: 'ohos.permission.CAMERA', evidence: 'src/features/scan.tsx' },声明页展示的证据链(scan-code、App.tsx#scan)就是 id 加证据文件的组合。源码扫描按 API 判定:cameraPicker、PhotoViewPicker、contact.selectContacts 这类系统 Picker 不产生权限证据——这是 CHANGELOG 里专门修的一条,理由很硬:“否则’换成 Picker 就能删掉的权限’会被最小集一直保留”。两路证据的并集让动态调用(扫描看不到的)靠台账兜底,台账过期(人忘了更新)靠扫描兜底——单一路径都有盲区,交叉才是真相。

6. 我踩过的坑(每一条都有真实修复记录)

这一节可能是全文最值钱的部分。以下坑全部来自 CHANGELOG 修订记录里的真实修复。

坑一:系统 Picker 被当成权限证据。 源码扫描最初按 import 判定,扫到 cameraPicker 就把 CAMERA 标记为"在使用"——但 Picker 类 API 恰恰是不需要权限的那类,结果"换成 Picker 就能删掉的权限"被最小集永远保留,最小化永远做不彻底。修复:扫描按 API 白名单判定,Picker 不计入证据。证据判定错了,后面的账全是错的。

坑二:报告自相矛盾,移除与新增同时出现。 "建议移除 LOCATION"和"建议新增 APPROXIMATELY_LOCATION"在同一份报告里并列——移除是台账没提,新增是配套规则,两条规则各说各话。修复:先算最小集再派生 finding(见 5.1 的顺序调整)。审计报告内部打架,比漏报一条更毁信任。

坑三:module.json5 的解析野路子。 真实工程里的 json5 五花八门:usedScene 写在 name 前面、注释里带 }、key 用单引号、usedScene: {} 空对象——第一版解析器在这些写法上不是崩就是解析出半个清单。修复:解析器逐个补齐,并把 usedScene: {} 明确视为缺失(空结构和没写是一个意思)。解析用户的工程文件,按最野的写法做测试。

坑四:最小清单越俎代庖。 生成的补丁给 system_grant 权限也补上了 reason/usedScene——但系统授权类权限根本不需要这些字段,贴进清单反而是废材料;user_grant 缺 reason 时工具又替人编了一句通用文案。修复:按授权类型区别处理,user_grant 只生成 $string: 占位,文案由开发者自己填,Ability 名用 --ability 配置。工具可以备好骨架,不能替人写"为什么"。

坑五:台账过期,没人认领的权限其实是有人在用的。 台账是人维护的,功能迭代之后没人回头更新——仅凭台账会把"实际在用但没登记"的权限误判成可移除。修复:使用集合取台账与源码扫描的并集,两路证据互为兜底。单一路径都有盲区,交叉才是真相。

坑六:自动改清单的诱惑。 最省事的交付是工具直接把 module.json5 改好——但权限清单是审核材料,工具静默增删等于替开发者做了安全决策,出了问题连责任人都不清楚。修复:默认只出报告与建议,--write-patch 才生成可粘贴片段。权限这个领域,"不动手"比"高效"重要。

坑七:把风险分当合规结论。 演示时有人问"风险分 14 是不是就等于能过审"——不是。风险分只是 22 条目录三值加权的内部排序工具,应用市场审核有自己的checklist。修复:README 设计取舍里专门加了一条声明。工具能做的说够,做不到的说清,别让数字越权。

7. 现在怎么用:从一条命令到 CI 卡点

经过上面的整理,这个工程是"CLI + JS API + 报告页"三合一(npm 包名 react-native-harmony-permission-guard,版本 1.0.0,Apache-2.0)。安装:

npm install react-native-harmony-permission-guard

在 RN 工程根目录跑审计(--fail-on high 命中即退出码 2,流水线直接失败):

node node_modules/react-native-harmony-permission-guard/lib/cli/permission-audit.js \
  --project . \
  --format md \
  --out build/security/permissions.md \
  --fail-on high

参数一览:--project(工程根目录)、--usage(台账路径,默认 <project>/permissions.usage.json)、--format md/json、--out、--write-patch(输出最小 requestPermissions JSON5)、--fail-on none/low/medium/high、--ability(生成清单里的 Ability 名,默认 EntryAbility)。

台账是唯一要人维护的输入,格式三行一个功能:

{
  "features": [
    { "id": "scan-code", "permission": "ohos.permission.CAMERA", "evidence": "src/features/scan.tsx" },
    { "id": "nearby-store", "permission": "ohos.permission.LOCATION", "evidence": "src/features/map.ts" },
    { "id": "api-client", "permission": "ohos.permission.INTERNET", "evidence": "src/api/client.ts" }
  ]
}

想看报告长什么样,跑内置演练样本即可复现本文全部截图:

node lib/cli/permission-audit.js --project example/fixtures/bad --format json \
  --out example/permission-report.json --fail-on none

当前版本在 RN 0.84.1 / RNOH 0.84.3、DevEco Studio 26.0.0.851(HarmonyOS SDK API 26)环境下验证:npm test node:test 14/14 全绿——覆盖 module.json5 解析(引号 key、嵌套 usedScene)、最小集、隐含权限、风险分、Markdown、最小清单;示例应用四 Tab 报告页在真机运行,演练样本审计结论"声明 6 → 最小 4、风险分 26 → 14、7 条 finding(高危 3 / 中危 4)"与 CLI 输出逐项一致。权限最小化没有魔法——让每一项声明都有人认领,让每一项保留都有据可查,这件事靠的是对账,不是记忆。

相关推荐

RN 鸿蒙安全三方库落地:react-native-digital-shield,密钥不出 TEE,AES-GCM/RSA-JWT 跨端身份打通

本文基于 RNOH 0.84 与 HarmonyOS API 26,自研数字盾库 react-native-digital-shield,把 ArkTS 专属的 HUKS、asset 能力经TurboModule 桥接给 JS:提供 AES-256-GCM 加解密与密钥托管、敏感资产存储、RSA-2048 签发校验 RS256 JWT,并以 JWK 公钥和 HS256 共享密钥实现跨端身份互认,密钥明文始终不出 TEE。文中还复盘 TurboModule 双侧注册、GCM 需拆分 16 字节

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 16

Flutter 修复鸿蒙 WebView Cookie 同名键丢失:离线回读与开发助手复核实录

修复了 Flutter 三方库 webview_cookie_manager 鸿蒙端因同名键误判导致的 Cookie 名称丢失问题,确保业务键如 path、domain 等在回读时正确保留。修复后,模拟器与真机测试均实现四组数据完整恢复,值中多等号也保持不变。补丁已提交至 CPF-Flutter 官方仓库,提升插件在鸿蒙平台的可靠性。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 26

Flutter 鸿蒙启动图撤销后编译失败:用 DevEco Code 复核三方库修复

本文针对 Flutter 鸿蒙启动图撤销时导致编译失败的问题,修复了 flutter_native_splash_ohos 库在移除启动图时误删仍被引用资源的缺陷。通过保留1×1透明图片并透传自定义模块路径,确保资源引用完整性,使工程可正常构建。修复已提交至官方仓库,支持幂等操作与多场景验证,提升开发体验。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 40

Flutter 接入鸿蒙 ArkWeb 预初始化:帮助页首开时机与主线程成本实测

为解决Flutter鸿蒙版webview_flutter无法在无视图状态下提前初始化引擎的问题,我在其原生实现中新增可选静态入口initializeWebEngine()。实测表明,在2秒预热窗口下,页面首屏渲染(FCP)耗时从中位数1791ms降至1019ms,显著提升首次打开体验;而在零延迟场景下,总路径耗时略有上升,需权衡预热时机与用户等待成本。该补丁已提交至CPF-Flutter官方仓库,支持社区协作优化。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 36

Flutter 优化鸿蒙 printing_ohos 多页 PDF 光栅化:原生资源释放与缓冲复用

针对鸿蒙端 printing_ohos 插件存在的页码映射错误与高内存占用问题,本文提出并实现三项优化:修正页码索引映射、引入原生资源分层释放机制、复用像素缓冲区。修复后,第三页显示正确,内存增长显著降低——在模拟器上PSS增量中位数下降65.8%,真机测试下降64.4%。完整补丁已提交至官方仓库,支持社区协作与问题反馈。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 33

Cordova 鸿蒙 WebView 安全实战:能改的运行时拦,改不了的构建期审

本文通过 cordova-plugin-harmony-webguard 插件,解决 Cordova/HarmonyOS 应用中导航安全、引擎不可修改配置、JS 门面静默降级三大难题。基于运行时策略闸门(onPageStart + JS 预检)与构建期审计 CLI(扫描 MainPage.ets、config.xml 等),实现协议拦截、白名单校验、高危配置阻断,支持 CI 失败退出,将安全基线可视化、可测化,真正落地“能改的运行时拦,改不了的构建期审”。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 25

Flutter 鸿蒙供应链审计实战:让高危依赖卡在 CI 门口

本文介绍了一个基于纯 Dart CLI 与 Flutter Dashboard 的依赖审计工具,解决鸿蒙工程中三套锁文件(pubspec.lock、oh-package-lock.json5、package-lock.json)统一读取、离线快照与 OSV 在线情报选择、以及高危依赖通过退出码卡在 CI 的问题。工具以锁文件为事实依据,支持离线快照(4 条真实 GHSA)与在线查询,输出 SBOM(CycloneDX 1.5)、Markdown/JSON 报告,并通过退出码实现 CI 阻断,性能秒级

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 138

React Native 鸿蒙端侧 OCR 实战:TurboModule 与纯 TS 引擎的逐字契约

本文以鸿蒙真机上的 React Native 0.84 工程为例,详解三大难题:通过 TurboModule 接入 HarmonyOS Core Vision Kit 实现端侧离线 OCR;规避 Metro 预置头导致的 require 不存在问题;实现 npm 包与 HAR 双形态交付。项目采用 codegen 生成 ArkTS 接口,结合纯 TS 回退引擎,确保跨引擎逐字符一致,并通过 autolinking 支持无缝集成。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 90

Flutter 鸿蒙端侧 OCR 实战:让文字识别留在设备上

本文通过一个运行在鸿蒙真机上的 Flutter 插件工程,系统解决了三大核心问题:如何统一内存、文件、相册三类输入的识别链路;如何实现与 KMP 版本的 JSON 契约逐字节对齐;以及在系统不提供置信度时如何诚实处理。基于 HarmonyOS Core Vision Kit,插件实现端侧离线 OCR,全程无网络、无权限、无密钥,支持真实小票与截图识别,性能稳定(312~507ms),并通过 35 项单元测试与真机集成验证。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 148

跨端 RN 鸿蒙碰一碰分享库实战:基于 Share Kit 封装 react-native-ohos-knock-share,实现卡片、文件一碰传

本文介绍基于React Native的鸿蒙碰一碰分享库,解决RN开发者在鸿蒙生态中无法便捷使用Share Kit碰一碰功能的痛点。通过封装NFC/星闪触碰、3秒发送窗口、沙箱文件URI转换等核心逻辑,实现跨设备快速传递链接、文件、图片等内容。支持手机、平板、PC多端适配,提供回环演示与真机实测验证,显著降低接入门槛,提升跨端协作效率。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 180

React Native 鸿蒙实战:给应用接入小艺语音指令,跑通 Skill 声明到操作闭环

本文介绍如何在 React Native 鸿蒙(RNOH)工程中实现小艺技能闭环,通过开源库 react-native-ohos-ai-agent 封装技能声明、语音指令接收、端侧执行与结果回传全流程。针对三方应用权限限制,精准定位可操作边界,实现“被唤起→执行→反馈”链路贯通。结合五张真机截图验证:技能注册、指令匹配、意图上报、智能体调起及对话层弹出等关键节点均成功,完整打通语音交互闭环,助力应用无需入口即可被用户“叫”到。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 169

Flutter 鸿蒙实现精准碰一碰分享:tap_share_ohos 三方库打通真机传文件与传卡片

本文针对Flutter在鸿蒙系统上“碰一碰”分享功能缺失的痛点,基于DevEco Studio 26.0、HarmonyOS 7.0 API 26与Flutter 3.41.9实测环境,提出并实现开源库tap_share_ohos。该库封装NFC、Share Kit、权限管理及分布式能力,通过Dart门面层统一接口,利用MethodChannel与BasicMessageChannel对接原生ArkTS逻辑,实现文件与卡片的碰一碰分享。真机测试显示,可无缝调起系统分享面板,支持华为分享接力

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 169

Flutter 鸿蒙实战:用三方库接入小艺语音指令与智能体,跑通 Skill 声明到操作闭环

本文基于 flutter_ohos_ai_agent 三方库,实现 Flutter 应用一键调起鸿蒙小艺智能体。针对跨端框架对接鸿蒙 AI 能力的碎片化、环境差异等痛点,通过插件封装系统 Kit 能力,提供统一 Dart API。实测显示,模拟器与真机均支持文本/语音指令闭环,真机可完整调起小艺面板并回传事件。核心原理为:利用 ArkUI 承载页桥接 FunctionComponent,通过 MethodChannel 与 EventChannel 实现 Flutter 与原生能力双向通信,完成从语音识别到

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 151

RNOH 原生内存泄漏定位与治理:借助 LeakyGuard 实现图片解码降采样、LRU 字节缓存、资源生命周期管控,长列表图片页面峰值内存优化

本文面向 RNOH 0.84 长列表图片场景,剖析滑动数分钟后进程被系统杀掉的根因:原图解码尺寸失控、缓存按条数限流、PixelMap未显式 release。基于自研LeakyGuar,TurboModule 库,给出 desiredSize 真降采样、字节预算 LRU 缓存(逐出必 release)、资源登记与快照 diff、卸载即释放 Hook 的闭环方案,实测单图内存降 98.6%,24 图峰值由 1098.6MB 降至15.8MB。并总结双侧注册、ArkTS 语法差异、vp 转像

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 245

Flutter 鸿蒙空间音频实战:让音乐播放器的声音“长出方位感“

本文通过一个真实运行的 Flutter 工程,系统解析了在鸿蒙系统上实现空间音频的三大核心问题:基于双耳时间差(ITD)、声级差(ILD)和频谱整形的方位感算法;耳机切换与音频焦点管理;以及播放器与音效的集成。项目使用自研插件 spatial_audio,结合原生 HarmonyOS 接口,实现了跨设备的空间音频体验,支持普通耳机,无需硬件依赖,并提供实时参数反馈与系统状态监听。附带完整代码仓库与实测效果展示,为 Flutter on HarmonyOS 的音频开发提供了可复用的技术方案。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 289

Flutter 鸿蒙 HiTrace 请求归因:图片压缩等待时,主线程在做什么

为定位鸿蒙平台图片压缩性能瓶颈,我在 flutter_native_image 插件中新增可选的 HiTrace 阶段追踪功能,支持按请求开启解码、缩放、编码与资源释放阶段的耗时分析。通过对比模拟器与真机(华为畅享 100 Pro Max)数据,精准识别出耗时主要集中在解码与编码阶段,显著提升诊断效率。相关代码已提交至官方仓库,助力开发者快速定位性能问题。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 1万+

Flutter 适配鸿蒙折叠屏铰链角度按需订阅:支架调节页用完即停与重入实测

本文介绍对 Flutter 三方库 dual_screen 的优化:针对支架调节页等短时观察场景,保留原有缓存入口的同时,新增按需订阅机制。通过按需启停监听,实现页面退出后停止原生回调,避免无效数据更新。实测显示,无消费者时原生回调从3条降至0条,重进页面则等待新事件,更符合临时工具页的使用逻辑。完整代码已开源,支持鸿蒙折叠屏角度动态感知,适用于需精准控制生命周期的折叠屏应用开发。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 1万+

Flutter 适配鸿蒙手表屏幕形状:让计时卡片按圆屏和方屏布局

本文基于 wear_plus 1.2.4 版本,为鸿蒙系统补全屏幕形状查询功能,使 WatchShape 能正确返回 round 等形状信息。通过在原 Dart 接口不变的前提下,新增鸿蒙平台处理器,实现与 Android 一致的异步查询逻辑。对照实验验证:适配后页面可从“查询未接入”变为“圆屏已确认”,日志成功接收系统回执,布局行为保持一致。完整代码开源至 oh-flutter/wear_plus,支持 Flutter 鸿蒙穿戴设备开发。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 1万+

Flutter 优化鸿蒙剪贴板大图复制卡顿:从主线程同步阻塞到异步文件描述符直解

针对鸿蒙系统下 flutter_image_clipboard 插件复制高清图片时阻塞主线程的问题,本文提出三项优化:异步文件描述符直解、异步剪贴板写入及原生资源逆序释放。实测显示,模拟器事件循环最大间隔从300.32ms降至54.36ms(降幅81.9%),真机上更从133.20ms降至11.20ms(降幅91.59%),显著提升页面响应性。完整代码已开源,支持直接使用与社区交流。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 1万+

Flutter 三方库 petalmaps_ohos 的 OpenHarmony 适配实战(0 → 1 全记录)

本文详细记录了从零构建 Flutter 三方库 petalmaps_ohos 并适配 OpenHarmony/HarmonyOS 平台的全过程,涵盖项目初始化、原生实现(基于 ArkTS 和 MethodCallHandler)、插件注册、功能验证及升级至 HarmonyOS SDK 26 的关键步骤。重点解析了为何需实现 AbilityAware 获取 UIAbilityContext 以确保地图调起成功,并通过分层架构、枚举封装与兼容性设计,实现功能完整、易用且低维护成本的“调起系”地图插件,

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 59

Flutter 三方库 holding 的 OpenHarmony 适配实战:从 0 到 1 开发一个鸿蒙感知插件

本文详述了从零实现开源 Flutter 插件 holding 并适配 OpenHarmony/HarmonyOS 的全过程。基于鸿蒙专属 MultimodalAwarenessKit,实现握持手与操作手状态感知,覆盖事件流订阅、状态查询及 API 26 新增接口,确保功能一致、性能高效、接口稳定。通过 Dart 层封装、ArkTS 原生桥接、真机验证与单元测试,完成插件工程化落地,并发布至 pub.dev,为同类系统能力插件的鸿蒙化提供可复用的技术路径。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 28

Flutter 三方库 gesturesshare 从 0 到 1:鸿蒙隔空传送分享插件的开发、升级与发布实战

本文详述了 Flutter for OpenHarmony 三方库 gesturesshare 从零开发到发布全过程:基于 HarmonyOS 隔空传送能力,实现跨设备图片与 App Linking 一键分享。涵盖双端代码设计、API 26 升级、真机验证及 Pub 发布流程,提供 Dart/ArkTS 对照与踩坑复盘。项目填补 Flutter 生态空白,推动鸿蒙多设备交互能力普及,助力开发者快速接入系统级功能。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 28

Qt 鸿蒙沉浸光感实战:让玻璃的每个像素自己发光

本文通过一个 QML 模块与 Qt for OpenHarmony 构建实践,完整解答了三个核心问题:如何用 81 行 GLSL 实现无图片依赖的动态玻璃材质(含光核漂移、视差、SDF 圆角与颗粒);如何在 Qt Quick 中通过 C++ 控制器实现弹层锚定与翻转;以及如何将 Qt 应用交叉编译并以 HAR 形式部署至鸿蒙系统。项目基于 Qt 5.12.12,利用 ShaderEffect 实现纯渲染级视觉效果,兼顾性能与跨平台兼容性,提供可复用的开源方案。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 23

开源鸿蒙平台 KMP_CMP 三方库「端侧语音转文字」适配全流程

本项目实现KMP/CMP在OpenHarmony鸿蒙平台的语音转文字(TTS)完整链路适配,通过Kotlin/Native共享模型、C ABI/N-API桥接与ArkTS交互,解决权限、音频格式、生命周期及跨平台契约等难题。支持中文、英文、日文多语言识别,提供统一结果模型与JSON序列化,实测于华为Mate 80 Pro Max模拟器,验证了JVM测试、Native动态库、HAP签名部署及真机识别全流程。项目结构清晰,分六阶段推进,确保代码复用与平台无关性,为KMP在鸿蒙生态落地提供可复用的技术范式。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 30

开源鸿蒙平台 KMP_CMP 三方库「端侧OCR」新特性适配

本项目实现Kotlin Multiplatform(KMP)在OpenHarmony平台的端侧OCR适配,基于HarmonyOS 7.0 SDK与Compose Multiplatform 1.9.2,成功打通JVM、Kotlin/Native与ArkTS间的数据交互。通过C ABI/N-API桥接层,实现KMP模型与Core Vision Kit识别结果的跨语言共享,支持中、英、日、韩四语识别。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 13

开源鸿蒙平台 KMP/CMP 三方库「智感握姿」新特性

本项目实现鸿蒙KMP/CMP平台下智感握姿能力的跨端适配,基于Kotlin Multiplatform构建共享状态模型,通过C ABI与ArkTS桥接,支持左手、右手、双手等五种握持状态的稳定传递。项目打通ohosArm64目标、Native动态库构建与DevEco Studio集成链路,提供统一API与真机验证示例,确保状态模型、事件序列与生命周期在多端一致。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 19

Electron 鸿蒙沉浸光感实战:把玻璃交给操作系统去发光

本文通过一个 Electron 库与 HarmonyOS 三方库,系统解决三大核心问题:跨平台材质路径对齐(macOS vibrancy、Windows acrylic、鸿蒙 backgroundBlurStyle)、菜单子窗口精准定位(坐标转换与工作区适配)、以及无脚本菜单文档的安全事件回传(自定义 URL scheme 与焦点管理)。基于 CPF-Electron 鸿蒙化分支,实现桌面级玻璃效果——材质由操作系统合成器采样,网页仅渲染薄色层与光斑,确保视觉一致性与性能优化。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 21

Flutter 修复 flutter_secure_storage 鸿蒙入口路由与前缀隔离:让多账号登录凭证在手机上独立读写与清理

本文针对 flutter_secure_storage 在鸿蒙平台的适配问题,修复了主包缺失 TargetPlatform.ohos 路由导致的 unsupported_platform 错误,并统一鸿蒙子包多账号前缀的读写与清理范围,解决键值覆盖、前缀错用及批量操作匹配过宽等问题。修复后,业务层可继续使用统一接口实现跨账号安全存储,保障数据隔离性。完整代码已开源至 abaoge/flutter_secure_storage。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 1万+

Cordova 鸿蒙沉浸光感实战:让弹层玻璃“喝到“背景的光

本文通过一个 HarmonyOS 模拟器上的 Cordova 项目,详解了在 WebView 中实现“玻璃拟态”效果的三大核心问题:利用 backdrop-filter 实现背景实时模糊与提亮,构建四层结构(采样、渐变底、光场、噪点)模拟真实玻璃质感;通过锚点定位与动态布局实现弹层贴边生长;并集成焦点管理、系统返回键及 inert 属性,确保交互礼仪完整。插件为纯 JS 无原生依赖,基于 ArkWeb 内核,兼顾性能与真实背景采样,适用于菜单、浮层等场景。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 28

CMP 鸿蒙透明玻璃实战:让悬浮导航栏真正透出光场

本文通过一个KMP/CMP工程,详解如何在鸿蒙上用Kotlin实现沉浸光感玻璃材质的逐像素渲染。核心解决三大问题:透明感源于环境光场与带alpha的柔光混合、玻璃“透光”依赖alpha保留的屏幕混合算法、跨平台一致性通过软件光栅器与原生桥接实现。项目以纯代码生成全屏光场与悬浮玻璃组件,无图片资源,支持动态切换调色板,实测模拟器下亚秒级重绘,完整复现官方“沉浸光感”视觉效果。仓库地址:https://atomgit.com/lqjmac/spatial-glass-cmp。

白天写代码,晚上追AI大模型,偶尔搞点八卦 开源动态|技术干货|实习机会|生态活动 我负责分享,你负责变强 28
上一篇: Cordova 鸿蒙 WebView 安全实战:能改的运行时拦,改不了的构建期审
下一篇: Flutter 优化鸿蒙 printing_ohos 多页 PDF 光栅化:原生资源释放与缓冲复用
AtomGit 代码君
AtomGit 代码君 企业官方账号 企业官方账号
博客等级 码龄6年 2万+粉丝 856原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值