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.