11

I have written an app using the official API to upload to Google drive, this works perfectly. However I can't find anyway to cancel an upload. I'm running it in an ASyncTask, so far I have tried making the drive object, the file path, the token and a few other variables none. I've also tried to invalidate the token however it seems this only removes it from the cache and doesn't actually invalidate it server side. I've called cancel on the ASyncTask however if it is cancelled once the upload has started there seems to be no way to stop it.

My issue is if a user starts uploading a 100mb file there's no way for them to cancel it other then turning their internet connection on and off which isn't practical. This is my upload code:

  java.io.File jFile = new java.io.File(path); //Does not get file just info
                File body = setBody(jFile, mimeType);
                try
                {
                  java.io.File mediaFile = new java.io.File(path);
                  InputStreamContent mediaContent =
                      new InputStreamContent(mimeType,
                          new BufferedInputStream(new FileInputStream(mediaFile)));
                  mediaContent.setLength(mediaFile.length());
                  request = drive.files().insert(body, mediaContent);
                  request.getMediaHttpUploader().setProgressListener(new CustomProgressListener());
                  File file = request.execute();

Surely there is a way to cancel an upload?

Claudio Cherubino
  • 14,896
  • 1
  • 35
  • 42
crazyfool
  • 1,433
  • 4
  • 22
  • 38

4 Answers4

8

Great question! I filed a feature request for the ability to cancel a media upload request:

https://code.google.com/p/google-api-java-client/issues/detail?id=671

However, this may a difficult feature to implement based on the current design of that library.

Another option to consider is to not use AsyncTask and instead implementing the multi-threading yourself and abort the running Thread. Not pleasant, but may be your only option for doing this now.

Yaniv Inbar
  • 1,409
  • 9
  • 10
2

In a comment I have said that putting the request in a thread and call interrupt is not working. So I was searching another way of doing it.

I have finally found one, an ugly one: Close the InputStream of the uploaded file!

I initialize with:

mediaContent = new InputStreamContent(NOTE_MIME_TYPE,new BufferedInputStream(new FileInputStream(fileContent)));
mediaContent.setLength(fileContent.length());

And in a stop listener I have :

IOUtils.closeQuietly(mediaContent.getInputStream());

For sure it should be possible to do it in a better way!

Regards

pommedeterresautee
  • 1,843
  • 1
  • 20
  • 24
  • Did you use this with Android? what is the absolute name of IOUtils? I only can import com.google.api.client.util.IOUtils but this class doesn't have this method. mediaContent.getInputStream().close is also not working. – David Nov 07 '13 at 15:38
  • it s part of Appache IO lib. – pommedeterresautee Nov 11 '13 at 19:04
  • And why is this solution an ugly one? – David Nov 12 '13 at 09:54
  • 1
    Because to stop the upload, basically you make it crash. The lib is uploading and then you close the InputStream which probably release an exception inside the lib, and then it s stopped. A way to ask nicely to stop the upload would be better! – pommedeterresautee Nov 14 '13 at 14:24
  • Ugly but the best possible method available currently. Thanks! This is the only solution that 'actually' stops the uploading of file. Tested on Android. – dknchris May 06 '17 at 16:09
0

I've been looking for an answer for a long time as well. The following is the best I could come up with.

Store the Future object anywhere you want (use Object or Void):

Future<Object> future;

Call this code (Java 8):

try
{
    ExecutorService executor = Executors.newSingleThreadExecutor();

    future = (Future<Object>) executor.submit(() ->
    {
       // start uploading process here
    });

    future.get();            // run the thread (blocks)
    executor.shutdown();
}
catch (CancellationException | ExecutionException | InterruptedException e)
{}

To cancel, call:

future.cancel(true);

This solution hasn't produced any nasty side effects so far, unlike stopping a thread (deprecated), and guarantees a cancel, unlike interrupting.

Ahmed Elsawalhy
  • 148
  • 1
  • 6
  • 10
-1

I've found a nasty way to do it. I am developing an android app, but I assume similar logic can apply to other platforms

I've set a progressListener to the upload request:

uploader.setProgressListener(new MediaHttpUploaderProgressListener() {
    @Override
    public void progressChanged(MediaHttpUploader uploader) throws IOException {
        if (cancelUpload) {
            //This was the only way I found to abort the download
            throw new GoogleDriveUploadServiceCancelException("Upload canceled");
        }
            reportProgress(uploader);
    }
});

As you can see, I've used a boolean member that is set from outside when I need to abort the upload. If this boolean is set to true, then on the next update of the upload progress I will crash, resulting in the abortion of the request.

Again, very ugly, but that was the only way I found to make it work

Tunaki
  • 132,869
  • 46
  • 340
  • 423
amitfr
  • 1,033
  • 1
  • 9
  • 29