1

I'm using this method to download a file from Google Drive.

My code:

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        driveService.files().export(remoteFiles[0].getId(),"text/plain").executeMediaAndDownloadTo(byteArrayOutputStream);


        FileOutputStream fileOutputStream= new FileOutputStream(new File(downloadsDirectory,remoteFiles[0].getName()));


        byteArrayOutputStream.writeTo(fileOutputStream);

        byteArrayOutputStream.flush();

        byteArrayOutputStream.close();
        fileOutputStream.close();

Is there a way to get the progress of the file download?

cgifox
  • 639
  • 11
  • 23

2 Answers2

4

Answering my own question,found it on this page.

//custom listener for download progress
class DownloadProgressListener implements MediaHttpDownloaderProgressListener{


    @Override
    public void progressChanged(MediaHttpDownloader downloader) throws IOException {
        switch (downloader.getDownloadState()){

            //Called when file is still downloading
            //ONLY CALLED AFTER A CHUNK HAS DOWNLOADED,SO SET APPROPRIATE CHUNK SIZE
            case MEDIA_IN_PROGRESS:
                //Add code for showing progress
                break;
            //Called after download is complete
            case MEDIA_COMPLETE:
                //Add code for download completion
                break;
         }
    }
}


//create a Drive.Files.Get object,
//set a ProgressListener
//change chunksize(default chunksize seems absurdly high)
Drive.Files.Get request = driveService.files().get(remoteFiles[0].getId());
request.getMediaHttpDownloader().setProgressListener(new DownloadProgressListener()).setChunkSize(1000000);
request.executeMediaAndDownloadTo(outputStream);
cgifox
  • 639
  • 11
  • 23
  • thanks, for the answer, by the way, how do you define : setChunkSize(1000000) ? – Noor Hossain Dec 16 '20 at 21:22
  • as soon as I do this, the speed drops very much and I get "java.net.SocketTimeoutException: timeout", What could be the reason ? – Andrey Lehan Feb 09 '21 at 20:49
  • It is very strange why the speed drops so much when there is a listener, but changing the TimeOut solved the problem https://stackoverflow.com/questions/13026613/how-to-avoid-read-timeout-when-requesting-all-files-google-drive-api – Andrey Lehan Feb 09 '21 at 21:16
0

The first thing that I can think of is wrapping the FileOutputStream in a custom Stream that overrides the write method to additionally notify a listener for the amount of bytes written. Like this:

public class ProgressOutputStream extends OutputStream {
    IProgressListener _listener;
    OutputStream _stream;
    int _position;

    public ProgressOutputStream(OutputStream stream, IProgressListener listener) {
        _stream = stream;
        _listener = listener;
    }

    @Override
    public void write(byte[] b, int offset, int len) {
        _stream.write(b, offset, len);
        _position += len;
        reportProgress();
    }

    private void reportProgress() {
        _listener.onProgressUpdate(_position);
    }

    @Override
    public void write(int b) {
        _stream.write(b);
    }
}

interface IProgressListener {
    void onProgressUpdate(int progress);
}

The rest is to know the size of the file so that you can calculate the progress in percentages in your progress listener.

stan0
  • 11,549
  • 6
  • 42
  • 59
  • How would this work? i'm calling the ByteArrayOutputStream.writeTo() method. Should i extend ByteArrayOutputStream? – cgifox Sep 07 '16 at 13:50
  • @Guest1997: https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayOutputStream.html#writeTo(java.io.OutputStream) - "Writes the complete contents of this byte array output stream to the specified output stream argument, as if by calling the output stream's write method using out.write(buf, 0, count)." – stan0 Sep 07 '16 at 14:14
  • I tried this,the progress is at 0 for a while and then suddenly jumps straight from 0 to 100%. I think what is happening is that this method is measuring writing-to-disk instead of the actual download.I think the data is downloaded to the bytearrayoutputstream in the 2nd line of the snippet in the question – cgifox Sep 07 '16 at 17:52
  • Then maybe wrap the ByteArray stream @Guest1997 – stan0 Sep 07 '16 at 18:11