Introduction

HUAWEI Drive Kit ("Drive Kit") allows you to create apps that use the HUAWEI Drive Kit service. Drive Kit provides cloud storage for your apps, enabling users to store files that are created when using your apps, including photos, videos, and documents, in HUAWEI Drive ("Drive"), as well as download, synchronize, and search for these files on demand. Drive Kit also provides comprehensive data protection, empowering users to manage their data securely and conveniently.
The current core capabilities of Drive Kit include uploading, downloading, and searching for files in the drive, in addition to querying and getting notifications.

What You Will Create

In this codelab, you will create an Android app that is capable of using the HUAWEI Drive Kit service. By integrating Drive Kit into your app, the app will allow users to manage and edit files in Drive with optimal convenience, with the ability to store photos, drawings, recordings, videos, and designs in Drive, and access files in Drive from any smartphone, tablet, or computer.

What You Will Learn

What You Will Need

Hardware Requirements

Software Requirements

To integrate HUAWEI HMS Core services, you will need to complete the following preparations:

For details, please refer to Preparations for Integrating HUAWEI HMS.

Enabling Required Services

Go to Develop > Overview > Manage APIs.

On the service management page, toggle the HUAWEI Drive switch and HUAWEI Account switch.

Adding Configuration File

Adding the agconnect-services.json File of the App

  1. In HUAWEI Developer AppGallery Connect, click the app that you have created, and go to Develop > Overview. In the Product information section, click Set.
  2. Set the app data storage location as needed, and click OK.
  3. In the App information section, click agconnect-services.json to download the configuration file.
  4. Copy the agconnect-services.json file to the app's root directory.

Adding Build Dependencies

1. Open the build.gradle file in the app directory.

2. Configure build dependencies.

dependencies { implementation 'com.huawei.hms:drive:4.0.0.301' implementation 'com.huawei.hms:hwid:4.0.0.300' }

3. Open the modified build.gradle file. You will find a Sync Now link in the upper right corner of the page. Click Sync Now and wait until synchronization is complete.

4. Define multi-language settings.

● Skip this step if your app does not require support for additional languages. By default, the app will support all languages supported by the HMS SDK.

● If your app only supports certain languages, you can configure the languages during this step.

  1. Open the build.gradle file in the app directory of your project.
  2. Go to android > defaultConfig and add the resConfigs configuration. en (English) and zh-rCN (Simplified Chinese) are mandatory. For example, if your app only supports English and Simplified Chinese, the configuration is as follows:
    android { defaultConfig { ... resConfigs "en", "zh-rCN" } }

Configuring Obfuscation Scripts

Before building the APK, configure obfuscation scripts to prevent the HMS SDK from being obfuscated. If obfuscation arises, the HMS SDK may not function properly.

1. Open the obfuscation configuration file proguard-rules.pro of your Android project.

2. Add configurations to exclude the HMS SDK from obfuscation.

-ignorewarnings -keepattributes *Annotation* -keepattributes Exceptions -keepattributes InnerClasses -keepattributes Signature -keepattributes SourceFile,LineNumberTable -keep class com.hianalytics.android.**{*;} -keep class com.huawei.updatesdk.**{*;} -keep class com.huawei.hms.**{*;} -keep class com.huawei.cloud.services.drive.**{*;}

3. If you have used AndResGuard, add it to the whitelist in the obfuscation script file.

"R.string.hms*", "R.string.connect_server_fail_prompt_toast", "R.string.getting_message_fail_prompt_toast", "R.string.no_available_network_prompt_toast", "R.string.third_app_*", "R.string.upsdk_*", "R.layout.hms*", "R.layout.upsdk_*", "R.drawable.upsdk*", "R.color.upsdk*", "R.dimen.upsdk*", "R.style.upsdk*", "R.string.agc*"

Signing In with a HUAWEI ID

Handling a login Button Event

To implement the sign-in function through the HMS SDK, you will need to set the Drive scope for obtaining the permission to access Drive APIs.

