简介

HMS Core Drive SDK(简称Drive)允许您创建使用华为云空间服务的应用程序,华为云空间服务可以为您的应用提供云端存储功能,让用户在使用您开发的应用时产生的文件保存到云盘,也可以下载和同步在云盘中的所有文件,包括照片、视频、以及文档等。同时云盘为各类数据提供了全方位的安全保障,让用户更安全、便捷地管理数据。
当前HUAWEI Drive Kit的核心能力包括文件的上传、下载和搜索,以及云端文件变化查询、推送通知功能等。

您将建立什么

在这个Codelab中,您将创建出一款可以使用华为云空间服务功能的Android应用程序,可以通过华为HMS Core Drive SDK方便快捷管理、编辑云盘上的文件,也可以在云盘上保存照片、绘图、录音、视频和各类设计作品。用户可以在其他智能手机、平板电脑或计算机上使用华为云盘中的文件。

您将会学到什么

您需要什么

硬件要求

软件要求

集成HUAWEI HMS能力,需要完成以下准备工作

具体操作,请按照《HUAWEI HMS Core集成准备》中详细说明来完成。

开通相关服务

点击"开发"-"概览"-"API管理",进入服务管理菜单。

打开"HUAWEI Drive"和"HUAWEI Account"服务开关。

添加配置文件

添加当前应用的agconnect-services.json配置文件

  1. 打开华为开发者联盟 AppGallery Connect应用管理中之前创建的应用,并选择"开发->概览",点击数据存储位置设置按钮。
  2. 根据应用实际情况,设置对应数据存储位置,然后点击确认按钮
  3. 下载应用中的"agconnect-services.json"。
  4. 将下载的"agconnect-services.json"文件移至Android Studio开发工程app的根目录下

添加SDK依赖。

1.打开应用级的build.gradle文件。

2.在"dependencies "中添加如下编译依赖。

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

3.重新打开修改完的build.gradle文件,右上方出现Sync Now链接。点击"Sync Now"等待同步完成。

4.多语言设置。

● 如果您的应用不需要设置只支持某些特定语言,则请忽略本步骤。应用将默认支持所有HMS SDK支持的语言。

● 如果您的应用需要设置只支持某些特定语言,则可通过本步骤配置。

打开应用级根目录的build.gradle文件。

android->defaultConfig中新增resConfigs配置,en(英语) 和 zh-rCN(简体中文)为必须配置的语种,配置格式如下:

android { defaultConfig { ... resConfigs "en", "zh-rCN", "需要支持的其他语言" } }

配置混淆脚本

开发者编译APK前需要配置不要混淆HMS SDK,避免功能异常。

1.打开Android工程的混淆配置文件app/proguard-rules.pro,

2.加入排除HMS SDK的混淆配置。

-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.如果开发者使用了AndResGuard,需要在混淆配置文件中加入AndResGuard白名单。

"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*"

登录华为账号

处理login的按钮事件

通过HMS SDK登陆时,需要设置Drive Scope,用于获取访问Drive接口的权限:

private void driveLogin() { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); List<Scope> scopeList = new ArrayList<>(); scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE)); //所有权限,除了应用文件夹权限 scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_READONLY)); // 只允许查看文件内容和元数据 scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_FILE)); //允许查看和管理文件 scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_METADATA)); //允许查看和管理文件元数据,但不包括文件实体 scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_METADATA_READONLY)); //只允许查看文件元数据,但不包括文件实体 scopeList.add(new Scope(DriveScopes.SCOPE_DRIVE_APPDATA)); //支持APP数据上传和存储 scopeList.add(HuaweiIdAuthAPIManager.HUAWEIID_BASE_SCOPE); // 账号基本权限 HuaweiIdAuthParams authParams = new HuaweiIdAuthParamsHelper(DEFAULT_AUTH_REQUEST_PARAM) .setAccessToken() .setIdToken() .setScopeList(scopeList) .createParams(); // 调用账号接口, 获取信息 HuaweiIdAuthService client = HuaweiIdAuthManager.getService(this, authParams); startActivityForResult(client.getSignInIntent(), REQUEST_SIGN_IN_LOGIN); }

不同的DriveScope对应不同的权限, 第三方开发者可以根据自己的业务需要申请对应权限,API的使用详见《华为账号服务开发者文档》,如果用户未登陆华为账号,HMS SDK会引导用户登陆。

// 账号信息获取时的异常流程, 在该函数获取并保存拿到相关的accessToken和unionID @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); } }); }

调用Files.create接口创建目录及上传文件

接口说明

接口名:

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

接口描述:
用于创建文件和文件夹, 具体接口使用详见《华为云空间服务开发者文档》。

设置读写权限

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" />

在MainActivity.java 的oncreate函数添加权限申请。

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); }

加上申请权限的代码片段。

处理upload按钮事件

在用户云盘根目录创建一个新目录文件夹, 然后将输入框中指定目录下的文件上传到该新建目录。

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"); // 创建文件夹 File file = new File(); file.setFileName("somepath" + System.currentTimeMillis()) .setMimeType("application/vnd.huawei-apps.folder") .setAppSettings(appProperties); directoryCreated = drive.files().create(file).execute(); // 上传文件 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 "*/*"; }

创建成功后可以通过文件管理登录云盘查看新上传的文件。

调用Files.list接口根据文件名称查询文件详细信息

接口说明

public List list() throws java.io.IOException

处理query按钮事件

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(); }

调用Files.Get接口下载文件

接口说明

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

处理download按钮事件

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(); }

下载文件成功后,可以在文件管理/Huawei/Drive/DownLoad/目录下查看下载的文件。

Drive服务示例代码运行效果

在Android Studio中,单击"运行"。然后,选择您的设备作为目标,然后单击"确定"以在设备上启动示例应用程序。程序运行界面如下:

下载Drive服务示例代码

您可以直接下载Drive服务示例代码,进行Drive服务开发体验。

源码下载

祝贺您,您已经成功地构建了您的第一个Drive服务应用程序!

您学习了如何使用Drive SDK的相关知识,并学习了如何创建属于您自己的Drive服务应用程序。您学习了如何在Android Studio中运行Drive Demo程序。

现在,您知道了创建华为云空间服务应用的所有关键操作。

接下来您可以

看看这些代码片段...

您可以阅读下面链接,了解更多相关的信息。

相关文档

已复制代码