鸿蒙5与AGC云存储实战:实现安全高效的图片上传下载

一、环境准备与配置
1.1 在AGC控制台启用云存储服务
登录AppGallery Connect
进入「构建」>「云存储」服务
开启服务并配置默认存储位置
1.2 项目级build.gradle配置
// 项目级build.gradle
buildscript {
repositories {
maven { url 'https://developer.huawei.com/repo/' }
}
dependencies {
classpath 'com.huawei.agconnect:agcp:1.6.5.300'
}
}
1.3 模块级build.gradle配置
dependencies {
implementation 'com.huawei.agconnect:agconnect-storage-harmony:1.6.5.300'
implementation 'com.huawei.agconnect:agconnect-auth-harmony:1.6.5.300'
}
二、云存储初始化与安全配置
2.1 初始化云存储实例
import com.huawei.agconnect.cloud.storage.core.AGCStorageManagement;
import com.huawei.agconnect.cloud.storage.core.StorageReference;
import ohos.app.Context;

public class CloudStorageManager {
private static AGCStorageManagement storageInstance;

public static void init(Context context) {
    if (storageInstance == null) {
        storageInstance = AGCStorageManagement.getInstance(context);
    }
}

public static StorageReference getRootReference() {
    return storageInstance.getStorageReference();
}

}
2.2 安全规则配置示例
// 在AGC控制台配置的存储规则示例
{
"rules": {
"images": {
"$imageId": {
".read": "auth != null",
".write": "auth != null && request.resource.size < 5 * 1024 * 1024",
".contentType": "image/*"
}
}
}
}
三、实现图片上传功能
3.1 基础图片上传
import com.huawei.agconnect.cloud.storage.core.UploadTask;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import java.io.ByteArrayOutputStream;

public class ImageUploader {
public static UploadTask uploadImage(PixelMap pixelMap, String remotePath) {
// 转换PixelMap为字节数组
ImageSource.EncodeOptions options = new ImageSource.EncodeOptions();
options.format = "image/jpeg";
options.quality = 80;

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    pixelMap.encode(baos, options);
    byte[] imageData = baos.toByteArray();
    
    // 获取存储引用并上传
    StorageReference imageRef = CloudStorageManager.getRootReference()
        .child("images/" + System.currentTimeMillis() + ".jpg");
    
    return imageRef.putBytes(imageData)
        .addOnProgressListener(taskSnapshot -> {
            double progress = (100.0 * taskSnapshot.getBytesTransferred()) 
                            / taskSnapshot.getTotalByteCount();
            updateUploadProgress(progress);
        });
}

private static void updateUploadProgress(double progress) {
    // 更新UI进度显示
}

}
3.2 带元数据的上传(推荐)
import com.huawei.agconnect.cloud.storage.core.StorageMetadata;
import java.util.HashMap;

public UploadTask uploadWithMetadata(PixelMap pixelMap, String userId) {
// 创建元数据
StorageMetadata metadata = new StorageMetadata.Builder()
.setCustomMetadata(new HashMap<String, String>() {{
put("uploader", userId);
put("device_model", SystemUtil.getDeviceModel());
}})
.setContentType("image/jpeg")
.build();

// 转换图片数据...
ByteArrayOutputStream baos = new ByteArrayOutputStream();
pixelMap.encode(baos, new ImageSource.EncodeOptions());

// 上传带元数据的文件
String filename = "user_" + userId + "_" + System.currentTimeMillis() + ".jpg";
return CloudStorageManager.getRootReference()
    .child("user_images/" + filename)
    .putBytes(baos.toByteArray(), metadata);

}
四、实现图片下载功能
4.1 基础图片下载
import com.huawei.agconnect.cloud.storage.core.DownloadTask;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;

public class ImageDownloader {
public static DownloadTask downloadImage(String remotePath, ImageCallback callback) {
StorageReference imageRef = CloudStorageManager.getRootReference()
.child(remotePath);

    return imageRef.getBytes(Long.MAX_VALUE)
        .addOnSuccessListener(bytes -> {
            ImageSource source = ImageSource.create(bytes, null);
            PixelMap pixelMap = source.createPixelmap(null);
            callback.onSuccess(pixelMap);
        })
        .addOnFailureListener(e -> {
            callback.onError(e);
        });
}

public interface ImageCallback {
    void onSuccess(PixelMap pixelMap);
    void onError(Exception e);
}

}
4.2 带缩略图的下载优化
import com.huawei.agconnect.cloud.storage.core.StorageReference;

public DownloadTask downloadThumbnail(String remotePath, int maxWidth) {
StorageReference imageRef = CloudStorageManager.getRootReference()
.child(remotePath);

// 创建下载URL时添加图片处理参数
return imageRef.getBytes(Long.MAX_VALUE, 
    new StorageReference.GetBytesOptions() {{
        setImageSizing(maxWidth);
    }})
    .addOnSuccessListener(bytes -> {
        // 处理缩略图数据...
    });

}
五、高级功能实现
5.1 断点续传实现
import com.huawei.agconnect.cloud.storage.core.ContinuationResult;

