2017-02-08 12 views
4

Ich bin neu zu Retrofit. Ich habe gesucht, aber keine einfache Antwort gefunden. Ich möchte wissen, wie ich den Fortschritt des Downloads in der Benachrichtigungsleiste anzeigen kann oder zumindest einen Fortschrittsdialog anzeigen kann, der den Prozentsatz des Vorgangs und der Größe der heruntergeladenen Datei angibt. Hier ist mein Code:Android Retrofit Download Fortschritt

public interface ServerAPI { 
    @GET 
    Call<ResponseBody> downlload(@Url String fileUrl); 

    Retrofit retrofit = 
      new Retrofit.Builder() 
        .baseUrl("http://192.168.43.135/retro/") 
        .addConverterFactory(GsonConverterFactory.create()) 
        .build(); 

} 

public void download(){ 
    ServerAPI api = ServerAPI.retrofit.create(ServerAPI.class); 
    api.downlload("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png").enqueue(new Callback<ResponseBody>() { 
     @Override 
     public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { 
      try { 
       File path = Environment.getExternalStorageDirectory(); 
       File file = new File(path, "file_name.jpg"); 
       FileOutputStream fileOutputStream = new FileOutputStream(file); 
       IOUtils.write(response.body().bytes(), fileOutputStream); 
      } 
      catch (Exception ex){ 
      } 
     } 


     @Override 
     public void onFailure(Call<ResponseBody> call, Throwable t) { 
     } 
    }); 
} 

Bitte führen Sie mich, wenn Sie können. Dank

Antwort

1

Sie einen Blick here nehmen können, müssen Sie nicht es implementieren müssen, um von sich selbst, hinter der Idee ist, den Inhalt Länge des Antrags zu nehmen und wenn Sie auf den Puffer schreiben Sie einfach berechnen Sie Ihre Fortschritte

6

Sie müssen einen speziellen OkHttp-Client erstellen, der die Netzwerkanforderungen abfängt und Aktualisierungen sendet. Dieser Client sollte nur für Downloads verwendet werden.

Zuerst werden eine Schnittstelle müssen, wie diese:

public interface OnAttachmentDownloadListener { 
    void onAttachmentDownloadedSuccess(); 
    void onAttachmentDownloadedError(); 
    void onAttachmentDownloadedFinished(); 
    void onAttachmentDownloadUpdate(int percent); 
} 

Ihr Download Anruf ein ResponseBody zurückkehren soll, die wir erstrecken sich von der Lage sein, den Download-Fortschritt zu erhalten.

private static class ProgressResponseBody extends ResponseBody { 

    private final ResponseBody responseBody; 
    private final OnAttachmentDownloadListener progressListener; 
    private BufferedSource bufferedSource; 

    public ProgressResponseBody(ResponseBody responseBody, OnAttachmentDownloadListener progressListener) { 
     this.responseBody = responseBody; 
     this.progressListener = progressListener; 
    } 

    @Override public MediaType contentType() { 
     return responseBody.contentType(); 
    } 

    @Override public long contentLength() { 
     return responseBody.contentLength(); 
    } 

    @Override public BufferedSource source() { 
     if (bufferedSource == null) { 
      bufferedSource = Okio.buffer(source(responseBody.source())); 
     } 
     return bufferedSource; 
    } 

    private Source source(Source source) { 
     return new ForwardingSource(source) { 
      long totalBytesRead = 0L; 

      @Override public long read(Buffer sink, long byteCount) throws IOException { 
       long bytesRead = super.read(sink, byteCount); 

       totalBytesRead += bytesRead != -1 ? bytesRead : 0; 

       float percent = bytesRead == -1 ? 100f : (((float)totalBytesRead/(float) responseBody.contentLength()) * 100); 

       if(progressListener != null) 
        progressListener.onAttachmentDownloadUpdate((int)percent); 

       return bytesRead; 
      } 
     }; 
    } 
} 

Dann müssen Sie Ihre OkHttpClient wie diese

public OkHttpClient.Builder getOkHttpDownloadClientBuilder(OnAttachmentDownloadListener progressListener) { 
    OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder(); 

    // You might want to increase the timeout 
    httpClientBuilder.connectTimeout(20, TimeUnit.SECONDS); 
    httpClientBuilder.writeTimeout(0, TimeUnit.SECONDS); 
    httpClientBuilder.readTimeout(5, TimeUnit.MINUTES); 

    httpClientBuilder.addInterceptor(new Interceptor() { 
     @Override 
     public Response intercept(Chain chain) throws IOException { 
      if(progressListener == null) return chain.proceed(chain.request()); 

     Response originalResponse = chain.proceed(chain.request()); 
     return originalResponse.newBuilder() 
       .body(new ProgressResponseBody(originalResponse.body(), progressListener)) 
       .build(); 
     } 
    }); 

    return httpClientBuilder; 
} 

Schließlich erstellen Sie müssen nur Ihre Retrofit-Client eine andere Art und Weise erstellen, indem Sie Ihre neuen OkHttp Client übergeben. Basierend auf Ihren Code, können Sie so etwas wie folgt verwenden:

public Retrofit getDownloadRetrofit(OnAttachmentDownloadListener listener) { 

    return new Retrofit.Builder() 
       .baseUrl("http://192.168.43.135/retro/") 
       .addConverterFactory(GsonConverterFactory.create()) 
       .client(getOkHttpDownloadClientBuilder(listener).build()) 
       .build(); 

} 

Ihre Zuhörer wird die Erstellung Ihrer Benachrichtigung behandeln oder was auch immer Sie wollen.