Проверьте прогресс для загрузки и загрузки (API для Google Диска для Android или Java)
Как проверить ход загрузки, использующего API GoogleDrive?
service.files(). insert (body, mediaContent).execute(); возвращает только файл, который мы можем проверить, полностью ли загружен файл.
Но мне нужно проверить прогресс в реальном времени (по крайней мере каждую секунду или около того), чтобы все это сделать?
И для части загрузки, я думаю, мы можем вручную сравнить количество байтов, которые мы уже прочитали из входного потока, в общий размер файла, а затем вычислить текущий прогресс.
Но верно ли это? Или есть другой лучший способ проверить прогресс?
private void saveFileToDrive() {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
// File binary content
java.io.File fileContent = new java.io.File(fileUri.getPath());
FileContent mediaContent = new FileContent("image/jpeg", fileContent);
// File 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: Используя этот код 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) Возобновляемая загрузка намного медленнее, чем одиночная загрузка, потому что она останавливается много раз между ними, только посылая 1 МБ каждый раз.
Если я установлю chunksize на более высокий, то он вообще не покажет прогресс для более мелкого файла.
Таким образом, прогресс в возобновляемой загрузке - это не то, что я действительно хочу. Я хочу прогресс в одиночной загрузке.
2) Если я установил chunksize около 1 МБ, моя загрузка всегда выйдет из строя примерно на 70% для обычного 10 МБ файла.
Если я установлю 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)
Ответы
Ответ 1
Продвинутый слушатель:
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
Прямая загрузка мультимедиа будет загружать весь мультимедийный контент одним запросом, в отличие от возобновляемого протокола массовой загрузки, который может загружаться в несколько запросов.
Выполнение прямой загрузки уменьшает количество HTTP-запросов, но увеличивает сбой отказов при большой загрузке мультимедиа (например, отказ соединения).
Из-за архитектуры библиотеки вам нужно выбирать между куском и прогрессом или одним шагом без прогресса.
Наименьший размер Chunk должен улучшить ситуацию.
Меньший возможный фрагмент:
setChunkSize(MediaHttpUploader.MINIMUM_CHUNK_SIZE)
Надеюсь, что это поможет!
Ответ 2
Что касается размера куска, он должен быть кратным MediaHttpUploader.MINIMUM_CHUNK_SIZE, поэтому он ошибся с вашим предыдущим значением.
Ответ 3
Несколько иной подход с 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);
}
}
Полный учебник можно найти здесь.