在HarmonyOS Next中,将网络图片下载并保存到本地相册,主要涉及网络请求、文件写入和媒体库更新三个核心步骤。以下是关键实现代码和说明:
1. 权限申请
首先,需要在 module.json5 配置文件中声明必要的权限:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.WRITE_IMAGEVIDEO"
}
]
}
}
INTERNET 权限用于网络下载。
WRITE_IMAGEVIDEO 权限用于将图片写入媒体库(相册)。
2. 核心实现代码
以下是一个封装好的 ImageDownloader 工具类示例,可直接调用:
import { common, http } from '@kit.NetworkKit';
import { mediaLibrary } from '@kit.MediaLibraryKit';
import { fileIo } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { util } from '@kit.ArkTS';
export class ImageDownloader {
/**
* 下载图片并保存到相册
* @param imageUrl 网络图片地址
* @returns 返回保存成功后的本地URI,失败则返回空字符串
*/
static async downloadAndSave(imageUrl: string): Promise<string> {
try {
// 1. 创建HTTP请求
let request: http.HttpRequest = http.createHttp();
let response = await request.request(imageUrl, {
method: http.RequestMethod.GET,
responseType: http.ResponseType.ARRAY_BUFFER
});
// 2. 检查响应
if (response.responseCode !== http.ResponseCode.OK) {
console.error(`Download failed with code: ${response.responseCode}`);
return '';
}
// 3. 获取媒体库实例
let context = getContext(this) as common.UIAbilityContext;
let media = mediaLibrary.getMediaLibrary(context);
// 4. 创建相册目录(如果不存在)
let publicDirectory = mediaLibrary.DirectoryType.DIR_IMAGE;
let date = util.DateTime.getDate();
let displayName = `IMG_${date.getTime()}.jpg`;
// 5. 保存到媒体库
let fileAsset = await media.createAsset(
mediaLibrary.MediaType.IMAGE,
displayName,
publicDirectory
);
if (!fileAsset) {
console.error('Create file asset failed');
return '';
}
// 6. 写入文件数据
let fd = await fileAsset.open('rw');
await fileIo.write(fd, response.result as ArrayBuffer);
await fileAsset.close(fd);
// 7. 返回本地URI
return fileAsset.uri;
} catch (error) {
let err: BusinessError = error as BusinessError;
console.error(`Download error: code=${err.code}, message=${err.message}`);
return '';
}
}
}
3. 调用示例
在需要的地方(如按钮点击事件)调用该方法:
import { ImageDownloader } from '../utils/ImageDownloader';
// 示例:下载图片
let imageUrl = 'https://example.com/image.jpg';
let localUri = await ImageDownloader.downloadAndSave(imageUrl);
if (localUri) {
console.info('Image saved successfully: ' + localUri);
// 这里可以通知H5端下载成功
} else {
console.error('Image save failed');
// 通知H5端下载失败
}
4. 与H5交互
如果是从H5页面调用,需要在 EntryAbility 中注册自定义路由,并通过 postMessage 与H5通信:
// 在Web组件中注册JavaScript接口
webController.registerJavaScriptProxy({
downloadImage: (url: string) => {
return ImageDownloader.downloadAndSave(url);
}
}, 'harmonyBridge');
// H5端通过 window.harmonyBridge.downloadImage(url) 调用
关键注意事项:
- 网络请求:确保设备可以访问目标URL,HTTPS地址需要配置网络安全。
- 文件命名:示例中使用时间戳命名,可根据需求调整。
- 错误处理:实际使用中应添加更完善的错误提示和用户反馈。
- 大文件下载:如需下载大文件,建议实现分片下载和进度回调。
此实现直接保存到系统相册,用户可以在图库中立即看到下载的图片。