Android客戶端實現七牛雲存儲文件上傳

1.簡單文件上傳  上傳模型以下。

image

   1.1得到Token

           無論是簡單文件上傳,仍是分片上傳、斷點續傳 都須要首先訪問服務器,以得到上傳憑證信息Token.。用於測試時,能夠用本地模擬Token信息(有安全隱患,容易形成數據和空間數據危險)本地模擬Token信息 1.2《本地模擬Token》html

    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,採用簡單文件上傳模式。從回調中得到上傳最後信息,是失敗或者是成功。android

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

回調參數說明: api

      參數 說明
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 實現。 dom

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對象。ide

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:這裏:ui

相關代碼:

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 + "\r\n";
        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() + "  \r\n可到" + 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());
            }
        });
    }
相關文章
相關標籤/搜索