检查上传和进度下载(适用于 Android 或 Java 的 Google Drive API)

2022-01-10 00:00:00 google-drive-api android java

如何查看使用 GoogleDrive API 的上传进度?

How to check the progress of an upload that use GoogleDrive API?

service.files().insert(body, mediaContent).execute(); 只返回一个文件我们可以检查文件是否已完全上传.

The service.files().insert(body, mediaContent).execute(); only return a file which we can check if the file has upload completely.

但我需要实时检查进度(至少每秒左右),无论如何要这样做?

But I need to check the progress in real time(at least each second or so), anyway to do it?

对于下载部分,我认为我们可以手动比较我们已经从输入流中读取的字节数与总文件大小,然后计算当前进度.

And for download part, I think we can manually compare how many bytes we have already read from the inputstream to the total filesize, then calculate the current progress.

但这是正确的方法吗?还是有其他更好的检查进度的方法?

But is this the correct way? Or there is other better way of checking progress?

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=基于-1.12&r=08555cd2a27be66dc97505e15c60853f47d84b5a

如果我使用可恢复上传,我现在能够取得一些进展,我将块大小设置为 1MB.但是现在有两个问题.

I am able to get some progress now if I am using resumable upload, I set chunksize to 1MB. BUT there are 2 problems now.

1) 可恢复上传比单次上传慢很多,因为中间会停很多次,每次只发送1MB.
如果我将 chunksize 设置为更高,那么对于较小的文件,它根本不会显示进度.
所以,可恢复上传的进展并不是我真正想要的.我想要单次上传的进度.

1) The resumable upload is much slower than single upload, because it stop many times in between, only sending 1MB each time.
If I set chunksize to higher, then it wont show progress at all for smaller file.
So, progress in resumable upload is not what I actually want. I want progress in single upload.

2) 如果我将块大小设置为大约 1MB,对于一个正常的 10MB 文件,我的上传总是失败约为 70%.
如果我将 chunksize 设置为 10MB,那么它会成功,但我不会看到任何进展.

2) If I set chunksize about 1MB, my upload always fail at about 70% for a normal 10MB file.
If I set chunksize to 10MB then it will success, but I wont see any progress.

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)

推荐答案

进度监听器:

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/维基/媒体上传

直接媒体上传将在一个请求中上传整个媒体内容,而不是可以在多个请求中上传的可恢复媒体上传协议.

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.

直接上传会减少 HTTP 请求的数量,但增加失败的变化与大型媒体上传(例如连接失败).

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

由于库的架构,您必须在块和进度或没有进度的一步之间进行选择.最小的块大小应该可以改善事情.可能的更小的块:

Because of the architecture of the library, you have to choose between chunk and progress OR one step without progress. The smallest Chunk size should improve things. Smaller chunk possible:

setChunkSize(MediaHttpUploader.MINIMUM_CHUNK_SIZE)

希望对你有帮助!

相关文章