当前位置: 首页 > news >正文

HarmonyOS WPS Open SDK:关闭回传 URI-FD 与 ResultData 解析实现

在 HarmonyOS 应用中集成 WPS Open SDK 后,OpenFileRequest负责把沙箱内的文档交给 WPS 进程编辑。编辑结束后,最新文件内容往往落在 WPS 自身沙箱,而非调用方传入的原始路径。若业务需要在关窗后继续上传或持久化,必须在请求对象上启用关闭回传(Transfer),并在WPSApi.sendRequest的异步结果里解析Result/ResultData,再把文件同步到本应用沙箱。本文按接口语义说明参数组合、URI 与 FD 两种回传路径的差异,以及filePath落盘的参考实现。

一、关闭回传在调用链中的位置

典型时序如下:应用构造OpenFileRequest并设置wpsTransferTypesendRequest拉起 WPS → 用户编辑并关闭文档 → Promise resolve,此时result.data携带回传信息 → 应用侧拷贝或读 fd → 得到可用于上传的本地路径。

若未配置enableTransferFilewpsTransferTypesendRequest在 WPS 成功拉起后即可返回code === ResultCode.OK,但data为空。这与「回传成功」是两种语义,UI 层应区分「已打开 WPS」与「已收到回传文件」,避免在data为空时提示保存成功。

二、ResultData 字段说明

Result.data类型为ResultData,与文件回传相关字段如下:

字段类型/含义
fileUriURI 模式:WPS 沙箱内临时文件路径
transferFdFD 模式:可读文件描述符
transferFileNameFD 模式:建议使用的文件名
transferFileSizeFD 模式:字节数,用于校验读入是否完整
parameters扩展字典,部分版本 FD 信息嵌套在此

sendRequest与回传相关的返回语义:

场景codedata
未开回传,拉起成功OK
开启回传,用户关闭且成功OK含 fileUri 或 transferFd 等
拉起失败或回传异常非 OK视版本可能为空或带错误信息

三、开启回传的参数配置

OpenFileRequest上两组相关属性:

参数说明
enableTransferFiletrue时按 URI 回传
wpsTransferTypeTransferType.URITransferType.FD优先于enableTransferFile

工程上建议只设置wpsTransferType,避免两个开关语义重叠。enableEdit控制是否可编辑,与回传独立,可编辑场景通常同时开启。

import{common}from'@kit.AbilityKit';import{WPSApi,OpenFileRequest,TransferType,ResultCode,}from'@wps/wps_sdk';asyncfunctionopenWithTransfer(ctx:common.UIAbilityContext,sandboxPath:string,mode:TransferType=TransferType.URI){constrequest=newOpenFileRequest(ctx,sandboxPath);request.enableEdit=true;request.wpsTransferType=mode;constresult=awaitWPSApi.sendRequest(request);if(result.code!==ResultCode.OK){thrownewError(result.msg??`WPS error${result.code}`);}returnresult;}

四、URI 回传:拷贝到本应用沙箱

URI 模式下,result.data.fileUri指向 WPS 维护的临时文件。三方应用应使用@ohos.file.fs以只读方式打开,再copyFileSync到例如context.filesDir/wps_callback/目录,最后用fileuri.getUriFromPath转为业务使用的 URI。

注意:fileUri不能写入业务数据库作为长期路径;拷贝前需mkdirSync;专业版启用不落地时,拷贝完成后可对 WPS 临时文件执行unlink

importfsfrom'@ohos.file.fs';importfileurifrom'@ohos.file.fileuri';functioncopyWpsUriToSandbox(ctx:common.UIAbilityContext,wpsFileUri:string):string{constfile=fs.openSync(wpsFileUri,fs.OpenMode.READ_ONLY);constbaseName=wpsFileUri.split('/').pop()??'edited.docx';constdestDir=`${ctx.filesDir}/wps_callback`;fs.mkdirSync(destDir,true);constbackupPath=`${destDir}/${Date.now()}_${baseName}`;fs.copyFileSync(file.fd,backupPath);fs.closeSync(file);returnfileuri.getUriFromPath(backupPath);}

五、FD 回传:分块读取与关闭描述符

FD 模式从transferFd分块readSync写入本应用沙箱新文件,写完后必须closefd。实现时建议校验累计读取字节数与transferFileSize一致,否则按失败处理,避免上传残缺文件。大文件可将读写在TaskPool中执行,避免阻塞 UI 线程。

统一入口可先判断 FD,再回退 URI,与官方 Demo 中handleCallbackData/handleCallbackDataByFd的分支顺序一致:

