9

공식 API를 사용하여 Google 드라이브에 업로드하는 앱을 작성했지만 완벽하게 작동합니다. 그러나 어쨌든 업로드를 취소 할 수 없습니다. 나는 ASyncTask에서 실행하고 있는데, 지금까지는 드라이브 객체, 파일 경로, 토큰 및 몇 가지 다른 변수를 만들려고 시도하지 않았습니다. 나는 또한 토큰을 무효화하려고 시도했으나 캐시에서 제거하고 서버 측을 실제로 무효화하지는 않는다. ASyncTask에서 취소를 호출했지만 일단 업로드가 시작되면 취소 된 경우 중지 할 방법이없는 것으로 보입니다.Google 드라이브 업로드를 취소 할 수 있습니까?

내 문제는 사용자가 100MB 파일을 업로드하기 시작하면 다른 사람이 취소 할 수있는 방법이 없다는 것입니다. 다른 방법으로는 인터넷 연결을 켜고 끄는 것이 실용적이지 않습니다. 내 업로드 코드 :

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(); 

물론 업로드를 취소하는 방법이 있습니까?

답변

7

큰 질문! 나는 미디어 업로드 요청을 취소 할 수있는 기능에 대한 기능 요청을 제기 :

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

그러나, 이것은 어려운 기능은 해당 라이브러리의 현재 디자인을 기반으로 구현하기 위해 수 있습니다.

또 다른 옵션은 AsyncTask를 사용하지 않고 자신이 멀티 스레딩을 구현하고 실행중인 스레드를 중단하는 것입니다. 즐겁지는 않지만 지금이 일을하는 유일한 방법 일 수 있습니다.

+2

스레드를 호출하려고했습니다. Interrupt() 메소드를 사용하지만 업로드가 계속됩니다. 멀티 스레드를 직접 구현하면 무엇을 의미합니까? – pommedeterresautee

2

나는 스레드와 인터럽트에 요청을하는 것은 작동하지 않는다고 말했습니다. 그래서 나는 그것을하는 또 다른 방법을 찾고있었습니다.

드디어 하나를 발견했습니다 : 못생긴 하나 : 업로드 된 파일의 InputStream을 닫습니다!

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

그리고 내가 가진 정지 리스너에 :

나는 함께 초기화 확인을 위해

IOUtils.closeQuietly(mediaContent.getInputStream()); 

이 더 나은 방법으로 그것을 할 수 있어야한다!

감사합니다.

+0

Android에서 사용하셨습니까? IOUtils의 절대 이름은 무엇입니까? com.google.api.client.util.IOUtils 만 가져올 수 있지만이 클래스에는이 메소드가 없습니다. mediaContent.getInputStream(). close도 작동하지 않습니다. – David

+0

그것은 Appache IO lib의 일부입니다. – pommedeterresautee

+0

그리고 왜이 솔루션은 추악한 솔루션입니까? – David

0

저는 오랫동안 답을 찾고있었습니다. 다음은 내가 생각해 낼 수있는 최선의 방법입니다.

스토어 어디서나 Future 객체 당신이 원하는 (사용 Object 또는 Void) :

Future<Object> future; 

전화 코드 (자바 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) 
{} 

취소하려면, 전화 :

future.cancel(true); 

이 솔루션은 지금까지 아무런 부작용을 일으키지 않았습니다. 쓰레드를 멈추는 것처럼 (비추천), 인터럽트와 달리 취소를 보장한다.

+0

CancellationException이 발견 된 후에도 업로드가 계속됩니다. – cdkn7

0

나는 그것을하는 더러운 방법을 발견했습니다. 나는 안드로이드 응용 프로그램을 개발하고,하지만 난 비슷한 논리가 내가 업로드 요청에 progressListener를 설정 한

다른 플랫폼에 적용 할 수있는 가정 : 당신이 볼 수 있듯이, 내가 사용했습니다

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); 
    } 
}); 

업로드를 중단해야 할 때 외부에서 설정되는 부울 멤버입니다. 이 부울을 true로 설정하면 다음 업로드 진행 상황에서 충돌이 발생하여 요청이 중단됩니다.

다시보기는 매우 못생긴 것이지만 작동하는 것으로 확인 된 유일한 방법입니다.

관련 문제