2012-11-27 75 views
13

如何檢查使用GoogleDrive API的上傳進度?檢查上傳和下載的進度(Google Drive API for Android或Java)

The service.files()。insert(body,mediaContent).execute();只返回一個文件,我們可以檢查文件是否已經完全上傳。

但我需要實時檢查進度(至少每秒左右),反正辦呢?

而對於下載的一部分,我想我們可以手動比較多少字節,我們已經從InputStream總文件大小閱讀,然後計算出當前的進度。

但這是正確的方法嗎?或者還有其他更好的方法來檢查進度?

private void saveFileToDrive() { 
    Thread t = new Thread(new Runnable() { 
     @Override 
     public void run() { 
     try { 
      // File's binary content 
      java.io.File fileContent = new java.io.File(fileUri.getPath()); 
      FileContent mediaContent = new FileContent("image/jpeg", fileContent); 

      // File's metadata. 
      File body = new File(); 
      body.setTitle(fileContent.getName()); 
      body.setMimeType("image/jpeg"); 

      File file = service.files().insert(body, mediaContent).execute(); 
      if (file != null) { 
      showToast("Photo uploaded: " + file.getTitle()); 
      //startCameraIntent(); 
      } 
     } catch (UserRecoverableAuthIOException e) { 
      startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     } 
    }); 
    t.start(); 
    } 

編輯:使用此代碼http://code.google.com/p/google-api-java-client/source/browse/drive-cmdline-sample/src/main/java/com/google/api/services/samples/drive/cmdline/DriveSample.java?repo=samples&name=based-on-1.12&r=08555cd2a27be66dc97505e15c60853f47d84b5a

我現在能夠獲得一些進步,如果我使用續傳的上傳,我設置CHUNKSIZE爲1MB。 但現在有2個問題。

1)繼續上傳比單個上傳慢得多,因爲它阻止很多次之間,每次只能發送1MB。
如果我將chunksize設置得更高,那麼對於較小的文件它就不會顯示進度。
因此,可恢復上傳的進展並不是我真正想要的。我想要單一上傳的進度。 2)如果我將大塊大小設置爲大約1MB,那麼對於正常的10MB文件,我的上傳總是失敗約爲70%。
如果我將chunksize設置爲10MB,那麼它會成功,但我不會看到任何進展。

Drive.Files.Insert insert = service.files().insert(body, mediaContent); 
MediaHttpUploader uploader = insert.getMediaHttpUploader(); 
uploader.setDirectUploadEnabled(false); 
uploader.setChunkSize(10*1024*1024); // previously I am using 1000000 thats why it won't work 
uploader.setProgressListener(new FileUploadProgressListener()); 
com.google.api.services.drive.model.File f = insert.execute(); 

logcat的錯誤:

11-27 19:23:26.927: D/FileUploadProgressListener(11527): Upload is In Progress: 0.5235538030501893 
11-27 19:23:33.692: D/FileUploadProgressListener(11527): Upload is In Progress: 0.56095050326806 
11-27 19:23:38.294: D/FileUploadProgressListener(11527): Upload is In Progress: 0.5983472034859306 
11-27 19:23:50.583: D/FileUploadProgressListener(11527): Upload is In Progress: 0.6357439037038013 
11-27 19:23:55.091: D/FileUploadProgressListener(11527): Upload is In Progress: 0.673140603921672 
11-27 19:24:05.130: D/FileUploadProgressListener(11527): Upload is In Progress: 0.7105373041395426 
11-27 19:24:17.005: D/FileUploadProgressListener(11527): Upload is In Progress: 0.7479340043574133 
11-27 19:24:28.888: D/FileUploadProgressListener(11527): Upload is In Progress: 0.785330704575284 
11-27 19:24:28.896: W/HttpTransport(11527): exception thrown while executing request 
11-27 19:24:28.896: W/HttpTransport(11527): java.io.IOException: unexpected end of stream 
11-27 19:24:28.896: W/HttpTransport(11527):  at libcore.net.http.FixedLengthOutputStream.close(FixedLengthOutputStream.java:58) 
11-27 19:24:28.896: W/HttpTransport(11527):  at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:88) 
11-27 19:24:28.896: W/HttpTransport(11527):  at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:980) 
11-27 19:24:28.896: W/HttpTransport(11527):  at com.google.api.client.googleapis.media.MediaHttpUploader.upload(MediaHttpUploader.java:293) 
11-27 19:24:28.896: W/HttpTransport(11527):  at com.google.api.services.drive.Drive$Files$Insert.executeUnparsed(Drive.java:309) 
11-27 19:24:28.896: W/HttpTransport(11527):  at com.google.api.services.drive.Drive$Files$Insert.execute(Drive.java:331) 
+0

