控制台指南

最佳实践

开发者指南

API 文档

SDK 文档

快速入门

最近更新时间:2021-07-06 14:36:32

相关资源

说明:

如果您在使用 XML 版本 SDK 时遇到函数或方法不存在等错误,请先将 XML 版本 SDK 升级到最新版再重试。如果您仍在使用 JSON 版本 SDK,请 升级到 XML Android SDK

准备工作

  1. 您需要一个 Android 应用,这个应用可以是您现有的工程,也可以是您新建的一个空的工程。
  2. 请确保您的 Android 应用目标为 API 级别 15 (Ice Cream Sandwich) 或更高版本。
  3. 您需要一个可以获取腾讯云临时密钥的远程地址,关于临时密钥的有关说明请参考 移动应用直传实践

第一步:安装 SDK

方式一:自动集成(推荐)

说明:

bintray 仓库已经下线,COS SDK 已经迁移到 mavenCentral,引用路径和之前不同,您在更新的时候请使用新的引用路径。

使用 mavenCentral 仓库

在项目级别(通常是根目录下)的 build.gradle 中添加:

repositories {
   google()
   // 增加这行
   mavenCentral() 
}

标准版 SDK

在应用级别(通常是 app 模块下)的 build.gradle 中添加依赖:

dependencies {
...
   // 增加这行
   implementation 'com.qcloud.cos:cos-android:5.6.+'
}

如果您的项目中使用 kotlin 开发,可以添加我们的 ktx 扩展包,提供了更加友好的 API:

dependencies {
...
   // 增加这行
   implementation 'com.qcloud.cos:cos-ktx:5.6.+'
}

精简版 SDK

在应用级别(通常是 app 模块下)的 build.gradle 中添加依赖:

dependencies {
...
   // 增加这行
   implementation 'com.qcloud.cos:cos-android-lite:5.6.+'
}

关闭 beacon 上报功能(适用于5.5.8以及以上版本)

为了持续跟踪和优化 SDK 的质量,给您带来更好的使用体验,我们在 SDK 中引入了 beacon 分析。

若是想关闭该功能,请在应用级别(通常是 app 模块下)的 build.gradle 中添加去掉 beacon 的语句:

dependencies {
...
  implementation ('com.qcloud.cos:cos-android:x.x.x'){
      // 增加这行
      exclude group: 'com.tencent.qcloud', module: 'beacon-android-release'
  }
}

方式二:手动集成

1. 下载归档文件

您可以通过 快速下载地址 下载最新的正式包,也可以在 SDK Releases 里面找到我们所有历史版本的正式包。

下载完成并解压后,您可以看到里面包含了数个 jaraar 包。下面是对它们的简单说明,请根据需要选择集成的包。

必选的库:

  • cosxml:COS 协议实现
  • qcloud-foundation:基础库
  • bolts-tasks:第三方 Task 库
  • okhttp:第三方 Networking 库
  • okio:第三方 IO 库

可选的库:

  • beacon: beacon 移动分析,用于改进 SDK
  • LogUtils: 日志模块,用于改进 SDK
  • quic:QUIC 协议,当您使用到 QUIC 协议来传输数据时需要

2. 集成到项目中

把需要的包放到您应用模块下的 libs 文件夹下,并在应用级别(通常是 app 模块下)的 build.gradle 文件中添加如下依赖:

dependencies {
...
  // 增加这行
  implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
}

第二步:配置权限

网络权限

SDK 需要网络权限,用于与 COS 服务器进行通信,请在应用模块下的 AndroidManifest.xml 中添加如下权限声明:

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

存储权限

如果您的应用场景中需要从外部存储中读写文件,请在应用模块下的 AndroidManifest.xml 中添加如下权限声明:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
注意:

在 Android 6.0(API level 23)以上,您需要在运行时动态申请存储权限。

第三步:开始使用

1. 实现获取临时密钥

实现一个 BasicLifecycleCredentialProvider的子类,实现请求临时密钥并返回结果的过程。

public static class MySessionCredentialProvider
      extends BasicLifecycleCredentialProvider {
   @Override
  protected QCloudLifecycleCredentials fetchNewCredentials() 
          throws QCloudClientException {
       // 首先从您的临时密钥服务器获取包含了密钥信息的响应
       // 然后解析响应,获取临时密钥信息
      String tmpSecretId = "SECRETID"; // 临时密钥 SecretId
      String tmpSecretKey = "SECRETKEY"; // 临时密钥 SecretKey
      String sessionToken = "SESSIONTOKEN"; // 临时密钥 Token
      long expiredTime = 1556183496L;//临时密钥有效截止时间戳,单位是秒
       //建议返回服务器时间作为签名的开始时间,避免由于用户手机本地时间偏差过大导致请求过期
      // 返回服务器时间作为签名的起始时间
      long startTime = 1556182000L; //临时密钥有效起始时间,单位是秒
       // 最后返回临时密钥信息对象
      return new SessionQCloudCredentials(tmpSecretId, tmpSecretKey,
              sessionToken, startTime, expiredTime);
  }
}

