隔着屏幕,也能原样抵达【鸿蒙心迹】

摘要
这是一篇关于距离与抵达的心迹。我和我妈隔着一千多公里,隔着三个月没见的面,也隔着一块总也看不清的屏幕。微信把照片压成模糊的色块,把视频传成转圈的等待,她那句"你发的不清楚",其实是一次次不好意思说出口的失落。直到用上鸿蒙的远场分享——不在附近也能发,而且原样不压缩——她第一次看清了高原上云的纹路,也第一次主动把院里开花的月季发回给我。这篇文章从这件小事写起,聊远场分享如何把"附近才能传"的默认改成"只要你想,就能原样送到",也聊我那些贪心的想象:分享能不能带上上下文、能不能跨设备自己"出现",以及更重要的——推送要懂得安静,授权要落在长辈那一侧。技术最温柔的部分,从来不是参数多漂亮,而是让某个远方的人,原样收到你的心意。
目录
- 一、一千公里,和三个月
- 二、那些"不清楚"的夜晚
- 三、第一次"原样"抵达
- 四、不在附近,也能送到
- 五、把"原样"落到代码里
- 六、如果分享还能带上上下文
- 七、让分享自己"出现"
- 八、不打扰,是一门功课
- 九、技术最温柔的部分
一、一千公里,和三个月
我妈在老家,我在外地。两个城市之间,隔着一千多公里,隔着一张机票的价格,也隔着一种说不清的、慢慢习惯了的疏离。上一次见她,是三个月前的事。那次我拎着行李走的时候,她在门口站了很久,说了一句"路上慢点",然后转身去关电视。我没回头,可我知道她在看我。
我们这一代人,大概都活在这样的夹缝里:人在远方,心在家里,可心和家之间,总隔着一块发烫的屏幕。我和我妈的联络,多半是微信上几句不咸不淡的"吃了吗"“挺好的”。我知道她想知道的远不止这些,我也知道我想让她看见的,远比文字能装下的多。
小时候,我和在外地打工的表姐通信,靠的是邮票和信纸。一封信要走一个星期,可当它终于躺在手里,每一个字都带着重量,因为你知道,写它的人,是认真想让你看见的。后来有了微信,距离被压缩成一秒,可某种重量,也跟着一起被压缩了。我们发得越来越快,却越来越少"原样"。我常常想,技术的进步,是不是也在悄悄拿走某种郑重——那种"我特意让你看见"的郑重。
二、那些"不清楚"的夜晚
以前想让她看看我拍的东西,只能发微信。可微信是给"能凑合"的人设计的——照片被压成一团模糊,视频传到一半转圈,声音和画面常常对不上。她总说"你发的不清楚",然后就很体贴地不再多问。
我后来才懂,她不是真的在嫌画质。她是那种把"孩子想让我看见"这件事,悄悄换算成了"我没能看清"的遗憾。隔着屏幕,那份失落也一并传了过来。我妈这辈子没用过几样智能设备,她不会调清晰度,不会点"原图",甚至不太确定自己收到的,到底是不是我拍的那个版本。每一次"不清楚",都是一次微小的、她不好意思说出口的挫败。
我记得有一次,我在海边拍了张日落发给她,天边那道金红色的光,是我那阵子见过最好看的。她回得很快:"你这照片咋这么暗,是不是天黑了?"我盯着那行字,半天没说出话——她看到的,是一团被压缩成深灰的、丢失了所有层次的色块。我想告诉她那光有多亮,可隔着屏幕,语言太苍白。
我试过教她。视频通话里,我在这头比划:“你点这个,再点原图。“她在那头点头,说"看见了看见了”。可挂了电话再操作,又回到原点——她记不住那些藏在三级菜单里的开关,就像我记不住她年轻时会做的那些菜的顺序。那种"近在咫尺的远”,比地理上的远更让人无力。
三、第一次"原样"抵达
转机是鸿蒙的远场分享。它最打动我的一句话,是"原样传递"——不在附近也能发,而且不压缩。我一开始将信将疑,毕竟"原样"这两个字,在太多产品里只是宣传语,落到手上往往打了折扣。
直到我第一次把一段旅行视频,原样发给我妈。那是我站在高原上拍的,天很低,云很厚,风把草吹成一片流动的绿。以往发微信,这段视频到她手机上,云成了灰白的一团,风的声音闷得像隔着棉被。而那次,她收到后愣了好一会儿,才慢慢说了一句:“这云彩的纹路,都看得清。”
我握着手机,鼻子有点酸。就这一句,值了我之前所有折腾。所谓"原样",传的不只是像素,是我当时站在那片风景前面,想让她也站一站的心情。她看清了云,也就离我站过的地方,近了一点。后来她把那段视频反复看了好几遍,还转发给了小区的老姐妹,配文是"我儿子拍的"。我没好意思说那云其实是在八百公里外,可我知道,她分享的不是一段画质,是一份骄傲。
过了几天,她又用远场分享,给我发回来一段她院里月季开花的视频。画质依旧算不上好,可那是她第一次主动"也让我看见你"。我们之间那块发烫的屏幕,好像凉下来一点,变成了能原样握住的通道。
四、不在附近,也能送到
鸿蒙总在讲"分布式",讲设备与设备之间那种无感协同。可在我这儿,它更像一种关于"在场"的哲学:距离,不该决定抵达的质量。
我们习惯了"附近才能传"——蓝牙要贴着,Wi-Fi 要同网,分享这件事,默认是给身边人准备的。可生活里最想分享的人,偏偏都不在身边。远场分享把那个默认设置,悄悄改成了"只要你想,就能原样送到"。技术退到后面,人和人之间那点惦记,浮到前面。
我把工作里拍的一段演示视频,也原样发给了异地出差的同事。以往这种事,得先传云盘、再发链接、等对方下载,中间还担心他网速慢、担心文件过期。那次直接从联系人里发起,他点个同意,文件就落在了他的设备上,带着我拍时的所有细节。他回我:"这下清楚了,比邮件靠谱。"我笑了笑——原来"原样"这件事,救的不只是亲情,还有那些被传输门槛磨掉的效率。一个功能能不能打动人,往往就看它是不是悄悄替你,把那点"将就"给抹平了。
我还试过给一个远在另一个城市的朋友发旅行视频。她当时正闷在办公室加班,收到那段原样的海和风,回了我一句"谢谢你让我喘了口气"。那一刻我意识到,远场分享治愈的不只是"看不见",还有"不在场"的那种孤单。
五、把"原样"落到代码里
前面写的都是感受,这一节换个视角,说说如果真要把远场分享接进一个鸿蒙应用,代码层面大概要经过哪几步。我按自己踩过的顺序整理,尽量让每一步都能直接对着文档跑通。
1. 先声明能力与权限
远场分享依赖分布式设备发现与跨设备数据传输,需要在 module.json5 里声明对应权限,并在首次使用时向用户申请:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC",
"reason": "$string:reason_distributed_datasync",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.INTERNET"
}
]
}
}
DISTRIBUTED_DATASYNC 属于用户授权权限,必须在运行时动态申请,不能只写在配置里就当作已授权:
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
const PERMISSIONS: Permissions[] = ['ohos.permission.DISTRIBUTED_DATASYNC'];
async function requestSharePermission(context: common.UIAbilityContext): Promise<boolean> {
const atManager = abilityAccessCtrl.createAtManager();
try {
const result = await atManager.requestPermissionsFromUser(context, PERMISSIONS);
// 0 表示已授权
return result.authResults.every((code: number) => code === 0);
} catch (err) {
const error = err as BusinessError;
console.error(`request permission failed, code: ${error.code}, msg: ${error.message}`);
return false;
}
}
2. 发送端:从联系人发起一次原样传输
发送端的核心是"选设备 → 建会话 → 传文件"。设备发现用分布式设备管理,传输用跨设备数据通道,文件本身走文件描述符,避免把大视频整个读进内存:
import { distributedDeviceManager } from '@kit.DistributedServiceKit';
import { fileIo as fs } from '@kit.CoreFileKit';
// 1) 发现可信设备
function listenTrustedDevices(onFound: (device: distributedDeviceManager.DeviceBasicInfo) => void) {
const dmInstance = distributedDeviceManager.createDeviceManager('com.example.farshare');
dmInstance.on('deviceStateChange', (data: distributedDeviceManager.DeviceStateChangeInfo) => {
if (data.action === distributedDeviceManager.DeviceStateChange.AVAILABLE) {
onFound(data.device);
}
});
return dmInstance;
}
// 2) 以只读方式打开待分享文件,拿到 fd
function openForShare(filePath: string): fs.File {
return fs.openSync(filePath, fs.OpenMode.READ_ONLY);
}
拿到 fd 之后,把它和文件名、大小、MIME 类型一起封装成传输请求发给对端。这里有个容易忽略的点:"不压缩"不是默认行为,而是要在传输参数里显式关掉转码,否则图片仍可能被按屏幕尺寸重采样,视频仍可能被降码率——那"原样"就又成了宣传语。
interface SharePayload {
fileName: string;
fileSize: number;
mimeType: string;
fd: number;
// 关键:显式声明原样传输,禁止服务端转码/重采样
keepOriginal: true;
}
function buildPayload(filePath: string): SharePayload {
const file = openForShare(filePath);
const stat = fs.statSync(filePath);
return {
fileName: filePath.split('/').pop() ?? 'unnamed',
fileSize: stat.size,
mimeType: guessMimeType(filePath),
fd: file.fd,
keepOriginal: true
};
}
3. 接收端:先确认,再落盘
接收端不要一收到就自动写进相册,先弹一次确认,把"是否接收""存到哪个目录"交给用户决定,这既是体验,也是隐私边界:
async function onShareReceived(payload: SharePayload, context: common.UIAbilityContext) {
const granted = await showReceiveDialog(payload.fileName, payload.fileSize);
if (!granted) {
return; // 用户拒绝,直接丢弃,不落盘
}
const targetDir = context.filesDir + '/received';
if (!fs.accessSync(targetDir)) {
fs.mkdirSync(targetDir);
}
const targetPath = `${targetDir}/${payload.fileName}`;
const dest = fs.openSync(targetPath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
// 按块搬运,避免大文件一次性占用内存
await copyByChunk(payload.fd, dest.fd, payload.fileSize);
fs.closeSync(dest);
fs.closeSync({ fd: payload.fd });
}
4. 传输状态要能被感知
跨设备传输耗时不短,进度、失败重试、断点续传都得有反馈,否则用户只会看到"卡住了":
type TransferState = 'pending' | 'transferring' | 'success' | 'failed';
function onTransferProgress(state: TransferState, transferred: number, total: number) {
const percent = total > 0 ? Math.floor((transferred / total) * 100) : 0;
switch (state) {
case 'transferring':
updateProgressBar(percent);
break;
case 'success':
toast('已原样送达');
break;
case 'failed':
// 失败时保留已传分片,下次从断点继续
toast('传输中断,可重试');
break;
default:
break;
}
}
5. 上下文打包:让文件带上"背后的门道"
第五节聊到的"带上上下文",落到代码上就是给 payload 加一个可选的 context 字段,把笔记、坐标、时间戳一起序列化过去。接收端解析后,就能在预览页旁边挂出"这道菜怎么复刻":
interface ShareContext {
note?: string; // 文字笔记,如食材清单
location?: { lat: number; lon: number };
capturedAt?: number; // 拍摄时间戳
deviceModel?: string;
}
function attachContext(payload: SharePayload, ctx: ShareContext): SharePayload {
return { ...payload, context: ctx } as SharePayload & { context: ShareContext };
}
6. 隐私分级:默认最小授权
第七节说的"授权落在长辈那一侧",在代码里就是默认只同步白名单类型,并且把开关做成一次性、可回看的设置项,而不是藏在三级菜单:
const DEFAULT_ALLOWED_TYPES = ['image/jpeg', 'image/png', 'video/mp4'];
function isAllowedToSync(mimeType: string, userAllowed: string[]): boolean {
const allowed = userAllowed.length > 0 ? userAllowed : DEFAULT_ALLOWED_TYPES;
return allowed.includes(mimeType);
}
写到这里我最大的体会是:所谓"原样",在代码里其实是一连串默认值的取舍——默认不压缩、默认先确认、默认最小授权、默认给进度反馈。这些开关单看都不起眼,可它们叠在一起,才让"隔着屏幕也能原样抵达"从一句文案,变成用户真的能感受到的东西。
五、如果分享还能带上上下文
用了几次之后,我冒出一个贪心的念头:要是分享还能顺手带上上下文,该多好。
比如我给我妈发一段做菜的视频,能不能把对应的食材清单、火候和步骤笔记,一起打包过去?她点开视频,旁边就挂着"这道菜怎么复刻",不用再打电话问我"你放了多少盐"。再比如我发一段旅行视频,系统如果能自动带上拍摄地的坐标、时间和设备参数,她收到的就不只是一个文件,还有那段旅程背后的故事——我在哪、为什么停、当时几点。
文件还是那个文件,可附上的上下文,让它有了温度。分享不再是"我丢给你一段画面",而是"我把当时那整段经历,原样交给你"。我妈这种人,最在意的就是"背后的门道":她看我拍的菜,想知道怎么做的;看我拍的景,想知道在哪。上下文,恰恰是把"看见"升级成"懂得"的那把钥匙。
我甚至想象过一个具体的画面:过年回家,我教她做红烧肉,拍下视频,顺手把"五花肉一斤、冰糖八颗、先炒糖色再下肉"的笔记一起发去。她在老家照着做,做得比我还好,又发视频回来显摆。这样一来一回,隔着一千公里,我们竟像是在同一口锅边忙活。技术要是能成全这种"在一起",才算没白进步。
六、让分享自己"出现"
脑洞再放大一点,我更想要的是"跨设备接力"。我在外面用手机拍了段东西,家里那台平板不用我特意操作,就自动原样落了一份;我妈的开机屏或者锁屏,直接弹出一句"孩子刚分享给你一段视频"。她不用主动去翻哪个 App,不用琢磨怎么下载,抬眼就看见了。
在这个想象里,分享的主动权,从"我推给你",变成了"你刚好就在那看到"。技术退到更后面,人和人之间那点惦记,浮到最前面。我妈这种不太会用智能设备的人,恰恰最该被这种"不用学、不用找"的设计照顾到——不是让她适应机器,是让机器迁就她。
我脑子里常浮现一个清晨:她刚起床,平板从休眠里醒来,锁屏上静静躺着昨夜我发来的那段雪。她不用戴老花镜找图标,不用问我"在哪看",只是像翻日历一样,一眼就看见。那种不打扰的、刚刚好的出现,才是科技该有的体贴。我们总说科技要向善,可善的起点,往往只是把那个最不会被照顾到的人,也轻轻托住。
七、不打扰,是一门功课
当然,贪心之外,我也清楚这里面有分寸。开机屏弹窗要是没节制,就会从"贴心"变成"打扰";自动落盘要是没边界,隐私就成了一件悬在头顶的事。
我尤其在意两件事。一是授权要落在长辈那一侧:哪些内容允许自动同步到家里设备、能不能按"仅照片""仅视频"分级,得让他们一次性点清楚,而不是我在远端替他们决定。二是推送要懂得安静:最好能设个安静时段,或者把一天的消息收敛成一条摘要,别让锁屏变成随时蹦出来的广告位。主动推送和不动声色之间,那根线得拿捏好——毕竟,我们想给父母的,是陪伴,不是负担。
有一回,我差点把一张私密的截图也一起同步到了家里的平板,幸好动手前犹豫了一下。从那以后我更确信:能"原样"是本事,知道"什么不该原样"是修养。一项技术能不能被人长久地喜欢,往往不取决于它能做多少,而取决于它懂得克制什么。想清楚这些,我反而更期待了,因为真正成熟的"远场",不是把功能做满,是把分寸做对。
八、技术最温柔的部分
技术的浪漫,从来不是参数有多漂亮、跑分有多高。它最动人的时刻,往往很安静:是某个人,在某个远方,原样收到了你的心意。
前阵子,我妈破天荒地主动发来一段她拍的广场舞,画质算不上好,可那是她学会"也让我看见你"之后,递回来的回应。后来又是一桌刚出锅的菜,配了句"今天多做了你爱吃的"。我们之间的屏幕,好像没那么烫了——它不再是隔着一层、总也看不清的屏障,而成了能够原样抵达的通道。
隔着屏幕,也能原样抵达——这大概就是我眼里,鸿蒙最温柔的部分。它没说什么大话,只是悄悄把"想让你看见"这件事,变得真正可行。而这件事,值得我用很多个普通的深夜,去认真对待,也值得更多像我一样隔着距离的人,去慢慢相信。也许有一天,当"原样"成了分享的默认,我们反而会重新找回小时候那封信里的郑重——因为知道对方一定能看清,所以每一次发送,都格外用心。
更多推荐


所有评论(0)