鸿蒙5文件存储解决方案:AGC云存储集成教程
前言
在HarmonyOS 5应用开发中,文件存储是常见需求。AppGallery Connect(AGC)云存储服务提供了安全可靠的文件存储解决方案,支持多种文件类型,具备权限管理和自动扩展能力。本文将详细介绍如何在HarmonyOS 5应用中集成AGC云存储服务。
第一部分:环境准备
1.1 创建HarmonyOS 5项目
打开DevEco Studio 5.0,创建新项目:
模板:Empty Ability
语言:ArkTS
API版本:HarmonyOS 5.0
配置项目基本信息:
{
"projectName": "CloudStorageDemo",
"bundleName": "com.example.cloudstorage",
"deviceTypes": ["phone", "tablet"]
}
1.2 在AGC控制台启用云存储
登录AppGallery Connect
选择你的项目,进入"构建" → "云存储"
点击"立即启用",选择存储区域(如中国区)
配置安全规则(可先使用默认规则)
第二部分:集成AGC云存储SDK
2.1 添加依赖
修改oh-package.json5文件:
{
"dependencies": {
"@hw-agconnect/api-ohos": "^1.8.0",
"@hw-agconnect/core-ohos": "^1.8.0",
"@hw-agconnect/storage-ohos": "^1.8.0"
}
}
运行依赖安装:
ohpm install
2.2 配置AGC服务
从AGC控制台下载agconnect-services.json
放入项目entry/src/main/resources/rawfile/目录
第三部分:实现文件上传功能
3.1 初始化云存储
创建entry/src/main/ets/utils/CloudStorageUtil.ets:
import { agconnect } from '@hw-agconnect/api-ohos';
import { AGCStorage, StorageReference, StorageTask, StorageError } from '@hw-agconnect/storage-ohos';
export class CloudStorageUtil {
private static instance: CloudStorageUtil = new CloudStorageUtil();
private storage: AGCStorage;
private constructor() {
agconnect.instance().init(globalThis.abilityContext);
this.storage = AGCStorage.getInstance();
}
public static get(): CloudStorageUtil {
return this.instance;
}
// 获取存储引用
public getRef(path: string): StorageReference {
return this.storage.reference().child(path);
}
// 上传文件
public async uploadFile(
localPath: string,
remotePath: string,
onProgress?: (progress: number) => void
): Promise
const ref = this.getRef(remotePath);
const task = ref.putFile(localPath);
if (onProgress) {
task.on('progress', (snapshot) => {
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
onProgress(progress);
});
}
try {
await task;
return await ref.getDownloadURL();
} catch (error) {
if (error instanceof StorageError) {
throw new Error(`上传失败: ${error.message}`);
}
throw error;
}
}
}
3.2 创建文件上传页面
创建entry/src/main/ets/pages/UploadPage.ets:
import { CloudStorageUtil } from '../utils/CloudStorageUtil';
import { common } from '@kit.AbilityKit';
import { fileIo } from '@kit.CoreFileKit';
@Entry
@Component
struct UploadPage {
@State selectedFile: string = '';
@State uploadProgress: number = 0;
@State downloadUrl: string = '';
@State isUploading: boolean = false;
// 选择文件
async selectFile() {
try {
const context = getContext(this) as common.UIAbilityContext;
const result = await context.startAbilityForResult({
bundleName: 'com.example.filepicker',
abilityName: 'FilePickerAbility'
});
if (result?.resultCode === 0 && result.want?.parameters?.fileUri) {
this.selectedFile = result.want.parameters.fileUri;
}
} catch (error) {
console.error('选择文件失败:', error);
}
}
// 上传文件
async uploadFile() {
if (!this.selectedFile) return;
this.isUploading = true;
this.uploadProgress = 0;
this.downloadUrl = '';
try {
// 获取文件名
const fileName = this.selectedFile.split('/').pop() || `file_${new Date().getTime()}`;
// 上传到云存储
const downloadUrl = await CloudStorageUtil.get().uploadFile(
this.selectedFile,
`uploads/${fileName}`,
(progress) => {
this.uploadProgress = progress;
}
);
this.downloadUrl = downloadUrl;
console.log('文件上传成功,下载URL:', downloadUrl);
} catch (error) {
console.error('上传失败:', error);
} finally {
this.isUploading = false;
}
}
build() {
Column() {
Text('文件上传')
.fontSize(25)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 30 })
// 文件选择区域
Row() {
Button('选择文件')
.width(150)
.height(50)
.onClick(() => this.selectFile())
Text(this.selectedFile || '未选择文件')
.margin({ left: 10 })
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
.width('90%')
.margin({ bottom: 20 })
// 上传按钮
Button(this.isUploading ? '上传中...' : '上传文件')
.width(200)
.height(50)
.margin({ bottom: 20 })
.enabled(!this.isUploading && !!this.selectedFile)
.onClick(() => this.uploadFile())
// 进度条
if (this.isUploading) {
Column() {
Text(`上传进度: ${this.uploadProgress.toFixed(1)}%`)
.margin({ bottom: 10 })
Progress({
value: this.uploadProgress,
total: 100,
type: ProgressType.Linear
})
.width('90%')
.height(20)
}
.width('100%')
.margin({ bottom: 20 })
}
// 下载链接
if (this.downloadUrl) {
Column() {
Text('上传成功!下载链接:')
.margin({ bottom: 10 })
Text(this.downloadUrl)
.fontColor(Color.Blue)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
.onClick(() => {
// 实现打开链接的逻辑
})
}
.width('90%')
.margin({ top: 20 })
}
}
.width('100%')
.height('100%')
.padding(20)
}
}
第四部分:实现文件下载功能
4.1 扩展CloudStorageUtil
在CloudStorageUtil.ets中添加下载方法:
// 添加至CloudStorageUtil类
public async downloadFile(
remotePath: string,
localPath: string,
onProgress?: (progress: number) => void
): Promise
const ref = this.getRef(remotePath);
const task = ref.getFile(localPath);
if (onProgress) {
task.on('progress', (snapshot) => {
const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
onProgress(progress);
});
}
try {
await task;
} catch (error) {
if (error instanceof StorageError) {
throw new Error(下载失败: ${error.message});
}
throw error;
}
}
// 获取文件列表
public async listFiles(path: string): Promise<Array
const ref = this.getRef(path);
const result = await ref.listAll();
return result.items.map(item => item.fullPath);
}
4.2 创建文件下载页面
创建entry/src/main/ets/pages/DownloadPage.ets:
import { CloudStorageUtil } from '../utils/CloudStorageUtil';
import { fileIo } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
@Entry
@Component
struct DownloadPage {
@State fileList: Array
@State downloadProgress: number = 0;
@State isDownloading: boolean = false;
@State downloadPath: string = '';
onPageShow() {
this.loadFileList();
}
// 加载文件列表
async loadFileList() {
try {
this.fileList = await CloudStorageUtil.get().listFiles('uploads/');
} catch (error) {
console.error('获取文件列表失败:', error);
}
}
// 下载文件
async downloadFile(remotePath: string) {
const context = getContext(this) as common.UIAbilityContext;
const fileName = remotePath.split('/').pop() || download_${new Date().getTime()};
const localPath = ${context.filesDir}/${fileName};
this.isDownloading = true;
this.downloadProgress = 0;
this.downloadPath = '';
try {
await CloudStorageUtil.get().downloadFile(
remotePath,
localPath,
(progress) => {
this.downloadProgress = progress;
}
);
this.downloadPath = localPath;
console.log('文件下载成功,保存路径:', localPath);
} catch (error) {
console.error('下载失败:', error);
} finally {
this.isDownloading = false;
}
}
build() {
Column() {
Text('文件下载')
.fontSize(25)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 30 })
// 文件列表
List({ space: 10 }) {
ForEach(this.fileList, (filePath) => {
ListItem() {
Row() {
Text(filePath)
.fontSize(16)
.layoutWeight(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
Button('下载')
.width(80)
.height(40)
.enabled(!this.isDownloading)
.onClick(() => this.downloadFile(filePath))
}
.width('100%')
.padding(10)
}
}, (filePath) => filePath)
}
.width('100%')
.layoutWeight(1)
// 下载进度
if (this.isDownloading) {
Column() {
Text(`下载进度: ${this.downloadProgress.toFixed(1)}%`)
.margin({ bottom: 10 })
Progress({
value: this.downloadProgress,
total: 100,
type: ProgressType.Linear
})
.width('90%')
.height(20)
}
.width('100%')
.margin({ top: 20 })
}
// 下载完成提示
if (this.downloadPath) {
Text(`文件已保存到: ${this.downloadPath}`)
.fontSize(14)
.margin({ top: 20 })
}
}
.width('100%')
.height('100%')
.padding(20)
}
}
第五部分:实现文件管理功能
5.1 扩展CloudStorageUtil
添加文件管理相关方法:
// 添加至CloudStorageUtil类
public async deleteFile(path: string): Promise
const ref = this.getRef(path);
try {
await ref.delete();
} catch (error) {
if (error instanceof StorageError) {
throw new Error(删除失败: ${error.message});
}
throw error;
}
}
public async getFileMetadata(path: string): Promise<{
name: string;
size: number;
contentType: string;
updated: string;
}> {
const ref = this.getRef(path);
const metadata = await ref.getMetadata();
return {
name: metadata.name,
size: metadata.size,
contentType: metadata.contentType,
updated: new Date(metadata.updated).toLocaleString()
};
}
5.2 创建文件管理页面
创建entry/src/main/ets/pages/FileManagerPage.ets:
import { CloudStorageUtil } from '../utils/CloudStorageUtil';
@Entry
@Component
struct FileManagerPage {
@State fileList: Array
@State currentFile: string = '';
@State fileMetadata: {
name: string;
size: string;
contentType: string;
updated: string;
} | null = null;
onPageShow() {
this.loadFileList();
}
async loadFileList() {
try {
this.fileList = await CloudStorageUtil.get().listFiles('uploads/');
} catch (error) {
console.error('获取文件列表失败:', error);
}
}
async showFileDetails(filePath: string) {
this.currentFile = filePath;
try {
const metadata = await CloudStorageUtil.get().getFileMetadata(filePath);
this.fileMetadata = {
name: metadata.name,
size: ${(metadata.size / 1024).toFixed(2)} KB,
contentType: metadata.contentType,
updated: metadata.updated
};
} catch (error) {
console.error('获取文件详情失败:', error);
this.fileMetadata = null;
}
}
async deleteCurrentFile() {
if (!this.currentFile) return;
try {
await CloudStorageUtil.get().deleteFile(this.currentFile);
this.currentFile = '';
this.fileMetadata = null;
await this.loadFileList();
} catch (error) {
console.error('删除文件失败:', error);
}
}
build() {
Column() {
Text('文件管理')
.fontSize(25)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 30 })
// 文件列表
List({ space: 10 }) {
ForEach(this.fileList, (filePath) => {
ListItem() {
Row() {
Text(filePath)
.fontSize(16)
.layoutWeight(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
Button('查看')
.width(80)
.height(40)
.onClick(() => this.showFileDetails(filePath))
}
.width('100%')
.padding(10)
}
}, (filePath) => filePath)
}
.width('100%')
.layoutWeight(1)
// 文件详情
if (this.fileMetadata) {
Column() {
Text('文件详情')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 15 })
Divider()
Row() {
Text('名称:')
.fontWeight(FontWeight.Bold)
.width(100)
Text(this.fileMetadata.name)
.layoutWeight(1)
}
.margin({ bottom: 10 })
Row() {
Text('大小:')
.fontWeight(FontWeight.Bold)
.width(100)
Text(this.fileMetadata.size)
.layoutWeight(1)
}
.margin({ bottom: 10 })
Row() {
Text('类型:')
.fontWeight(FontWeight.Bold)
.width(100)
Text(this.fileMetadata.contentType)
.layoutWeight(1)
}
.margin({ bottom: 10 })
Row() {
Text('修改时间:')
.fontWeight(FontWeight.Bold)
.width(100)
Text(this.fileMetadata.updated)
.layoutWeight(1)
}
.margin({ bottom: 20 })
Button('删除文件')
.width(200)
.height(50)
.backgroundColor(Color.Red)
.fontColor(Color.White)
.onClick(() => this.deleteCurrentFile())
}
.width('90%')
.padding(20)
.margin({ top: 20 })
.border({ width: 1, color: '#eeeeee' })
.borderRadius(10)
}
}
.width('100%')
.height('100%')
.padding(20)
}
}
第六部分:安全规则配置
6.1 基本安全规则
在AGC控制台的云存储服务中,配置安全规则:
rules_version = '2';
service cloud.storage {
match /{bucket}/{path=} {
// 允许认证用户读写自己的文件
match /users/{userId}/{file=} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
// 允许公开读取上传的文件
match /uploads/{file=**} {
allow read;
allow write: if request.auth != null;
}
// 默认拒绝所有其他访问
match /{path=**} {
allow read, write: if false;
}
}
}
6.2 在应用中验证权限
在CloudStorageUtil.ets中添加权限检查:
// 添加至CloudStorageUtil类
public async checkPermission(path: string, operation: 'read' | 'write'): Promise
try {
const ref = this.getRef(path);
if (operation === 'read') {
await ref.getDownloadURL(); // 尝试获取下载URL
return true;
} else {
// 尝试写入一个测试文件
const testRef = ref.child('.permission_test');
await testRef.putString('test');
await testRef.delete();
return true;
}
} catch (error) {
return false;
}
}
第七部分:完整应用集成
7.1 创建主页面
修改entry/src/main/ets/pages/Index.ets:
@Entry
@Component
struct Index {
build() {
Column() {
Navigation() {
Column() {
Text('AGC云存储演示')
.fontSize(30)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 40 })
Button('文件上传')
.width(200)
.height(50)
.margin({ bottom: 20 })
.onClick(() => {
router.pushUrl({ url: 'pages/UploadPage' });
})
Button('文件下载')
.width(200)
.height(50)
.margin({ bottom: 20 })
.onClick(() => {
router.pushUrl({ url: 'pages/DownloadPage' });
})
Button('文件管理')
.width(200)
.height(50)
.onClick(() => {
router.pushUrl({ url: 'pages/FileManagerPage' });
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
.width('100%')
.height('100%')
}
}
7.2 配置路由
在entry/src/main/resources/base/profile/main_pages.json中添加:
{
"src": [
"pages/Index",
"pages/UploadPage",
"pages/DownloadPage",
"pages/FileManagerPage"
]
}
总结
通过本教程,你已经完成了:
HarmonyOS 5项目中集成AGC云存储服务
实现了文件上传、下载和管理功能
配置了云存储安全规则
构建了完整的文件管理应用
AGC云存储提供了强大的文件管理能力,包括:
自动扩展的存储空间
文件访问权限控制
上传下载进度监控
文件元数据管理
你可以基于此项目进一步扩展,实现更复杂的文件操作功能,如断点续传、文件预览等。

浙公网安备 33010602011771号