Cancel Google Drive upload possible?

2019-01-24 07:02发布

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?

4条回答
2楼-- · 2019-01-24 07:20

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.

查看更多
叛逆
3楼-- · 2019-01-24 07:28

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

查看更多
走好不送
4楼-- · 2019-01-24 07:33

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.

查看更多
霸刀☆藐视天下
5楼-- · 2019-01-24 07:42

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

查看更多
登录 后发表回答