这里假设类名为 MySessionCredentialProvider。初始化一个实例,来给 SDK 提供密钥。

QCloudCredentialProvider myCredentialProvider = new MySessionCredentialProvider();

使用永久密钥进行本地调试

您可以使用腾讯云的永久密钥来进行开发阶段的本地调试。由于该方式存在泄漏密钥的风险,请务必在上线前替换为临时密钥的方式。

String secretId = "SECRETID"; //永久密钥 secretId
String secretKey = "SECRETKEY"; //永久密钥 secretKey
// keyDuration 为请求中的密钥有效期,单位为秒
QCloudCredentialProvider myCredentialProvider = 
  new ShortTimeCredentialProvider(secretId, secretKey, 300);

2. 初始化 COS Service

使用您提供密钥的实例 myCredentialProvider,初始化一个 CosXmlService 的实例。

CosXmlService 提供了访问 COS 的所有接口,建议作为 程序单例 使用。

// 存储桶所在地域简称,例如广州地区是 ap-guangzhou
String region = "COS_REGION";
// 创建 CosXmlServiceConfig 对象,根据需要修改默认的配置参数
CosXmlServiceConfig serviceConfig = new CosXmlServiceConfig.Builder()
      .setRegion(region)
      .isHttps(true) // 使用 HTTPS 请求, 默认为 HTTP 请求
      .builder();
// 初始化 COS Service,获取实例
CosXmlService cosXmlService = new CosXmlService(context, 
  serviceConfig, myCredentialProvider);
说明:

关于存储桶不同地域的简称请参考 地域和访问域名

使用 ktx 包初始化 COS Service

如果您使用 ktx,初始化代码简化为:

val cos = cosService(context = application.applicationContext) {
   configuration {
      setRegion("ap-guangzhou")
      isHttps(true)
  }
   credentialProvider {
      lifecycleCredentialProvider {
          // fetch credential from backend
          // ...
          return@lifecycleCredentialProvider SessionQCloudCredentials(
                  "temp_secret_id",
                  "temp_secret_key",
                  "session_token",
                  1556183496
          )
      }
  }
}

第四步:访问 COS 服务

上传对象

SDK 支持上传本地文件、二进制数据、Uri 以及输入流。下面以上传本地文件为例。

// 初始化 TransferConfig,这里使用默认配置,如果需要定制,请参考 SDK 接口文档
TransferConfig transferConfig = new TransferConfig.Builder().build();
// 初始化 TransferManager
TransferManager transferManager = new TransferManager(cosXmlService,
       transferConfig);
String bucket = "examplebucket-1250000000"; //存储桶,格式:BucketName-APPID
String cosPath = "exampleobject"; //对象在存储桶中的位置标识符,即称对象键
String srcPath = new File(context.getCacheDir(), "exampleobject")
       .toString(); //本地文件的绝对路径
// 若存在初始化分块上传的 UploadId,则赋值对应的 uploadId 值用于续传;否则,赋值 null。
// 当次上传任务的 uploadid 可以在 TransferStateListener 的回调中拿到
String uploadId = null; 
// 上传文件
COSXMLUploadTask cosxmlUploadTask = transferManager.upload(bucket, cosPath,
       srcPath, uploadId);
//设置上传进度回调
cosxmlUploadTask.setCosXmlProgressListener(new CosXmlProgressListener() {
   @Override
   public void onProgress(long complete, long target) {
       // todo Do something to update progress...
   }
});
//设置返回结果回调
cosxmlUploadTask.setCosXmlResultListener(new CosXmlResultListener() {
   @Override
   public void onSuccess(CosXmlRequest request, CosXmlResult result) {
       COSXMLUploadTask.COSXMLUploadTaskResult cOSXMLUploadTaskResult =
               (COSXMLUploadTask.COSXMLUploadTaskResult) result;
   }
    @Override
   public void onFail(CosXmlRequest request,
                       CosXmlClientException clientException,
                       CosXmlServiceException serviceException) {
       if (clientException != null) {
           clientException.printStackTrace();
       } else {
           serviceException.printStackTrace();
       }
   }
});
//设置任务状态回调, 可以查看任务过程,并拿到 uploadId 用于续传
cosxmlUploadTask.setTransferStateListener(new TransferStateListener() {
   @Override
   public void onStateChanged(TransferState state) {
       // todo notify transfer state
       uploadId = cosxmlUploadTask.getUploadId();  
   }
});