private void driveLogin() { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); List<Scope> scopeList = new ArrayList<>(); scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE)); // All permissions, except permissions for the app folder. scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_READONLY)); // Permissions to view file content and metadata. scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_FILE)); // Permissions to view and manage files. scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_METADATA)); // Permissions to view and manage file metadata, excluding file content. scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_METADATA_READONLY)); // Permissions to view file metadata, excluding file content. scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_APPDATA)); // Permissions to upload and store app data. scopeList.add(HuaweiIdAuthAPIManager.HUAWEIID_BASE_SCOPE); // Basic account permissions. HuaweiIdAuthParams authParams = new HuaweiIdAuthParamsHelper(DEFAULT_AUTH_REQUEST_PARAM) .setAccessToken() .setIdToken() .setScopeList(scopeList) .createParams(); // Call the account API to get account information. HuaweiIdAuthService client = HuaweiIdAuthManager.getService(this, authParams); startActivityForResult(client.getSignInIntent(), REQUEST_SIGN_IN_LOGIN); }

Each Drive scope corresponds to a certain type of permissions. You may apply for the permissions as needed. For details about the corresponding APIs, please refer to HUAWEI Account Kit Development Guide. If the app user has not signed with his/her HUAWEI ID, the HMS SDK will prompt him/her to sign in.

// Exceptional process for obtaining account information. Obtain and save the related accessToken and unionID using this function. @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Log.i(TAG, "onActivityResult, requestCode = " + requestCode + ", resultCode = " + resultCode); if (requestCode == REQUEST_SIGN_IN_LOGIN) { Task<AuthHuaweiId> authHuaweiIdTask = HuaweiIdAuthManager.parseAuthResultFromIntent(data); if (authHuaweiIdTask.isSuccessful()) { AuthHuaweiId huaweiAccount = authHuaweiIdTask.getResult(); accessToken = huaweiAccount.getAccessToken(); unionId = huaweiAccount.getUnionId(); int returnCode = init(unionId, accessToken, refreshAT); if (DriveCode.SUCCESS == returnCode) { showTips("login ok"); } else if (DriveCode.SERVICE_URL_NOT_ENABLED == returnCode) { showTips("drive is not enabled"); } else { showTips("login error"); } } else { Log.d(TAG, "onActivityResult, signIn failed: " + ((ApiException) authHuaweiIdTask.getException()).getStatusCode()); Toast.makeText(getApplicationContext(), "onActivityResult, signIn failed.", Toast.LENGTH_LONG).show(); } } } public int init(String unionID, String at, DriveCredential.AccessMethod refreshAT) { if (StringUtils.isNullOrEmpty(unionID) || StringUtils.isNullOrEmpty(at)) { return DriveCode.ERROR; } DriveCredential.Builder builder = new DriveCredential.Builder(unionID, refreshAT); mCredential = builder.build().setAccessToken(at); return DriveCode.SUCCESS; } private void showTips(final String toastText) { MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), toastText, Toast.LENGTH_LONG).show(); TextView textView = findViewById(R.id.textView); textView.setText(toastText); } }); }

Calling the Files.create API to Create a Folder and Upload a File

API Description

API name:

public Create create(File content) throws java.io.IOException public Create create(File content, AbstractInputStreamContent mediaContent) throws java.io.IOException

API description:
This API is used to create a file and a folder. For details about API usage, please refer to HUAWEI Drive Kit Development Guide.

Setting the Read and Write Permissions

Add the phone storage read and write permissions to app/src/main/AndroidManifest.xml.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" tools:ignore="ProtectedPermissions" />

Add a permission application to the oncreate method in MainActivity.java.

private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestPermissions(PERMISSIONS_STORAGE, 1); }

Add the code snippet for applying for the permissions.

Handling an upload Button Event

Create a folder in the root directory of Drive, and upload the file in the designated directory to the folder.

