zoukankan      html  css  js  c++  java
  • Android客户端实现七牛云存储文件上传

    1.简单文件上传  上传模型如下。

    image

       1.1获得Token

               不管是简单文件上传,还是分片上传、断点续传 都需要首先访问服务器,以获得上传凭证信息Token.。用于测试时,可以用本地模拟Token信息(有安全隐患,容易造成数据和空间数据危险)本地模拟Token信息 1.2《本地模拟Token》

        1.1.1本地模拟Token.  

    /**
         * 获取token 本地生成
         * 
         * @return
         */
        private String getToken() {
            Mac mac = new Mac(QiNiuConfig.QINIU_AK, QiNiuConfig.QINIU_SK);
            PutPolicy putPolicy = new PutPolicy(QiNiuConfig.QINIU_BUCKNAME);
            putPolicy.returnBody = "{"name": $(fname),"size": "$(fsize)","w": "$(imageInfo.width)","h": "$(imageInfo.height)","key":$(etag)}";
            try {
                String uptoken = putPolicy.token(mac);
                System.out.println("debug:uptoken = " + uptoken);
                return uptoken;
            } catch (AuthException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }

       1.2简单文件实现上传(参考七牛官方文档)

    小于4M,采用简单文件上传模式。从回调中获得上传最后信息,是失败或者是成功。

    data = <File对象、或 文件路径、或 字节数组>
    String key = <指定七牛服务上的文件名,或 null>;
    String token = <从服务端SDK获取>;
    UploadManager uploadManager = new UploadManager();
    uploadManager.put(data, key, token,
    new UpCompletionHandler() {
        @Override
        public void complete(String key, ResponseInfo info, JSONObject response) {
            Log.i("qiniu", info);
        }
    }, null);

    回调参数说明:

          参数 说明
    key 即uploadManager.put(file, key, …)方法指定的key。key 指定存储在云服务器上的文件名字。并会通过返回值返回出来。
    info http请求的状态信息等,可记入日志。isOK()返回 true表示上传成功。
    response 七牛反馈的信息。可从中解析保存在七牛服务的key等信息,具体字段取决于上传策略的设置。

    1.2.1 记录上传进度  (参考七牛官方文档)

    用与进度显示。更新UI进度操作。

    uploadManager.put(data, key, token,handler,
        new UploadOptions(null, null, false,
            new UpProgressHandler(){
                public void progress(String key, double percent){
                    Log.i("qiniu", key + ": " + percent);
                }
            }, null));

    注:progress(key, percent)中的key 即uploadManager.put(file, key, …)方法指定的key

    1.2.2取消上传

    设置标志位,可以取消上传操作。直接覆盖uploadManager,最后一个上传参数。

    private volatile boolean isCancelled;
    ...
    // 某方法中执行取消:isCancelled = true;
    ...
    uploadManager.put(data, key, token,handler,
        new UploadOptions(null, null, false, progressHandler,
            new UpCancellationSignal(){
                public boolean isCancelled(){
                    return isCancelled;
                }
            }));

    1.2.3记录断点

    分片上传中,可将各个已上传的块记录下来,再次上传时,已上传的部分不用再次上传。 断点记录类需实现 com.qiniu.android.storage.Recorder 接口。已提供保存到文件的 FileRecorder 实现。

    String dirPath = <断点记录文件保存的文件夹位置>
    FileRecorder fr = new FileRecorder(dirPath)
    UploadManager uploadManager = new UploadManager(fr);
    uploadManager.put(data, key, ...)
    
    //默认使用 key 的url_safe_base64编码字符串作为断点记录文件的文件名。避免记录文件冲突(特别是key指定为null时),也可自定义文件名:
    
    UploadManager uploadManager = new UploadManager(fr, new KeyGenerator(){
        public String gen(String key, File file){
            // 不必使用url_safe_base64转换,uploadManager内部会处理
            // 该返回值可替换为基于key、文件内容、上下文的其它信息生成的文件名
            return key + file.getName();
        }
    });

    2.分片文件上传

    2.1官方相关概念

      image

    image

    2.2分片上传相关代码例子 (Demo这里)

    得到要上传的文件信息转化为Upload对象。

    private void preUpload(Uri uri) {
            // 此参数会传递到回调
            String passObject = "test: " + uri.getEncodedPath() + "passObject";
    
            String qiniuKey = UUID.randomUUID().toString();
            PutExtra extra = null;
    
            Upload up = UpApi.build(getAuthorizer(), qiniuKey, uri, this, extra, passObject, uploadHandler);
            addUp(up);
        }

    执行上传操作,UpApi.execuete(up)会根据文件大小,执行分块上传文件操作。

    private synchronized void doUpload() {
            System.out.println("doup: 启动上传任务");
            for (Upload up : ups) {
                if (UpApi.isSliceUpload(up)) {
                    String sourceId = generateSourceId(up.getUpParam(), up.getPassParam());
                    List<Block> bls = null;
                    try {
                        bls = load(sourceId);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    // 设置以前上传的断点记录。 直传会忽略此参数
                    up.setLastUploadBlocks(bls);
                }
                // UpApi.execute(up, bls);
                Executor executor = UpApi.execute(up);
                executors.add(executor);
            }
            System.out.println("doup: 启动上传任务完毕");
            start = System.currentTimeMillis();
        }

    3断点续传

    参考Demo:这里:

    相关代码:

    public void doResumableUpload(final Uri uri, PutExtra extra) {
            uploadUri = uri;
            final MyBlockRecord record = MyBlockRecord.genFromUri(this, uri);
    
            tvUploadInfo.setText("连接中");
            String key = null;
            if (extra != null) {
                extra.params = new HashMap<String, String>();
                extra.params.put("x:a", "bb");
            }
            List<Block> blks = record.loadBlocks();
            String s = "blks.size(): " + blks.size() + " ==> ";
            for (Block blk : blks) {
                s += blk.getIdx() + ", ";
            }
            final String pre = s + "
    ";
            uploading = true;
            executor = ResumableIO.putFile(this, auth, key, uri, extra, blks, new CallBack() {
                @Override
                public void onSuccess(UploadCallRet ret) {
                    uploading = false;
                    String key = ret.getKey();
                    String redirect = "http://" + MyActivity.bucketName + ".qiniudn.com/" + key;
                    String redirect2 = "http://" + MyActivity.bucketName + ".u.qiniudn.com/" + key;
                    tvUploadInfo.setText(pre + "上传成功! ret: " + ret.toString() + "  
    可到" + redirect + " 或  " + redirect2 + " 访问");
                    record.removeBlocks();
                    clean();
                }
    
                @Override
                public void onProcess(long current, long total) {
                    int percent = (int) (current * 100 / total);
                    tvUploadInfo.setText(pre + "上传中: " + current + "/" + total + "  " + current / 1024 + "K/" + total / 1024 + "K; "
                            + percent + "%");
                    // int i = 3/0;
                    progressBar.setProgress((int) percent);
                }
    
                @Override
                public void onBlockSuccess(Block blk) {
                    record.saveBlock(blk);
                }
    
                @Override
                public void onFailure(CallRet ret) {
                    uploading = false;
                    clean();
                    tvUploadInfo.setText(pre + "错误: " + ret.toString());
                }
            });
        }
  • 相关阅读:
    Windows SDK 之 mciSendString最后一个参数
    java常用包下载地址(非maven)
    windows api(GDI)实现图片旋转
    windows sdk版本 之 并查集生成迷宫
    自签https证书2(适配新版chrome,不会显示“不安全”)
    数据结构——栈(Stacks)
    数据结构——表(list)
    数据结构——链表(linkedlist)
    解题报告1010 诡秘的余数
    函数体中用指针返回数组的方法
  • 原文地址:https://www.cnblogs.com/lixiaodaoaaa/p/4224651.html
Copyright © 2011-2022 走看看