使用 ktx 包上传对象

如果您使用 ktx,请参考下面的上传示例代码:

// 这里使用了 viewModel 的 ktx 扩展
// viewModelScope 是 viewmodel 自带的 coroutine scope
viewModelScope.launch {
  val `object` = cosObject {
      bucket = cosBucket {
          service = cos
          name = "examplebucket-1250000000"
      }
      key = "exampleObject"
  }
  // 本地示例文件
  val sourceFile = File(appContext.externalCacheDir, "sourceFile")
   try {
      // upload 方法是 suspend function
      val result = `object`.upload(
          localFile = sourceFile,
          progressListener = { complete, target ->
              Log.d("cosxmlktx", "upload onProgress:" +
                              " $complete / $target")
          },
          transferStateListener = { state ->
              Log.d("cosxmlktx", "upload state is : $state")
          }
      )
   } catch (e : Exception ) {
      e.printStackTrace()
  }
}
说明:

  • 更多完整示例,请前往 GitHub 查看。
  • 上传之后,您可以用同样的 Key 生成文件下载链接,具体使用方法见 生成预签名链接 文档。但注意如果您的文件是私有读权限,那么下载链接只有一定的有效期。

下载对象

// 高级下载接口支持断点续传,所以会在下载前先发起 HEAD 请求获取文件信息。
// 如果您使用的是临时密钥或者使用子账号访问,请确保权限列表中包含 HeadObject 的权限。
// 初始化 TransferConfig,这里使用默认配置,如果需要定制,请参考 SDK 接口文档
TransferConfig transferConfig = new TransferConfig.Builder().build();
//初始化 TransferManager
TransferManager transferManager = new TransferManager(cosXmlService,
       transferConfig);
String bucket = "examplebucket-1250000000"; //存储桶,格式:BucketName-APPID
String cosPath = "exampleobject"; //对象在存储桶中的位置标识符,即称对象键
//本地目录路径
String savePathDir = context.getExternalCacheDir().toString();
//本地保存的文件名,若不填(null),则与 COS 上的文件名一样
String savedFileName = "exampleobject";
Context applicationContext = context.getApplicationContext(); // application
// context
COSXMLDownloadTask cosxmlDownloadTask =
       transferManager.download(applicationContext,
       bucket, cosPath, savePathDir, savedFileName);
//设置下载进度回调
cosxmlDownloadTask.setCosXmlProgressListener(new CosXmlProgressListener() {
   @Override
   public void onProgress(long complete, long target) {
       // todo Do something to update progress...
   }
});
//设置返回结果回调
cosxmlDownloadTask.setCosXmlResultListener(new CosXmlResultListener() {
   @Override
   public void onSuccess(CosXmlRequest request, CosXmlResult result) {
       COSXMLDownloadTask.COSXMLDownloadTaskResult cOSXMLDownloadTaskResult =
               (COSXMLDownloadTask.COSXMLDownloadTaskResult) result;
   }
    @Override
   public void onFail(CosXmlRequest request,
                       CosXmlClientException clientException,
                       CosXmlServiceException serviceException) {
       if (clientException != null) {
           clientException.printStackTrace();
       } else {
           serviceException.printStackTrace();
       }
   }
});
//设置任务状态回调,可以查看任务过程
cosxmlDownloadTask.setTransferStateListener(new TransferStateListener() {
   @Override
   public void onStateChanged(TransferState state) {
       // todo notify transfer state
   }
});

使用 ktx 包下载对象

如果您使用 ktx,请参考下面的下载示例代码:

// 这里使用了 viewModel 的 ktx 扩展
// viewModelScope 是 viewmodel 自带的 coroutine scope
viewModelScope.launch {
  val `object` = cosObject {
      bucket = cosBucket {
          service = cos
          name = "examplebucket-1250000000"
      }
      key = "exampleObject"
  }
   try {
      // download 方法是 suspend function
      val result = `object`.download(
          context = appContext,
          destDirectory = appContext.externalCacheDir!!,
          progressListener = { complete, target ->
              Log.d("cosxmlktx", "download onProgress: " +
                      "$complete / $target")
          },
          transferStateListener = { state ->
              Log.d("cosxmlktx", "download state is : $state")
          }
      )
   } catch (e : Exception ) {
      e.printStackTrace()
  }
}
说明:

  • 更多完整示例,请前往 GitHub 查看。
  • 高级下载接口支持断点续传,所以会在下载前先发起 HEAD 请求获取文件信息。如果您使用的是临时密钥或者使用子账号访问,请确保权限列表中包含 HeadObject 的权限。
目录