J'utilise actuellement Retrofit by Square pour les communications réseau Android. Existe-t-il un moyen d'obtenir sa progression pendant une tâche pour créer une notification de progression, quelque chose de similaire à celui utilisé par Facebook lors du téléchargement d'une image ?
Le cas d'utilisation serait de charger une image, espérons-le, de qualité d'image complète sans compression ni mise à l'échelle.
Je vois comment c'est possible avec une asynctask mais cela irait à l'encontre du but de l'utilisation de Retrofit. Cependant, cela pourrait être la voie que je devrais emprunter.
Cette réponse est pour Retrofit 1. Pour une solution compatible avec Retrofit 2 voir cette réponse .
J'ai eu le même problème et j'ai finalement réussi à le faire. J'utilisais Spring Lib avant et ce que je montre ci-dessous fonctionnait pour Spring mais n'était pas cohérent car j'ai fait une erreur en l'utilisant pour InputStream. J'ai déplacé toutes mes API pour utiliser la modification et le téléchargement était le dernier de la liste, je remplace simplement TypedFile writeTo () pour me mettre à jour sur les octets lus au OutputStream. Peut-être que cela peut être amélioré, mais comme je l'ai dit, je l'ai fait lorsque j'utilisais Spring, donc je l'ai simplement réutilisé. C'est le code pour le téléchargement et cela fonctionne pour moi sur mon application, si vous voulez des commentaires sur le téléchargement, vous pouvez utiliser @Streaming et lire le inputStream.
ProgressListener
public interface ProgressListener {
void transferred(long num);
}
CountingTypedFile
public class CountingTypedFile extends TypedFile {
private static final int BUFFER_SIZE = 4096;
private final ProgressListener listener;
public CountingTypedFile(String mimeType, File file, ProgressListener listener) {
super(mimeType, file);
this.listener = listener;
}
@Override public void writeTo(OutputStream out) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
FileInputStream in = new FileInputStream(super.file());
long total = 0;
try {
int read;
while ((read = in.read(buffer)) != -1) {
total += read;
this.listener.transferred(total);
out.write(buffer, 0, read);
}
} finally {
in.close();
}
}
}
MyApiService
public interface MyApiService {
@Multipart
@POST("/files")
ApiResult uploadFile(@Part("file") TypedFile resource, @Query("path") String path);
}
SendFileTask
private class SendFileTask extends AsyncTask<String, Integer, ApiResult> {
private ProgressListener listener;
private String filePath;
private FileType fileType;
public SendFileTask(String filePath, FileType fileType) {
this.filePath = filePath;
this.fileType = fileType;
}
@Override
protected ApiResult doInBackground(String... params) {
File file = new File(filePath);
totalSize = file.length();
Logger.d("Upload FileSize[%d]", totalSize);
listener = new ProgressListener() {
@Override
public void transferred(long num) {
publishProgress((int) ((num / (float) totalSize) * 100));
}
};
String _fileType = FileType.VIDEO.equals(fileType) ? "video/mp4" : (FileType.IMAGE.equals(fileType) ? "image/jpeg" : "*/*");
return MyRestAdapter.getService().uploadFile(new CountingTypedFile(_fileType, file, listener), "/Mobile Uploads");
}
@Override
protected void onProgressUpdate(Integer... values) {
Logger.d(String.format("progress[%d]", values[0]));
//do something with values[0], its the percentage so you can easily do
//progressBar.setProgress(values[0]);
}
}
Le CountingTypedFile n'est qu'une copie de TypedFile mais inclut le ProgressListener.
Si vous souhaitez obtenir la valeur maximale afin de l'afficher sur un ProgressDialog, une notification, etc.
ProgressListener
public interface ProgressListener {
void transferred(long num, long max);
}
CountingTypedFile
public class CountingTypedFile extends TypedFile {
private static final int BUFFER_SIZE = 4096;
private final ProgressListener listener;
public CountingTypedFile(String mimeType, File file, ProgressListener listener) {
super(mimeType, file);
this.listener = listener;
}
@Override
public void writeTo(OutputStream out) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE];
FileInputStream in = new FileInputStream(super.file());
long total = 0;
try {
int read;
while ((read = in.read(buffer)) != -1) {
total += read;
this.listener.transferred(total, super.file().length());
out.write(buffer, 0, read);
}
} finally {
in.close();
}
}
}