在 HarmonyOS 工程里接入 @wps/wps_sdk 时,验收标准往往不是「能编译」,而是「冷启动注册成功、沙箱内路径能拉起 WPS、日志能区分未注册与打开失败」。本文按官方对接文档的接入全流程,把 HAR 落盘、依赖声明、RegisterAppRequest 注册、OpenFileRequest 打开与 Result 归因写成一条可复制的最小路径,便于首轮联调与 Code Review。
一、工程侧:HAR 与 ohpm 依赖
SDK 以 HAR 形式交付,包名 @wps/wps_sdk。典型做法是将厂商提供的 wps_sdk.har 放入工程 libs/,在 oh-package.json5 中声明 file 依赖,再执行 ohpm install 拉齐依赖图。集成完成后,业务模块即可 import { WPSApi, RegisterAppRequest, OpenFileRequest, ResultCode } from '@wps/wps_sdk'。
| 步骤 | 操作 | 验收 |
|---|---|---|
| 落盘 | libs/wps_sdk.har |
文件与申请版本一致 |
| 声明 | oh-package.json5 → dependencies |
ohpm install 无报错 |
| 编译 | 引用 @wps/wps_sdk |
HAP 能链接 HAR |
凭据(appKey / appSecret)与 HAR 需与申请时绑定的 bundleName 一致;换包名或换交付包后须重新申请,否则注册阶段常出现鉴权失败类错误码。多 flavor 交付时,不要把调试包的 key 打进 release 变体:在构建脚本中按 product 注入常量,并在 CI 中增加「包名---凭据」对照表检查,避免测试环境正常、上架包 1013 的割裂现象。模块侧只需保证 entry 依赖了含 HAR 的 feature,不必在 UI 层散落 import 路径。若团队使用远程 HAR 仓库,仍建议在版本说明中锁定文件名与申请邮件编号,方便审计与回滚。
二、注册链:RegisterAppRequest 与 wpsReady 门闩
对接文档要求:在 registerApp / RegisterAppRequest 成功之前,其它 WPSApi.sendRequest 可能 reject 或不可用。工程上应把注册收敛为单次 ensureRegistered,用布尔门闩避免重复注册与并发双调。
typescript
import { common } from '@kit.AbilityKit';
import {
WPSApi,
RegisterAppRequest,
OpenFileRequest,
ResultCode,
} from '@wps/wps_sdk';
let wpsReady = false;
export async function ensureRegistered(
ctx: common.UIAbilityContext
): Promise<void> {
if (wpsReady) return;
const r = await WPSApi.sendRequest(
new RegisterAppRequest(ctx, APP_KEY, APP_SECRET)
);
if (r.code === ResultCode.ERROR_CODE_AUTH_FAILURE) {
throw new Error(`auth failed: ${r.msg ?? ''}`);
}
if (r.code !== ResultCode.OK) {
throw new Error(`register ${r.code} ${r.msg ?? ''}`);
}
wpsReady = true;
}
建议在 UIAbility 冷启动路径 await ensureRegistered 一次;所有「打开文档」按钮在 wpsReady 为真前禁用。Release 构建禁止打印完整 secret;日志仅保留 code / msg 与 bundleName 核对结果。
若签发凭据要求在注册成功后注入激活序列号,应在 ResultCode.OK 分支调用 WPSApi.setWpsFileToken,且优先全局设置,避免在每次 OpenFileRequest 上重复赋值导致行为漂移。
三、打开链:沙箱路径与 enableEdit 默认值
OpenFileRequest 构造需要 UIAbilityContext 与可读 filePath。从系统文档选择器拿到的 URI 往往不在应用沙箱内,直接传入容易在 sendRequest 回调中得到 ResultCode.ERROR。推荐先 copyFileSync 到 filesDir,再传沙箱绝对路径。
typescript
export async function openDocReadOnly(
ctx: common.UIAbilityContext,
sandboxPath: string
): Promise<void> {
await ensureRegistered(ctx);
const req = new OpenFileRequest(ctx, sandboxPath);
req.enableEdit = false;
const r = await WPSApi.sendRequest(req);
if (r.code !== ResultCode.OK) {
throw new Error(`open ${r.code} ${r.msg ?? ''}`);
}
}
enableEdit 未赋值或为 false 时语义为只读,这是能力默认值而非缺陷。预览入口与编辑入口应共用同一函数,仅布尔参数不同,避免仓库内出现多份 new OpenFileRequest 拷贝。
四、Promise 与异常:未注册 vs 打开失败
sendRequest 返回 Promise<Result>。未注册成功时可能进入 .catch,这与 result.code !== OK 的打开失败是两类问题,日志与监控应分维度统计。
| 现象 | 优先检查 |
|---|---|
| Promise reject | 是否已 ensureRegistered;是否并发在注册完成前点击 |
ERROR_CODE_AUTH_FAILURE |
appKey/secret、HAR 与包名是否与申请一致 |
ResultCode.ERROR 打开 |
沙箱路径是否存在、是否可读 |
OK 且无 data |
未开启关窗回传时为正常,勿误判上传失败 |
联调清单建议打印固定前缀日志,例如 stage=register|open 与 code,便于 grep 导出。
五、选择器路径拷贝示例
下列片段演示「选择器 URI → 沙箱文件 → 打开」的最小路径,便于与仅传 URI 的失败案例对照。实际项目请按业务封装为 copyIntoSandbox 工具函数,并处理大文件异步拷贝与进度提示。
typescript
import { fileIo } from '@kit.CoreFileKit';
function copyIntoSandbox(srcUri: string, destPath: string): void {
const src = fileIo.openSync(srcUri, fileIo.OpenMode.READ_ONLY);
const dest = fileIo.openSync(destPath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY);
fileIo.copyFileSync(src.fd, dest.fd);
fileIo.closeSync(src);
fileIo.closeSync(dest);
}
拷贝完成后再调用 openDocReadOnly(ctx, destPath)。若跳过拷贝,日志里往往只有笼统的 ERROR,排查会浪费大量时间。
六、UIAbility 与生命周期配合
文档打开通常发生在用户点击之后,此时 UIAbilityContext 必须仍有效。若从后台恢复后 context 变化,应使用当前 Ability 的 context 构造 OpenFileRequest,不要缓存已销毁的 context。
冷启动注册与「首屏可点」之间建议加短 loading:注册失败时展示 msg,避免用户连点触发多次 sendRequest。Ability 被系统回收后再次进入,应确认 wpsReady 是否仍需重置:若进程被杀,静态变量会丢失,需要重新 ensureRegistered,不要把「上次注册过」当成跨进程持久状态。
七、小结与首轮联调顺序
建议按序推进:HAR 编译通过 → 仅 ensureRegistered 断言 OK → 沙箱内只读打开 → 再开 enableEdit → 最后叠策略字段。每步保留日志样例,回归时对比 code 是否突变。正式签名包与调试包若包名不同,须使用各自邮件签发的凭据,混用会在上架阶段集中暴露为鉴权失败。
HarmonyOS WPS Open SDK 的快速入门本质是「HAR 正确集成 + 注册门闩 + 沙箱路径 + 分清 reject 与 Result」。把 ensureRegistered 与 openDoc 收进基础库,页面只调 Facade,比在每个 Activity 抄 Demo 更易维护。字段语义与错误码表以官方对接文档为准,实现侧保持单点 sendRequest 出口,联调成本会明显下降。
基于 WPS Open SDK 鸿蒙版对接实践整理,仅供开发者参考。