
回复
兄弟们,在App开发里,文件分享就像朋友间传文件——得方便又安全。HarmonyOS Next给咱们提供了两套方案:URI分享和FD分享,各有各的玩法。今天就聊聊怎么用这些功能,让用户传文件既顺畅又安全。
这种方式就像给文件弄个临时快递单号(URI),分享时不用直接传文件,对方拿单号就能取。好处是方便实现,而且分享后权限自动回收——对方App退出后,URI就失效了。但缺点是只能传单个文件,不能传文件夹。
FD相当于直接把文件的访问"钥匙"(文件描述符)给对方,支持传单个文件甚至文件夹。但这把"钥匙"有有效期——关闭FD后,对方就没法再访问了,用起来稍微复杂点。
分享方式 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
URI分享 | 简单易用,自动回收权限 | 只能传单个文件 | 分享文本、图片等单个文件 |
FD分享 | 支持文件夹,性能更好 | 需要手动管理FD,关闭后失效 | 传大文件或文件夹 |
要分享文件,先在module.json5
里声明权限,就像跟系统报备:
"abilities": [
{
"name": "EntryAbility",
"skills": [
{
"actions": [
"ohos.arkui.intent.action.SEND_DATA"
],
"uris": [
{
"scheme": "file",
"host": "*",
"path": "/storage/*"
}
]
}
]
}
]
有些场景得跟用户要授权,比如访问相册:
import permission from '@ohos.permission';
async function requestFilePermission() {
const result = await permission.requestPermissionsFromUser(
this.context,
['ohos.permission.READ_USER_STORAGE']
);
if (result[0].granted) {
// 有权限了,可以分享文件
} else {
// 没权限,提示用户去设置里开启
}
}
import { fileUri } from '@ohos.file.uri';
import { wantConstant, UIAbility } from '@ohos.app.ability';
export default class ShareAbility extends UIAbility {
onWindowStageCreate() {
// 1. 确定文件路径(比如沙箱里的test.txt)
const filePath = this.context.filesDir + '/test.txt';
// 2. 把路径转成URI(相当于给文件办个临时通行证)
const uri = fileUri.getUriFromPath(filePath);
// 3. 构造分享意图,带上读写权限
const want = {
flags: wantConstant.Flags.FLAG_AUTH_WRITE_URI_PERMISSION |
wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION,
action: 'ohos.arkui.intent.action.SEND_DATA',
uri: uri,
type: 'text/plain' // 文件类型
};
// 4. 发起分享
this.context.startAbility(want)
.then(() => console.log('分享成功'))
.catch(err => console.error('分享失败:', err));
}
}
import { fileio as fs } from '@ohos.file.fs';
export default class ReceiveAbility extends UIAbility {
onNewWant(want) {
// 1. 拿到分享过来的URI
const uri = want.uri;
try {
// 2. 打开文件(FD就是文件的操作句柄)
const fd = fs.openSync(uri, fs.OpenMode.READ_WRITE);
// 3. 读取文件内容(比如读文本文件)
const buffer = new ArrayBuffer(1024);
fs.readSync(fd, buffer);
const content = new TextDecoder().decode(buffer);
// 4. 处理内容...
// 5. 用完关闭FD,释放资源
fs.closeSync(fd);
} catch (err) {
console.error('处理分享文件出错:', err);
}
}
}
别一股脑要所有权限,按需申请:
FLAG_AUTH_READ_URI_PERMISSION
FLAG_AUTH_WRITE_URI_PERMISSION
传银行卡照片、合同之类的敏感文件,得加密:
import crypto from '@ohos.security.crypto';
async function encryptFile(filePath) {
// 1. 生成AES密钥
const key = await crypto.generateKey(
{ algorithm: 'AES', length: 256 },
true,
['encrypt', 'decrypt']
);
// 2. 读取文件
const fd = fs.openSync(filePath, fs.OpenMode.READ);
const buffer = new ArrayBuffer(fs.getSizeSync(fd));
fs.readSync(fd, buffer);
fs.closeSync(fd);
// 3. 加密
const cipher = await crypto.createCipher(
{ algorithm: 'AES/CBC/PKCS7Padding' },
key
);
const encrypted = await cipher.encrypt(new Uint8Array(buffer));
// 4. 保存加密文件
const encryptedPath = filePath + '.enc';
const encryptFd = fs.openSync(encryptedPath, fs.OpenMode.CREATE | fs.OpenMode.WRITE);
fs.writeSync(encryptFd, encrypted);
fs.closeSync(encryptFd);
return encryptedPath;
}
记好分享日志,出问题能追查:
// 分享成功后记录
log.info('文件分享记录', {
userId: '12345',
fileName: 'contract.pdf',
shareTime: new Date().toISOString(),
targetApp: 'com.example.wechat'
});
const want = {
// 其他配置...
bundleName: 'com.example.targetapp' // 限定只能传给这个App
};
HarmonyOS Next的文件分享有两套方案:
开发时记住:
把这些点做好,用户传文件就跟喝水一样自然,还不用担心安全问题。下次做文件分享功能,记得按这个路子来,少踩坑!