全部產品
Search
文件中心

Object Storage Service:Android斷點續傳上傳

更新時間:Feb 28, 2024

在無線網路下,上傳較大的檔案期間長,可能會遇到因為網路條件差、使用者切換網路等原因導致上傳中途失敗,整個檔案需要重新上傳。為此,Android SDK提供了斷點續傳上傳功能。

使用說明

Android SDK提供了resumableUpload以及sequenceUpload兩種方法用於斷點續傳上傳。

  • (推薦)resumableUpload表示並發上傳分區,即同時支援最多5個分區並發上傳。

  • sequenceUpload表示順序上傳分區,即上一個分區上傳完成後開始上傳下一個分區。

以下範例程式碼僅提供通過resumableUpload的方法斷點續傳上傳。如果您希望通過斷點續傳的方式上傳多個檔案或視頻,需建立多個ResumableUploadRequest。

注意事項

使用本文樣本前您需要先通過自訂網域名、STS等方式建立OSSClient,具體請參見如何初始化Android端OSSClient執行個體

對於移動端而言,如果不是大檔案(例如小於5 GB的檔案),不建議使用斷點續傳的方式上傳。斷點續傳上傳是通過分區上傳實現的,上傳單個檔案需要進行多次網路請求,效率不高。對於通過斷點續傳的方式上傳大於5 GB的檔案時:

  • 斷點續傳上傳前

    通過斷點續傳上傳的方式將檔案上傳到OSS前,您可以指定斷點記錄的儲存檔案夾。斷點續傳上傳僅在本次上傳生效。

    • 如果未指定斷點記錄的儲存檔案夾,假設某個分區因為網路原因等導致檔案上傳失敗時,將耗用大量的重試時間及流量來重新上傳整個大檔案。

    • 如果指定了斷點記錄的儲存檔案夾,在檔案上傳失敗時,將從斷點記錄處繼續上傳未上傳完成的部分。

  • 斷點續傳上傳時

    • 斷點續傳上傳僅支援上傳本地檔案。斷點續傳上傳支援上傳回調,使用方法與常見的上傳回調類似。具體操作,請參見Callback

    • 斷點續傳上傳依賴InitMultipartUploadUploadPartListPartsCompleteMultipartUploadAbortMultipartUpload等介面來實現。如果您需要通過STS鑒權模式來使用斷點續傳上傳,則需要保證您擁有訪問以上API介面的許可權。

    • 斷點續傳上傳預設已開啟每個分區上傳時的MD5校正,因此無需在請求中設定Content-Md5頭部。

    • 如果同一任務一直未完成續傳,可能會在OSS上積累無用的片段。此時,您可以為Bucket設定生命週期規則來定時清理片段。具體操作,請參見生命週期管理

範例程式碼

您可以通過同步或者非同步方式斷點續傳上傳本地檔案到OSS。

同步的方式

以下代碼以同步的方式斷點續傳上傳examplefile.txt檔案到目標儲存空間examplebucket中exampledir目錄下的exampleobject.txt檔案,並將斷點記錄檔案儲存到本地。

// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
// 填寫檔案完整路徑,例如/storage/emulated/0/oss/examplefile.txt。
String localFilepath = "/storage/emulated/0/oss/examplefile.txt";

String recordDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/oss_record/";

File recordDir = new File(recordDirectory);

// 確保斷點記錄的儲存檔案夾已存在,如果不存在則建立斷點記錄的儲存檔案夾。
if (!recordDir.exists()) {
    recordDir.mkdirs();
}

// 建立斷點續傳上傳請求,並指定斷點記錄檔案的儲存路徑,儲存路徑為斷點記錄檔案的絕對路徑。
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, localFilepath, recordDirectory);
// 調用OSSAsyncTask cancel()方法時,設定DeleteUploadOnCancelling為false,表示不刪除斷點記錄檔案,下次再上傳同一個檔案時將從斷點記錄處繼續上傳。如果不設定此參數,則預設值為true,表示刪除斷點記錄檔案,下次再上傳同一個檔案時則重新上傳。
request.setDeleteUploadOnCancelling(false);
// 設定上傳回調。
request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
    @Override
    public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
        Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
    }
});


ResumableUploadResult uploadResult = oss.resumableUpload(request);

對於Android10及之後版本的分區儲存,您可以使用檔案的Uri上傳檔案到OSS。

// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";

String recordDirectory = getApplication().getFilesDir().getAbsolutePath() + "/oss_record/";

File recordDir = new File(recordDirectory);

// 確保斷點記錄的儲存檔案夾已存在,如果不存在則建立斷點記錄的儲存檔案夾。
if (!recordDir.exists()) {
    recordDir.mkdirs();
}

// 建立斷點續傳上傳請求,並指定斷點記錄檔案的儲存路徑,儲存路徑為斷點記錄檔案的絕對路徑。
// 這裡參數"fileUri"需要填入檔案的實際Uri值。
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, fileUri, recordDirectory);
// 調用OSSAsyncTask cancel()方法時,設定DeleteUploadOnCancelling為false,表示不刪除斷點記錄檔案,下次再上傳同一個檔案時將從斷點記錄處繼續上傳。如果不設定此參數,則預設值為true,表示刪除斷點記錄檔案,下次再上傳同一個檔案時則重新上傳。
request.setDeleteUploadOnCancelling(false);
// 設定上傳回調。
request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
    @Override
    public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
        Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
    }
});


