跨应用拖拽:如何安全地传递图片 URI 与数据

前言

“跨应用拖一张图片,对面到底该拿 URI 还是直接拿图片数据?”——答案是 URI(文件描述符),不是裸二进制。鸿蒙的拖拽/分享走 UDM(Unified Data Manager),用 UDMF 统一数据封装,对端按类型取 URI 再去读文件。直接塞二进制既大又慢还容易截断。本文给出标准落地姿势。

问题描述

  • 拖拽/分享图片时,对端拿不到内容或拿到空数据;
  • 直接把图片二进制塞进拖拽数据,传输失败或被截断;
  • 跨应用拿到 URI 却无权访问。

细节解析

鸿蒙统一数据框架(UDMF)的设计目标是"跨应用、跨设备安全地传递结构化数据",图片走 uniformTypeDescriptor.Image 类型,传递的是 URI 而非像素:

  • 拖出方:构造 UDMF.UnifiedRecord,把文件 uri 写进去;
  • 接收方:从 unifiedDataChannel.getData() 取出 record,按类型匹配到 Image,读 .uri,再用 fs / open 自己读文件;
  • 权限:跨应用的 URI 必须是对端有权访问的(沙箱内用 fileUri,对方通过 Want 拿到权限;跨设备用分布式文件);
  • 类型:用 uniformTypeDescriptor.Image(或更细的 general.image.png),匹配错了对端收不到。

示例代码

拖出方

import { uniformTypeDescriptor } from '@kit.ArkData';
import { unifiedDataChannel, UDMF } from '@kit.ArkData';

// fileUri 是对端可访问的沙箱文件 uri
const record = new UDMF.UnifiedRecord(uniformTypeDescriptor.Image, {
  uri: fileUri,                   // 传的是 uri,不是二进制
});
const data = new UDMF.UnifiedData({ records: [record] });
unifiedDataChannel.setData(data);

接收方

import { uniformTypeDescriptor } from '@kit.ArkData';
import { unifiedDataChannel, UDMF } from '@kit.ArkData';

const data = unifiedDataChannel.getData();
const imgRecord = data.records.find((r) => r.type === uniformTypeDescriptor.Image) as UDMF.Image;
if (imgRecord) {
  const uri = imgRecord.uri;      // 拿到 uri,自己用 fs 读,别抠二进制
  // 用 @ohos.file.fs 打开 uri 读取,必要时通过 Want 申请权限
}

总结

  • 跨应用拖拽/分享图片,传 URI 不传二进制:性能好、不截断、类型清晰;
  • 用 UDMF UnifiedRecord + uniformTypeDescriptor.Image 封装,对端按类型取 .uri
  • URI 必须是对端有权限访问的(沙箱 fileUri + Want 授权,跨设备用分布式文件);
  • 验证:拖给"图库/文件管理"能正确预览,即 URI 通路 OK。
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