Check progress for Upload & Download (Google Drive API for Android or Java)
Asked Answered
T

3

21

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

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

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

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) 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) 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 Error:

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)
Thelma answered 27/11, 2012 at 8:30 Comment(1)
it is working now IF I set the size at multiply of 2, for example: 10*1024*1024. Previously I get error because I am using 1000000.Thelma
C
14

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

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

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!

Coop answered 25/12, 2012 at 14:11 Comment(2)
Unable to find this Interface MediaHttpUploaderProgressListener in Android.Folium
Thanks for confirming my instinct about non-chunked uploading not supporting progress feedbackMixed
C
3

With regards to the chunk size, it must be a multiple of the MediaHttpUploader.MINIMUM_CHUNK_SIZE which is why it errored out with your previous value.

Couchman answered 18/7, 2013 at 0:12 Comment(0)
C
0

A slightly different approach with the CloudRail SDK instead of the original one. The following ProgressInputStream can be used for upload and download progress indication.

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.

Cenobite answered 7/3, 2017 at 18:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.