简体   繁体   English

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

[英]Check progress for Upload & Download (Google Drive API for Android or Java)

How to check the progress of an upload that use GoogleDrive API? 如何查看使用GoogleDrive API的上传进度?

The service.files().insert(body, mediaContent).execute(); 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();
  }

EDITED: Using this code 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 已编辑:使用此代码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

I am able to get some progress now if I am using resumable upload , I set chunksize to 1MB. 如果我使用可恢复上传 ,我现在可以取得一些进展,我将chunksize设置为1MB。 BUT there are 2 problems now. 但现在有2个问题。

1) The resumable upload is much slower than single upload, because it stop many times in between, only sending 1MB each time. 1)可恢复上传比单个上传要慢得多,因为它在中间停止很多次,每次只发送1MB。
If I set chunksize to higher, then it wont show progress at all for smaller file. 如果我将chunksize设置为更高,那么它对于较小的文件根本不会显示进度。
So, progress in resumable upload is not what I actually want. 因此,可恢复上传的进展并不是我真正想要的。 I want progress in single upload. 我希望单上传进步。

2) If I set chunksize about 1MB, my upload always fail at about 70% for a normal 10MB file. 2)如果我将chunksize设置为大约1MB,那么对于正常的10MB文件,我的上传总是失败大约70%。
If I set chunksize to 10MB then it will success, but I wont see any progress. 如果我将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 Error: 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)

Progress listener: 进度监听:

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!");
        }
    }
}

More information here: https://code.google.com/p/google-api-java-client/wiki/MediaUpload 有关详情,请访问: 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 (eg connection failure). 执行直接上载可减少HTTP请求的数量,但会增加大型媒体上载(例如,连接失败)时的故障更改

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)

Hope it helps! 希望能帮助到你!

关于块大小,它必须是MediaHttpUploader.MINIMUM_CHUNK_SIZE的倍数,这就是为什么它与您之前的值出错。

A slightly different approach with the CloudRail SDK instead of the original one. 使用CloudRail SDK而不是原始SDK的方法略有不同。 The following ProgressInputStream can be used for upload and download progress indication. 以下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);
  }
}

The full tutorial can be found here . 完整的教程可以在这里找到。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM