检查上传和下载进度(适用于 Android 或 Java 的 Google Drive API)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13580109/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check progress for Upload & Download (Google Drive API for Android or Java)
提问by tcboy88
How to check the progress of an upload that use GoogleDrive API?
如何检查使用 GoogleDrive API 的上传进度?
The service.files().insert(body, mediaContent).execute();only return a filewhich we can check if the file has upload completely.
的。service.files()插入(身体,mediaContent).execute(); 只返回一个文件,我们可以检查文件是否已完全上传。
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();
}
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.
如果我使用可恢复上传,我现在可以取得一些进展,我将 chunksize 设置为 1MB。但是现在有两个问题。
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.
1)可续传上传比单次上传慢很多,因为中间会停很多次,每次只发送1MB。
如果我将 chunksize 设置为更高,那么它根本不会显示较小文件的进度。
所以,可恢复上传的进展并不是我真正想要的。我想要单次上传的进展。
2) If I set chunksize about 1MB, my upload always failat about 70% for a normal 10MB file.
If I set chunksize to 10MB then it will success, but I wont see any progress.
2) 如果我将 chunksize 设置为大约 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 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)
采纳答案by pommedeterresautee
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 requestas 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 failureswith a large media upload (e.g. 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:
由于库的架构,您必须在块和进度或没有进度的一步之间进行选择。最小的 Chunk 大小应该会有所改善。可能的小块:
setChunkSize(MediaHttpUploader.MINIMUM_CHUNK_SIZE)
Hope it helps!
希望能帮助到你!
回答by Bruce
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.
关于块大小,它必须是 MediaHttpUploader.MINIMUM_CHUNK_SIZE 的倍数,这就是它与您之前的值错误的原因。
回答by Tmm
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.
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);
}
}
The full tutorial can be found here.
完整教程可以在这里找到。