現在運轉如果我設置的大小在2乘,例如:10 * 1024 * 1024。以前我因爲使用​​1000000而得到錯誤。 – tcboy88

回答

9

進展聽衆:

private class FileUploadProgressListener implements MediaHttpUploaderProgressListener { 

    private String mFileUploadedName; 

    public FileUploadProgressListener(String fileName) { 
     mFileUploadedName = fileName; 
    } 

    @Override 
    public void progressChanged(MediaHttpUploader mediaHttpUploader) throws IOException { 
     if (mediaHttpUploader == null) return; 
     switch (mediaHttpUploader.getUploadState()) { 
      case INITIATION_STARTED: 
      //System.out.println("Initiation has started!"); 
       break; 
      case INITIATION_COMPLETE: 
      //System.out.println("Initiation is complete!"); 
       break; 
      case MEDIA_IN_PROGRESS: 
       double percent = mediaHttpUploader.getProgress() * 100; 
       if (Ln.DEBUG) { 
        Log.d(Ln.TAG, "Upload to Dropbox: " + mFileUploadedName + " - " + String.valueOf(percent) + "%"); 
       } 
       notif.setProgress(percent, mFileUploadedName).fire(); 
       break; 
      case MEDIA_COMPLETE: 
      //System.out.println("Upload is complete!"); 
     } 
    } 
} 

點擊此處瞭解詳情: https://code.google.com/p/google-api-java-client/wiki/MediaUpload

Direct media upload will upload the whole media content in one request as opposed to the resumable media upload protocol that could upload in multiple requests.

Doing a direct upload reduces the number of HTTP requests but increases the change of failures with a large media upload (e.g. connection failure).

由於架構圖書館,你必須在大塊和進步之間做出選擇,或者一步沒有進展。 最小塊大小應該會改善。 較小的塊可能:

setChunkSize(MediaHttpUploader.MINIMUM_CHUNK_SIZE) 

希望它能幫助!

+0

無法在Android中找到此接口'MediaHttpUploaderProgressListener'。 –

+0

感謝您確認我關於不分塊上傳不支持進度反饋的直覺 – Ian

2

至於塊大小,它必須是MediaHttpUploader.MINIMUM_CHUNK_SIZE的倍數這就是爲什麼它與前值出錯了。

0

稍微不同的方法與CloudRail SDK,而不是原來的一個。以下ProgressInputStream可用於上傳和下載進度指示。

class ProgressInputStream extends InputStream { 

    private InputStream stream; 
    private ProgressListener progressListener; 
    private long offset = 0; 

    public ProgressInputStream(InputStream stream, UploadProgressListener progressListener) { 
    this.stream = stream; 
    this.progressListener = progressListener; 
    } 

    @Override 
    public int read() throws IOException { 
    int res = this.stream.read(); 
    this.progressListener.onProgressChanged(++this.offset); 

    return res; 
    } 

    @Override 
    public int read(byte[] b, int off, int len) throws IOException { 
    int res = this.stream.read(b, off, len); 
    this.offset += res; 
    this.progressListener.onProgressChanged(this.offset); 

    return res; 
    } 

    // You might need to override additional methods but you can just 
    // call the corresponding method on the stream property 

    public interface ProgressListener { 
    void onProgressChanged(long bytes); 
    } 
} 

完整的教程可以找到here