functionresolveCallbackFilePath(ctx:common.UIAbilityContext,result:Result):string|undefined{constdata=result.data;if(!data)returnundefined;if(data.transferFd!==undefined&&data.transferFd>=0){returncopyFdToSandbox(ctx,data);// 按文档 Demo 实现}if(data.fileUri){returncopyWpsUriToSandbox(ctx,data.fileUri);}returnundefined;}

六、联调与常见问题

  1. 回调无 data:未设置wpsTransferType,或用户未关闭文档即切回应用。
  2. 上传仍是旧文件:业务仍使用打开前的sandboxPath,未使用回传拷贝后的路径。
  3. 拷贝失败:目标目录未创建、沙箱权限不足、文件被占用。
  4. FD 泄漏:读完后未closeSync(transferFd)
  5. HAR 与凭据不匹配:个人版测试包须使用申请时对应的 SDK 版本。

建议测试矩阵:小 docx / 大 xlsx 各测 URI 与 FD;正常关窗、杀 WPS 进程两种路径;拷贝后用本应用再次打开校验内容 hash。extraOptions、水印等参数与回传无冲突,可配置在同一OpenFileRequest实例上。

错误处理建议

生产代码中应对sendRequest做完整分支:code !== OK时向用户展示result.msg或映射后的错误文案;code === OK && !result.data表示仅打开成功,不应触发上传;data非空但拷贝失败时,与回传失败分开提示,便于定位是 WPS 侧还是应用侧文件系统问题。单元测试可对resolveCallbackFilePath注入 MockResult,覆盖空 data、仅 URI、仅 FD、size 不一致等分支。

与不落地策略的配合

专业版默认不落地时,云文档数据流与本地回传无直接关系,但 URI 模式下 WPS 仍可能产生临时文件。拷贝到本应用沙箱后,若安全策略要求最小化残留,应在确认上传成功后再删除 WPS 临时路径与本应用中间文件。个人版与个人版 HAR 的接口与专业版一致,联调时注意包名、签名与申请凭据对应,避免回调字段缺失被误判为未开回传。

七、小结

关闭回传把 WPS 编辑能力从「单向打开」扩展为「可回写」:wpsTransferType声明传输层形态,sendRequest的 Promise 承载关窗结果,应用侧负责沙箱拷贝与后续业务消费。实现时固定「解析 Result → 拷贝/fd 读入 → 上传或落库」三层,URI/FD 仅影响第二步的具体 API 调用。


基于 WPS Open SDK 鸿蒙版对接实践整理,仅供开发者参考。
官方对接文档:https://365.kdocs.cn/l/clQl5cek2NoT
技术交流 QQ 群:628436767

http://www.cnnetsun.cn/news/3243523.html

相关文章:

  • 液态神经网络 (LNN) 与 LSTM/GRU 对比评测:在 2 个时序任务上的精度与效率分析
  • STM32与A3908实现高精度电机控制方案解析
  • 安卓抓包实战:BurpSuite代理配置与HTTPS解密全指南
  • 树莓派5 砝码识别方案:2024起重机创意赛机器学习模块,识别精度99.5%实测
  • 2026年江门奔驰C260音响改装店怎么选?看完这台车后,我会先去江门汇声汽车音响试听
  • 【JAVA毕设源码分享】基于Springboot的体育赛事视频管理系统(程序+文档+代码讲解+一条龙定制)
  • TTS-Backup终极指南:3步拯救你的Tabletop Simulator珍贵数据
  • 当微信网页版成为禁区:如何在受限环境中实现即时通讯?
  • 锂离子电池组主动均衡方案设计与STM32实现
  • 3个技术突破:虚拟手柄驱动如何彻底解决Windows游戏兼容性问题
  • Codex从零上手全攻略:AI编程助手核心用法与多场景实战
  • 选售后服务好的家电代理商,要考虑哪些适配条件?
  • L9958与PIC18F4525电机控制方案解析
  • VisualCppRedist AIO:三步彻底解决Windows软件兼容性问题的完整指南
  • 如何用MTKClient解锁联发科设备:从新手到专家的完整实战指南
  • STM32F207ZG与L9958电机驱动器的工业级控制方案
  • 【Agent智能体】36DeepAgents深度搜索项目
  • 工程车预约调度平台开发案例:基于小程序、APP与后台管理系统的一体化平台建设
  • NAU8224与MKV44F64VLH16音频系统设计与优化
  • 新一代IM即时通讯系统:高效连接,稳定运营,打造企业级沟通新体验#灰鲸IM#极光鸟IM
  • 微信聊天记录永久保存指南:用WeChatMsg轻松备份与分析你的珍贵对话
  • Claude助力智能测试全流程
  • PUBG罗技鼠标宏压枪脚本:三步实现精准射击的终极指南
  • TDA7468与TM4C129ENCZAD构建高性能音频处理系统
  • 深度揭秘:Play Integrity API Checker - Android设备安全检测终极指南
  • Linux中Vim编辑器
  • 让 Claude Code 学会走命令行这条近路
  • 如何在LeRobot中实现Waveshare ST3215舵机高精度控制实战
  • 基础利益、差异利益、未来利益:B2B理性利益三层模型
  • 基于NAU8224与STM32的高效嵌入式音频系统设计