ResumableUploadResult uploadResult = oss.resumableUpload(request);

如果在斷點續傳上傳時無需將斷點記錄檔案儲存到本地,範例程式碼如下:

// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
// 填寫檔案完整路徑,例如/storage/emulated/0/oss/examplefile.txt。
String localFilepath = "/storage/emulated/0/oss/examplefile.txt";

// 建立斷點續傳上傳請求。
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, localFilepath);
// 設定上傳回調。
request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
    @Override
    public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
        Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
    }
});


ResumableUploadResult uploadResult = oss.resumableUpload(request);

非同步方式

以下代碼以非同步方式斷點續傳上傳examplefile.txt檔案到目標儲存空間examplebucket中exampledir目錄下的exampleobject.txt檔案,並將斷點記錄檔案儲存到本地。

// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
// 填寫檔案完整路徑,例如/storage/emulated/0/oss/examplefile.txt。
String localFilepath = "/storage/emulated/0/oss/examplefile.txt";
String recordDirectory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/oss_record/";

File recordDir = new File(recordDirectory);

// 確保斷點記錄的儲存路徑已存在,如果不存在則建立斷點記錄的儲存路徑。
if (!recordDir.exists()) {
    recordDir.mkdirs();
}

// 建立斷點上傳請求,並指定斷點記錄檔案的儲存路徑,儲存路徑為斷點記錄檔案的絕對路徑。
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, localFilepath, recordDirectory);
// 調用OSSAsyncTask cancel()方法時,設定DeleteUploadOnCancelling為false,表示不刪除斷點記錄檔案,下次再上傳同一個檔案時將從斷點記錄處繼續上傳。如果不設定此參數,則預設值為true,表示刪除斷點記錄檔案,下次再上傳同一個檔案時則重新上傳。
request.setDeleteUploadOnCancelling(false);
// 設定上傳過程回調。
request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
    @Override
    public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
        Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
    }
});


OSSAsyncTask resumableTask = oss.asyncResumableUpload(request, new OSSCompletedCallback<ResumableUploadRequest, ResumableUploadResult>() {
    @Override
    public void onSuccess(ResumableUploadRequest request, ResumableUploadResult result) {
        Log.d("resumableUpload", "success!");
    }

    @Override
    public void onFailure(ResumableUploadRequest request, ClientException clientExcepion, ServiceException serviceException) {
        // 異常處理。
    }
});

// 等待完成斷點上傳任務。
resumableTask.waitUntilFinished();                

對於Android10及之後版本的分區儲存,您可以使用檔案的Uri上傳檔案到OSS。

// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
String recordDirectory = getApplication().getFilesDir().getAbsolutePath() + "/oss_record/";

File recordDir = new File(recordDirectory);

// 確保斷點記錄的儲存檔案夾已存在,如果不存在則建立斷點記錄的儲存檔案夾。
if (!recordDir.exists()) {
    recordDir.mkdirs();
}

// 建立斷點續傳上傳請求,並指定斷點記錄檔案的儲存路徑,儲存路徑為斷點記錄檔案的絕對路徑。
// 這裡參數"fileUri"需要填入檔案的實際Uri值。
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, fileUri, recordDirectory);
// 調用OSSAsyncTask cancel()方法時,設定DeleteUploadOnCancelling為false時,表示不刪除斷點記錄檔案,下次再上傳同一個檔案時將從斷點記錄處繼續上傳。如果不設定此參數,則預設值為true,表示刪除斷點記錄檔案,下次再上傳同一個檔案時則重新上傳。
request.setDeleteUploadOnCancelling(false);
// 設定上傳回調。
request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
    @Override
    public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
        Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
    }
});


OSSAsyncTask resumableTask = oss.asyncResumableUpload(request, new OSSCompletedCallback<ResumableUploadRequest, ResumableUploadResult>() {
    @Override
    public void onSuccess(ResumableUploadRequest request, ResumableUploadResult result) {
        Log.d("resumableUpload", "success!");
    }

    @Override
    public void onFailure(ResumableUploadRequest request, ClientException clientExcepion, ServiceException serviceException) {
        // 異常處理。
    }
});

// 等待完成斷點上傳任務。
resumableTask.waitUntilFinished();

如果在斷點續傳上傳時無需將斷點記錄檔案儲存到本地,範例程式碼如下:

// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampledir/exampleobject.txt";
// 填寫檔案完整路徑,例如/storage/emulated/0/oss/examplefile.txt。
String localFilepath = "/storage/emulated/0/oss/examplefile.txt";

// 建立斷點上傳請求。
ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectName, localFilepath);

// 設定上傳過程回調。
request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
    @Override
    public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
        Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
    }
});
// 非同步呼叫斷點上傳。
OSSAsyncTask resumableTask = oss.asyncResumableUpload(request, new OSSCompletedCallback<ResumableUploadRequest, ResumableUploadResult>() {
    @Override
    public void onSuccess(ResumableUploadRequest request, ResumableUploadResult result) {
        Log.d("resumableUpload", "success!");
    }

    @Override
    public void onFailure(ResumableUploadRequest request, ClientException clientExcepion, ServiceException serviceException) {
        // 異常處理。
    }
});

// 等待完成斷點上傳任務。
resumableTask.waitUntilFinished();                     

相關文檔