Android 如何使用亚马逊 S3实现文件的断点续传

1.集成android 开发环境

implementation 'com.amazonaws:aws-android-sdk-s3:2.17.1'

目前这个版本是最新的

2.s3 服务端的相关数据,注册时都会给到.有两种方式使用S3,一种是直接使用是直接使用s3的服务,一种就是像我们这样,直接部署的.

 

private String accessKeyId;    注册后就会有
private String secretAccessKey;   注册后就会有
private String sessionToken;    //token 这个可有可无,但是无门是不许要的,否则会权限拒绝错误
private String bucket;   //桶 这个就是具体的数据存放地,是一个虚拟的地址
private String endpoint;   //服务器地址
private String uploadPath;
private String expiration;

这是我们服务端给到的数据.

3.代码集成 这个比较坑,找了很久,没有找到相关具体的api 文档,从网上也没有找到好的文章,只找到了几个关键类,所以我基本上把相关的源码都看了一遍,折腾了好久才搞好,本质代码不多.

   1.创建s3 客户端

      

private AWSCredentials getS3Credentials() {
        AWSCredentials sessionCredentials = new BasicSessionCredentials (
                relayUploadBean.getAccessKeyId (),
                relayUploadBean.getSecretAccessKey (),
                relayUploadBean.getSessionToken ());
        return sessionCredentials;

    }

 这里也可以是两个函数创建的AWSCredentials ,根据也许来,有token 的原因是建立失效机制,

public AmazonS3 getS3Cline() {
        if (amazonS3Cline == null) {
            amazonS3Cline = new AmazonS3Client (new MYAWSCredentialsProvider (), new ClientConfiguration ());
            amazonS3Cline.setEndpoint ("https://" + relayUploadBean.getEndpoint ());
        }
        Log.d (TAG, "getS3Cline: " + relayUploadBean.toString ());
        return amazonS3Cline;
    }

创建 TransferUtility 类,这个类是关键,他自动帮我们实现了上传的分片机制,建议看下源码,

public TransferUtility getTransferUtility() {
        TransferUtility sTransferUtility = null;
        try {
            sTransferUtility = TransferUtility.builder ()
                    .s3Client (getS3Cline ())
                    .context (BaseApplication.mContext)
                    .build ();
        } catch (Exception e) {
            e.printStackTrace ();
        }
        return sTransferUtility;
    }

 然后就是开始上传了,我用的是这个方法

public TransferObserver upload(String bucket, String key, File file) {
        return upload(bucket, key, file, new ObjectMetadata());
    }

三个参数因该比较好理解,bucket 是桶名,但是我们自建的是比较怪的,用的是路径,但是无所谓,只要最后s3 帮我们拼的全路径是我们服务器的地址就好,key :一般用文件名 ,然后传入一个file 就可以了.

TransferObserver 是返回的一个类,通过他我们可以监听文件的上传进度
transferObserver.setTransferListener (transferListener);
public interface TransferListener {
    /**
     * Called when the state of the transfer is changed.
     *
     * @param id The id of the transfer record.
     * @param state The new state of the transfer.
     */
    public void onStateChanged(int id, TransferState state);

    /**
     * Called when more bytes are transferred.
     *
     * @param id The id of the transfer record.
     * @param bytesCurrent Bytes transferred currently.
     * @param bytesTotal The total bytes to be transferred.
     */
    public void onProgressChanged(int id, long bytesCurrent, long bytesTotal);

    /**
     * Called when an exception happens.
     *
     * @param id The id of the transfer record.
     * @param ex An exception object.
     */
    public void onError(int id, Exception ex);
}

这里返回的id  是整个资源的唯一标示,建议存到数据库中,后边会用到.

TransferState 返回了当前资源的状态,是一个枚举类.

long bytesCurrent, long bytesTotal 分别代表上传大小和源文件大小

int progress = (int) (((double) bytesCurrent / (double) bytesTotal) * 100);

这样就拿到了当前就进度, 直接。  progress % 就可以了.

 

关于暂停.开始与状态检查

TransferObserver transferObserver = sTransferUtility.getTransferById (resId);

这里的resId 就是我上边说的id,s3 本身实现了一套数据库他保存了对应id 的信息,包括上传进度,状态等等.

当app 暴力推出或者暂停时都可以使用它来判断.

if (transferObserver != null) {
                TransferState transferState = transferObserver.getState ();
                Log.d (TAG, "upload: 获取历史记录" + transferState.name ());
                if (transferState.equals (TransferState.FAILED)) {
                    Log.d (TAG, "upload: 失败了,重新开始");
                    transferObserver = sTransferUtility.upload (finalPath, file.getName (), file);
                } else if (transferState.equals (TransferState.IN_PROGRESS)) {
                    if (sTransferUtility.pause (resId)) {
                        Log.d (TAG, "upload: 进行中  暂停后重新开始");
                        transferObserver = sTransferUtility.resume (resId);
                    }
                } else if (transferState.equals (TransferState.COMPLETED)) {
                    Log.d (TAG, "upload: 已经完成了" + resId);
                    transferListener.onStateChanged (resId,transferState);
                } else {
                    transferObserver = sTransferUtility.resume (resId);
                    Log.d (TAG, String.format ("upload: 正在上传中无需重复 恢复:  total: %d, current: %d",
                            transferObserver.getBytesTransferred (), transferObserver.getBytesTotal ()));
                }

就这么多.

主要就三个方法

resume(int id)  恢复开始
pause (int id) 暂停
upload(String bucket, String key, File file)。 开始上传
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值