private void uploadFiles() { new Thread(new Runnable() { @Override public void run() { try { if (accessToken == null) { showTips("please click 'Login'."); return; } if (StringUtils.isNullOrEmpty(uploadFileName.getText().toString())) { showTips("please input upload file name above."); return; } java.io.File fileObject = new java.io.File("/sdcard/" + uploadFileName.getText()); if (!fileObject.exists()) { showTips("the input file does not exist."); return; } Drive drive = buildDrive(); Map<String, String> appProperties = new HashMap<>(); appProperties.put("appProperties", "property"); // Create a folder. File file = new File(); file.setFileName("somepath" + System.currentTimeMillis()) .setMimeType("application/vnd.huawei-apps.folder") .setAppSettings(appProperties); directoryCreated = drive.files().create(file).execute(); // Upload the file. File content = new File() .setFileName(fileObject.getName()) .setMimeType(mimeType(fileObject)) .setParentFolder(Collections.singletonList(directoryCreated.getId())); drive.files() .create(content, new FileContent("image/jpeg", fileObject)) .setFields("*") .execute(); showTips("upload success"); } catch (Exception ex) { Log.d("upload", ex); showTips("upload error " + ex.toString()); } } }).start(); } private Drive buildDrive() { Drive service = new Drive.Builder(mCredential, this).build(); return service; } private String mimeType(java.io.File file) { if (file != null && file.exists() && file.getName().contains(".")) { String fileName = file.getName(); String suffix = fileName.substring(fileName.lastIndexOf(".")); if (MIME_TYPE_MAP.keySet().contains(suffix)) { return MIME_TYPE_MAP.get(suffix); } } return "*/*"; }

After the folder is created and the file is uploaded, the file can be accessed by going to Files > HUAWEI Drive.

Calling the Files.list API to Query File Details by File Name

API Description

API name:

public List list() throws java.io.IOException

Handling a query Button Event

private void queryFiles() { new Thread(new Runnable() { @Override public void run() { try { if (accessToken == null) { showTips("please click 'Login'."); return; } if (StringUtils.isNullOrEmpty(searchFileName.getText().toString())) { showTips("please input file name above."); return; } String queryFile = "fileName = '" + searchFileName.getText() + "' and mimeType != 'application/vnd.huawei-apps.folder'"; Drive drive = buildDrive(); Drive.Files.List request = drive.files().list(); FileList files; while (true) { files = request .setQueryParam(queryFile) .setPageSize(10) .setOrderBy("fileName") .setFields("category,nextCursor,files/id,files/fileName,files/size") .execute(); if (files == null || files.getFiles().size() > 0) { break; } if (!StringUtils.isNullOrEmpty(files.getNextCursor())) { request.setCursor(files.getNextCursor()); } else { break; } } String text = ""; if (files != null && files.getFiles().size() > 0) { fileSearched = files.getFiles().get(0); text = fileSearched.toString(); } else { text = "empty"; } final String finalText = text; MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { queryResult.setText(finalText); } }); showTips("query ok"); } catch (Exception ex) { Log.d(TAG, "query", ex); showTips("query error " + ex.toString()); } } }).start(); }

Calling the Files.get API to Download a File

API Description

public Get get(String fileId) throws java.io.IOException

Handling a download Button Event

private void downloadFiles() { new Thread(new Runnable() { @Override public void run() { try { if (accessToken == null) { showTips("please click 'Login'."); return; } if (fileSearched == null) { showTips("please click 'QUERY FILE'."); return; } Drive drive = buildDrive(); File content = new File(); Drive.Files.Get request = drive.files().get(fileSearched.getId()); content.setFileName(fileSearched.getFileName()) .setId(fileSearched.getId()); MediaHttpDownloader downloader = request.getMediaHttpDownloader(); downloader.setContentRange(0, fileSearched.getSize() - 1); String filePath = "/storage/emulated/0/Huawei/Drive/DownLoad/Demo_" + fileSearched.getFileName(); request.executeContentAndDownloadTo(new FileOutputStream(new java.io.File(filePath))); showTips("download to " + filePath); } catch (Exception ex) { Log.d(TAG, "download", ex); showTips("download error " + ex.toString()); } } }).start(); }

After the file is downloaded successfully, you can view it in the /Huawei/Drive/DownLoad/ directory.

Follow-up

In your Android Studio, click Run. Select your mobile phone as the target, and click OK to run the Drive demo on the mobile phone. The following page will display.

Downloading the Drive Sample Code

You can download the Drive sample code used in this codelab, from the following address:

Download

Well done. You have successfully developed your first app using Drive Kit!

In this codelab, you have learned:

You have now learned all of the key operations required to create an app that uses Drive Kit.

What Else You Can Do

You can read the following code snippets:

For more information, please click the following link:

Documentation

Code copied