public class ResumableUploader {
private UploadTask uploadTask;
private byte[] fileData;
private String remotePath;

public void startUpload(byte[] data, String path) {
    this.fileData = data;
    this.remotePath = path;
    
    StorageReference ref = CloudStorageManager.getRootReference()
        .child(path);
        
    uploadTask = ref.putBytes(data);
    uploadTask.addOnPausedListener(taskSnapshot -> {
        saveUploadState(taskSnapshot.getUploadSessionUri());
    });
}

public void resumeUpload(String sessionUri) {
    uploadTask = CloudStorageManager.getRootReference()
        .resumeUpload(sessionUri)
        .putBytes(fileData);
}

private void saveUploadState(String sessionUri) {
    // 保存sessionUri到本地存储
}

}
5.2 图片批量操作
import com.huawei.agconnect.cloud.storage.core.ListResult;
import com.huawei.agconnect.cloud.storage.core.StorageReference;

public class BatchImageManager {
public static void listUserImages(String userId, ImageListCallback callback) {
CloudStorageManager.getRootReference()
.child("user_images/")
.list(100) // 最大返回100条
.addOnSuccessListener(result -> {
List images = new ArrayList<>();
for (StorageReference item : result.getItems()) {
if (item.getName().contains("user_" + userId)) {
images.add(item);
}
}
callback.onListReady(images);
})
.addOnFailureListener(callback::onError);
}

public static void deleteImages(List<String> paths) {
    for (String path : paths) {
        CloudStorageManager.getRootReference()
            .child(path)
            .delete();
    }
}

public interface ImageListCallback {
    void onListReady(List<StorageReference> images);
    void onError(Exception e);
}

}
六、性能优化与错误处理
6.1 上传下载性能优化
// 在Application初始化时配置
AGCStorageManagement.setMaxUploadRetryTime(3); // 设置最大重试次数
AGCStorageManagement.setMaxDownloadRetryTime(3);
AGCStorageManagement.setTransferThreadPoolSize(4); // 设置并发线程数
6.2 完善的错误处理
import com.huawei.agconnect.cloud.storage.core.StorageException;

public class ErrorHandler {
public static String handleStorageError(Exception e) {
if (e instanceof StorageException) {
StorageException se = (StorageException)e;
switch (se.getCode()) {
case StorageException.ERROR_NOT_AUTHENTICATED:
return "请先登录";
case StorageException.ERROR_QUOTA_EXCEEDED:
return "存储空间不足";
case StorageException.ERROR_CANCELED:
return "操作已取消";
case StorageException.ERROR_RETRY_LIMIT_EXCEEDED:
return "网络不稳定,请重试";
default:
return "存储服务错误: " + se.getCode();
}
}
return "未知错误: " + e.getMessage();
}
}
七、完整示例:图片管理组件
import ohos.agp.components.*;
import ohos.app.Context;
import ohos.media.image.PixelMap;

public class ImageManagerComponent extends StackLayout {
private Button uploadBtn;
private ImageView previewImage;
private ProgressBar progressBar;

public ImageManagerComponent(Context context) {
    super(context);
    initView();
}

private void initView() {
    // 初始化UI组件
    uploadBtn = new Button(getContext());
    uploadBtn.setText("上传图片");
    uploadBtn.setClickedListener(component -> selectImage());
    
    previewImage = new ImageView(getContext());
    progressBar = new ProgressBar(getContext());
    progressBar.setVisibility(Component.HIDE);
    
    addComponent(uploadBtn);
    addComponent(previewImage);
    addComponent(progressBar);
}

private void selectImage() {
    // 调用系统图片选择器...
    // 获取到PixelMap后调用uploadAndDisplay
}

private void uploadAndDisplay(PixelMap pixelMap) {
    progressBar.setVisibility(Component.VISIBLE);
    
    ImageUploader.uploadImage(pixelMap, "user_uploads/" + System.currentTimeMillis() + ".jpg")
        .addOnSuccessListener(taskSnapshot -> {
            // 上传成功后获取下载URL并显示
            taskSnapshot.getStorage().getDownloadUrl()
                .addOnSuccessListener(uri -> {
                    ImageDownloader.downloadImage(uri.toString(), new ImageDownloader.ImageCallback() {
                        @Override
                        public void onSuccess(PixelMap downloadedImage) {
                            getContext().getUITaskDispatcher().asyncDispatch(() -> {
                                previewImage.setPixelMap(downloadedImage);
                                progressBar.setVisibility(Component.HIDE);
                            });
                        }
                        
                        @Override
                        public void onError(Exception e) {
                            showToast("图片加载失败: " + ErrorHandler.handleStorageError(e));
                            progressBar.setVisibility(Component.HIDE);
                        }
                    });
                });
        })
        .addOnFailureListener(e -> {
            showToast("上传失败: " + ErrorHandler.handleStorageError(e));
            progressBar.setVisibility(Component.HIDE);
        })
        .addOnProgressListener(taskSnapshot -> {
            double progress = (100.0 * taskSnapshot.getBytesTransferred()) 
                            / taskSnapshot.getTotalByteCount();
            progressBar.setProgressValue((int)progress);
        });
}

private void showToast(String message) {
    // 实现Toast显示
}

}
结语
本文详细介绍了在HarmonyOS 5应用中集成AGC云存储服务实现图片上传下载的完整方案。关键点包括:

​​安全配置​​:通过服务端安全规则确保数据安全
​​性能优化​​:利用断点续传、缩略图等技术提升用户体验
​​错误处理​​:完善的错误处理机制增强应用健壮性
实际开发中,建议:

根据业务需求调整存储路径结构
实施客户端缓存策略减少网络请求
定期检查AGC服务端的用量统计和性能指标

posted @ 2025-06-28 22:28  暗雨YA  阅读(49)  评论(0)    收藏  举报