How Can I Quickly Integrate AppGallery Connect Cloud Storage into a Unity App?

Mayism
5 min readFeb 12, 2021

HUAWEI AppGallery Connect Cloud Storage provides maintenance-free cloud storage functions.

In this post, we’ll walk you through the steps required for integrating this service in Unity. You can access the Cloud Storage sample code on GitHub.

1. Test Environment

SDK Version: agconnect-storage:1.3.1.100

Platform:Unity 2019.4.17f1c1

Test Device:HONOR Magic 2

AppGallery Connect:

https://developer.huawei.com/consumer/en/service/josp/agc/index.html

2. Applying for Cloud Storage

Currently, Cloud Storage is still in beta status. To use the service, you need to send an application by email. For details, check:

https://developer.huawei.com/consumer/en/doc/development/AppGallery-connect-Guides/agc-cloudstorage-apply

3. Importing the Unity Package

Unity materials:

https://docs.unity.cn/cn/Packages-cn/com.unity.huaweiservice@1.3/manual/cloudstorage.html

1. Download Unity Hub here and install Unity Editor.

2. Configure the Android environment.

3. Import the HuaweiServices package. Download the package from Unity Assets Store. In Unity Editor, choose Assets > Import package.

Select the required package and click Import.

4. Completing Configurations in AppGallery Connect

1. Sign in to AppGallery Connect, and click the created app.

2. Go to My projects > Build > Cloud Storage and click Enable now. Set the default storage instance as required.

To permit Cloud Storage to read and write data without authorization, add the following code:

agc.cloud.storage[ 
match: /{bucket}/{path=**} {
allow read, write: if true;
}
]

3. Go to Project settings > General information and download the latest agconnect-services.json file.

4. Save the file to the Assets\Plugins\Android directory of your Unity project.

If the downloaded JSON file does not contain the default_storage parameter under cloudstorage, you need to add it manually. Set its value to the storage instance you just configured.

5. Completing Project Information in Unity Editor

1. Choose Edit > Project Settings > Player > Publish Settings. In the Build area, select the items for Android according to your requirements.

2. In Unity Editor, choose Edit > Project Settings > Player > Other Settings, and set the package name to match the package name you set in AppGallery Connect.

3. Add the following code to the project-level baseProjectTmeplate.gradle file in the Assets\Plugins\Android directory:

allprojects {
buildscript {
repositories {
maven { url 'https://developer.huawei.com/repo/' }
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
classpath 'com.huawei.agconnect:agcp:1.4.2.301'
**BUILD_SCRIPT_DEPS**
}
}
repositories {
maven { url 'https://developer.huawei.com/repo/' }
}
}

4. Add the following code to the app-level LauncherTmeplate.gradle file in the Assets\Plugins\Android directory:

apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'

dependencies {
implementation project(':unityLibrary')
implementation "com.huawei.agconnect:agconnect-storage:1.3.1.100"
implementation 'com.huawei.agconnect:agconnect-auth:1.4.2.301'

5. Configure the manifest file to add the corresponding permissions.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<application
android:allowBackup="false"
android:requestLegacyExternalStorage="true" >

6. Using Cloud Storage

1. Configure the UI layout.

In Unity Editor, choose GameObject > UI > Button and create a button. Click the button, click Add Component on the right to create a script file, and then create the corresponding method.

2. Initialize the storage instance and apply for the read and write permissions.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HuaweiService;
using HuaweiService.CloudStorage;
using System;

public delegate void SuccessCallBack<T>(T o);
public class HmsSuccessListener<T>:OnSuccessListener{
public SuccessCallBack<T> CallBack;
public HmsSuccessListener(SuccessCallBack<T> c){
CallBack = c;
}
public void onSuccess(T arg0)
{
Debug.Log("OnSuccessListener onSuccess");
if(CallBack != null)
{
CallBack.Invoke(arg0);
}
}

public override void onSuccess(AndroidJavaObject arg0){
Debug.Log("OnSuccessListener onSuccess");
if(CallBack !=null)
{
Type type = typeof(T);
IHmsBase ret = (IHmsBase)Activator.CreateInstance(type);
ret.obj = arg0;
CallBack.Invoke((T)ret);
}
}
}

public class testStorageDemo : MonoBehaviour
{
private AGCStorageManagement mAGCStorageManagement;
private string[] permissions =
{
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.READ_EXTERNAL_STORAGE",
};
// Start is called before the first frame update
void Start()
{
AndroidJavaClass javaUnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = javaUnityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
Activity aaa = HmsUtil.GetHmsBase<Activity>(currentActivity);
ActivityCompat.requestPermissions(aaa, permissions, 1);
}

// Update is called once per frame
void Update()
{

}

public void initAGCStorageManagement() {

mAGCStorageManagement = AGCStorageManagement.getInstance("9105385871708601205-ffeon");
Debug.Log("Instance is: "+ mAGCStorageManagement);

}

public class MySuccessListener : OnSuccessListener
{
private string m_name;

public MySuccessListener(string name)
{
m_name = name;
}

public MySuccessListener()
{
m_name = "default";
}

public override void onSuccess(AndroidJavaObject ex)
{
Debug.Log("download success: " + m_name);
}
}

}

3. Upload a file.

public void uploadFile() {
if (mAGCStorageManagement == null){
initAGCStorageManagement();
}
string fileName = "testUnity.jpg";
StorageReference reference = mAGCStorageManagement.getStorageReference(fileName);
string FileFolder = "/storage/emulated/0/AGCSdk/";
string FilePath = FileFolder + fileName;

Debug.Log("FilePath = " + FilePath);
File file = new File(FilePath);
Debug.Log("UploadFile = " + file);

UploadTask task = reference.putFile(file);
task.addOnSuccessListener(new MySuccessListener());
Debug.Log("UploadFile done:");
}

4. Download a file.

public void downloadFile() {
if (mAGCStorageManagement == null){
initAGCStorageManagement();
}
StorageReference reference = mAGCStorageManagement.getStorageReference("test.jpg");
string FileFolder = "/storage/emulated/0/AGCSdk/";
string FilePath = FileFolder + "test.jpg";

Debug.Log("FilePath = " + FilePath);
File file = new File(FilePath);
Debug.Log("File = " + file);

DownloadTask task = reference.getFile(file);
task.addOnSuccessListener(new MySuccessListener("NormalListener"));
Debug.Log("DownloadTask Result:");
}

5. Delete a file.

public void deleteFile() {
if (mAGCStorageManagement == null){
initAGCStorageManagement();
}

StorageReference reference = mAGCStorageManagement.getStorageReference("testUnity.jpg");
reference.delete();
Debug.Log("DeleteFileTest success.");
}

6. Package and test the app.

After you have packaged and installed the test app, you can tap each button, and view related logs in the Android Studio Logcat.

You can view the files you upload to or download from AppGallery Connect.

7. Summary

You can use Cloud Storage to store your Unity game data on the cloud without the hassle of server building and O&M. With AppGallery Connect, a web console, you can easily manage your files on the cloud side.

In addition to file upload, download, and deletion, Cloud Storage also offers a metadata setting function.

For reference:

Cloud Storage development guide:

https://developer.huawei.com/consumer/en/doc/development/AppGallery-connect-Guides/agc-cloudstorage-introduction

Unity materials:

https://docs.unity.cn/cn/Packages-cn/com.unity.huaweiservice@1.3/manual/cloudstorage.html

Cloud Storage codelab:

https://github.com/AppGalleryConnect/agc-demos/tree/main/Android/agc-cloudstorage-demo-java

--

--