HarmonyOS 鸿蒙Next中沙箱文件如何存媒体库?
HarmonyOS 鸿蒙Next中沙箱文件如何存媒体库? 沙箱文件如何存媒体库?
效果展示

实现思路

完整代码
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { fileIo } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import { promptAction } from '@kit.ArkUI';
import { BusinessError, request } from '@kit.BasicServicesKit';
import { image } from '@kit.ImageKit';
async function savePhotoToGallery(context: common.UIAbilityContext, url:string) {
let helper = photoAccessHelper.getPhotoAccessHelper(context);
try {
// onClick触发后10秒内通过createAsset接口创建图片文件,10秒后createAsset权限收回。
let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');
// 使用uri打开文件,可以持续写入内容,写入过程不受时间限制
let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
// 写到媒体库文件中
const source = image.createImageSource(url) // 图片对象
const packer = image.createImagePacker() // 创建打包对象
const buffer = await packer.packing(source, {
quality: 100,
format: 'image/jpeg'
})
await fileIo.write(file.fd, buffer);
await fileIo.close(file.fd);
promptAction.showToast({ message: '已保存至相册!' });
}
catch (error) {
const err: BusinessError = error as BusinessError;
console.error(`Failed to save photo. Code is ${err.code}, message is ${err.message}`);
}
}
@Entry
@Component
struct Index {
build() {
Row() {
Column({ space: 10 }) {
// $r('app.media.startIcon')需要替换为开发者所需的图像资源文件
Image('http://tmp00002.zhaodashen.cn/jd.png').width('100%')
SaveButton()
.padding({top: 12, bottom: 12, left: 24, right: 24})
.onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => {
if (result === SaveButtonOnClickResult.SUCCESS) {
const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
// 免去权限申请和权限请求等环节,获得临时授权,保存对应图片
// =======================
try {
// 需要手动将 url 替换为真实服务器的 HTTP 协议地址
request.downloadFile(
getContext(),
{
url: 'http://tmp00002.zhaodashen.cn/jd.png',
filePath: context.filesDir + '/hello3.jpg'
}
).then((data: request.DownloadTask) => {
let downloadTask: request.DownloadTask = data;
downloadTask.on('progress', (receivedSize: number, totalSize: number) => {
console.log('下载中:', receivedSize, totalSize)
})
downloadTask.on('complete', () => {
console.log('下载完成') // 保存到媒体库中✅
savePhotoToGallery(context, context.filesDir + '/hello3.jpg');
})
}).catch((err: BusinessError) => {
console.error(`Failed to request the download. Code: ${err.code}, message: ${err.message}`);
})
} catch (err) {
console.error(`Failed to request the download. err: ${JSON.stringify(err)}`);
}
// =======================
} else {
promptAction.showToast({ message: '设置权限失败!' })
}
})
}
.width('100%')
}
.height('100%')
.backgroundColor(0xF1F3F5)
}
}
更多关于HarmonyOS 鸿蒙Next中沙箱文件如何存媒体库?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,应用沙箱内的媒体文件通过媒体库接口进行管理。使用@ohos.file.photoAccessHelper或@ohos.file.videoAccessHelper模块,调用createAsset()方法可将沙箱文件存入媒体库。需先申请ohos.permission.READ_IMAGEVIDEO或ohos.permission.WRITE_IMAGEVIDEO权限。文件存入后,系统会为其分配URI,可通过媒体库查询和管理。
在HarmonyOS Next中,将沙箱内的文件(如应用私有目录中的图片、视频)存入系统媒体库,需要使用媒体库管理模块 @ohos.file.mediaLibrary 提供的接口。核心思路是:将沙箱内的源文件复制或移动到媒体库管理的公共目录下,并调用媒体库的插入接口使其被系统扫描和收录。
以下是关键步骤和代码示例:
1. 获取媒体库实例与公共目录访问权限
首先需要申请媒体库读写权限(ohos.permission.READ_MEDIA 和 ohos.permission.WRITE_MEDIA),并在代码中获取媒体库管理对象及公共目录。
import mediaLibrary from '@ohos.file.mediaLibrary';
// 获取媒体库单例对象
let media = mediaLibrary.getMediaLibrary(context);
// 获取公共目录路径,例如公共图片目录
let publicPath = await media.getPublicDirectory(mediaLibrary.DirectoryType.DIR_IMAGE);
2. 准备源文件与目标路径
假设你的应用沙箱内有一个图片文件 privateImage.jpg,位于应用文件目录 context.filesDir 下。
import fs from '@ohos.file.fs';
// 沙箱内源文件路径
let sourceFile = context.filesDir + '/privateImage.jpg';
// 在公共目录下创建目标文件路径
let destFile = publicPath + '/myAppImage.jpg';
3. 复制文件到公共目录
使用文件系统接口将文件从沙箱复制到媒体库公共目录。
try {
// 复制文件(也可使用移动 moveFile)
fs.copyFileSync(sourceFile, destFile);
console.log('File copied to public directory.');
} catch (err) {
console.error('Failed to copy file: ' + err.message);
}
4. 插入媒体库并刷新
复制完成后,需要调用媒体库的插入接口,通知系统将新文件扫描入库。
// 创建文件资源对象,指向目标文件
let fileAsset = await media.createAsset(
mediaLibrary.MediaType.IMAGE, // 媒体类型,如图片、视频
'myAppImage.jpg', // 显示名称
publicPath // 所在目录
);
if (fileAsset !== undefined) {
console.log('File inserted into media library with ID: ' + fileAsset.id);
// 可选:触发媒体库刷新(部分场景系统会自动扫描)
// mediaLibrary.getMediaLibrary().on('mediaLibraryChange', (args) => {});
}
注意事项:
- 权限申请:必须在
module.json5中声明权限,并在运行时动态申请用户授权。 - 文件类型:根据媒体类型(图片、视频、音频)选择对应的
DirectoryType(如DIR_IMAGE、DIR_VIDEO)。 - 文件覆盖:若目标文件已存在,复制或插入可能会失败,需提前检查或处理命名冲突。
- 资源释放:操作完成后,及时释放媒体库对象资源(如
media.release())。
通过以上步骤,即可将沙箱内的文件安全存入系统媒体库,供其他应用访问或系统相册显示。

