快速入门

最后更新时间:2021-07-12 14:09:15

    相关资源

    说明:

    如果您在使用 XML 版本 SDK 时遇到函数或方法不存在等错误,请先将 XML 版本 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 的权限。