在鸿蒙应用里接入 WPS Open SDK,开发者最先遇到的通常不是某个复杂接口,而是一连串看起来相似、实际原因完全不同的问题:HAR 放进工程后为什么仍然注册失败,registerApp 已经调用为什么打开时还会抛异常,文件明明存在为什么 sendRequest 返回错误,以及文档关闭后 Result.data 为空是不是回传坏了。把这些问题都归到“SDK 打不开文档”,会让联调停留在反复试参数。
更有效的方式是先按调用链分类:交付物是否匹配、应用是否注册成功、文件是否位于本应用沙箱、请求是否开启了预期能力、结果是否依赖关闭回传。下面就按这条顺序整理常见疑问与处理方式,示例基于 @wps/wps_sdk 当前公开接口。
一、先判断问题落在哪一段
一条最小的文档打开链路可以拆成五段:
HAR 与凭据 → registerApp → 文件准备 → sendRequest → Result / 关闭回传
每一段都有独立的失败表现。HAR 或凭据不匹配,常见结果是注册返回 1013;注册尚未成功就调用 sendRequest,通常进入 Promise 的异常分支;文件路径不在应用可访问范围内,返回的是打开错误;未设置 enableEdit 时文档只能预览;没有开启关闭回传时,打开成功但 Result.data 为空属于预期行为。
因此排查时不要先问“哪个参数能让它打开”,而要先确认当前失败属于哪一段。日志里至少保留注册 code/msg、打开 code/msg、文件路径来源和是否开启回传,后续定位会快很多。
二、HAR、appKey 与包名为什么要成组核对
WPS Open SDK 鸿蒙版以 HAR 交付,appKey 和 appSecret 用于应用资格校验,并与申请时填写的 Bundle 包名绑定。三者不是可以随意替换的独立配置:更换包名、混用旧 HAR、把调试环境的密钥带进正式包,都可能让本来可用的调用变成认证失败。
接入前建议核对:
- 当前安装包的 Bundle 名称是否与申请凭据时一致。
oh-package.json5中引用的 HAR 是否来自同一交付批次。- Release 构建是否误用了 Debug 配置,或者密钥中混入了空格。
- 替换 HAR 后是否 clean 并重新执行
ohpm install。
调试包和正式包使用不同包名时,应把两套信息分别归档。不要通过修改 WPS 包名、设备环境或反复重装来“验证”凭据,这些操作不会改变应用自身的身份校验结果。
三、registerApp 能不能在按钮点击时调用
技术上可以,但不推荐。registerApp 是应用级初始化,回调成功前不具备发送文档请求的条件。如果写在“打开文档”按钮里,快速连点或多个页面同时进入都可能触发重复注册,业务保存的就绪状态也容易出现竞态。
更稳的方式是在应用启动阶段建立共享初始化 Promise:
import { WPSApi, Result, ResultCode } from '@wps/wps_sdk';
let ready = false;
let booting: Promise<void> | null = null;
export function prepareWps(
appKey: string,
appSecret: string,
activationSn?: string
): Promise<void> {
if (ready) return Promise.resolve();
if (booting) return booting;
booting = new Promise<void>((resolve, reject) => {
WPSApi.registerApp(appKey, appSecret, {
onCallback: (result: Result) => {
if (result.code !== ResultCode.OK) {
booting = null;
reject(new Error(`register ${result.code}: ${result.msg ?? ''}`));
return;
}
if (activationSn) {
WPSApi.setWpsFileToken(activationSn);
}
ready = true;
resolve();
},
});
});
return booting;
}
这段封装同时解决两个问题:并发调用只触发一次注册;初始化失败后 booting 会被清空,用户下一次操作仍可重试。需要激活序列号的交付包,在成功回调里设置一次即可,不建议在每个 OpenFileRequest 上重复写入 wpsToken。
四、为什么文件路径要先进入应用沙箱
SDK 打开的是业务交给它的本地文件,而不是任意位置的外部 URI。外部选择器返回的临时权限可能在页面切换或应用重启后失效,直接传给 OpenFileRequest 就会出现“文件明明存在但打开失败”。
推荐流程是先把文件复制到应用自己的 filesDir 或其他安全沙箱目录,确认路径可读,再构造请求:
import { common } from '@kit.AbilityKit';
import { OpenFileRequest, Result, ResultCode, WPSApi } from '@wps/wps_sdk';
import { prepareWps } from './WpsBootstrap';
export async function openEditable(
context: common.UIAbilityContext,
sandboxPath: string,
appKey: string,
appSecret: string
): Promise<Result> {
await prepareWps(appKey, appSecret);
const request = new OpenFileRequest(context, sandboxPath);
request.enableEdit = true;
try {
const result = await WPSApi.sendRequest(request);
if (result.code !== ResultCode.OK) {
console.error('[WPS] open failed', result.code, result.msg);
}
return result;
} catch (error) {
console.error('[WPS] sendRequest rejected', error);
throw error;
}
}
如果这里进入 catch,先检查注册是否完成;如果拿到了 Result 但 code 非零,才继续检查路径、权限和请求参数。两种失败分开记录,能显著减少无效排查。
五、只读、可编辑与空 data 分别代表什么
OpenFileRequest 默认按只读处理,不设置或把 enableEdit 设为 false 都不会进入编辑模式。需要编辑时必须显式设置为 true。这属于参数语义,不是权限故障。
另一个高频疑问是打开成功后 Result.data 为空。没有开启关闭回传时,成功拉起 WPS 就会返回 ResultCode.OK,此时没有编辑结果可回传,data 为空是正常现象。只有开启回传后,用户关闭文档并成功回传,才应期待 data 中出现 URI 或文件描述符信息。
如果业务把“打开成功”和“拿到编辑结果”混成一个验收条件,就会把正常空返回误判为失败。建议拆成四个验收档位:注册成功、只读打开、可编辑打开、关闭回传成功。
六、1013 与未注册异常怎么区分
1013 对应 ResultCode.ERROR_CODE_AUTH_FAILURE,表示接入凭据校验失败。出现时应暂停水印、修订和回传参数实验,先对齐运行时 Bundle、申请包名、HAR 批次和凭据有效期。仅返回 ResultCode.ERROR 时,则先检查 appKey 或 appSecret 是否为空。
未注册异常通常发生在 Promise 层,表现是 sendRequest 直接 reject。它说明调用时序不对,而不是文件打不开。把这两种情况都写成“文档打开失败”,会让日志失去区分度。
七、上线前的问答式检查表
- HAR 和凭据是否来自同一交付批次?
- 运行时 Bundle 是否与申请记录完全一致?
- 冷启动日志是否出现一次
ResultCode.OK? - 需要序列号的交付包是否在成功回调中完成设置?
- 测试文件是否已复制到应用沙箱?
- 只读和可编辑是否分别验收?
- 开启回传后,是否真的等到用户关闭文档再读取结果?
- 更换 HAR 或包名后,是否从注册环节重新回归?
鸿蒙 WPS 二开的大多数“奇怪问题”,都能通过这条调用链找到位置。先把注册、文件、请求和回传拆开,再讨论具体参数,联调会比反复猜测更稳定。
基于 WPS Open SDK 鸿蒙版对接实践整理,仅供开发者参考。
官方对接文档:https://365.kdocs.cn/l/clQl5cek2NoT
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/less_12138/article/details/170447689




