2014-04-28 20 views
34

Attualmente sto utilizzando Retrofit by Square per le comunicazioni di rete Android. C'è un modo per ottenere i suoi progressi durante un'attività per creare una notifica di avanzamento, qualcosa di simile a quello che usa Facebook quando si carica un'immagine?Retrofit Android - onProgressUpdate per la notifica dell'avanzamento

L'uso del caso sarebbe quello di caricare un'immagine con speranza di una piena qualità dell'immagine senza compressione o ridimensionamento.

Vedo come è possibile con un asynctask, ma ciò vanificherebbe lo scopo di utilizzare Retrofit. Comunque quella potrebbe essere la strada che dovrei prendere.

+0

Can voi elaborare il caso d'uso? Le richieste di retrofit più semplici sono così brevi da non richiedere gli indicatori di avanzamento, ma suppongo che tu stia utilizzando PUT o POST per caricare un file come un'immagine? – Hober

+0

Precisely @Hober, suggeriresti di non utilizzare il retrofit per caricare un'immagine? E se sì, hai qualche consiglio? –

+0

L'ho implementato qualche tempo fa ma non ho trovato la soluzione, quindi ho fatto una barra di progresso indeterminato. – NujnaH

risposta

67

Questa risposta è per Retrofit 1. Per la soluzione compatibile con Retrofit 2 see this answer.


Ho avuto lo stesso problema e finalmente riuscito a farlo. Prima stavo usando lib di primavera e quello che ho mostrato qui sotto ha funzionato per Spring ma era incoerente da quando ho fatto un errore nell'usarlo per InputStream. Ho spostato tutte le mie API per utilizzare il retrofit e il caricamento è stato l'ultimo della lista, ho appena scavalcato TypedFile writeTo() per aggiornarmi sui byte letti in OutputStream. Forse questo può essere migliorato ma come ho detto l'ho fatto quando stavo usando Spring, quindi l'ho riutilizzato. Questo è il codice per il caricamento e funziona per me sulla mia app, se si desidera il feedback del download, è possibile utilizzare @Streaming e leggere l'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]); 
    } 
} 

Il CountingTypedFile è solo una copia di TypedFile ma compreso il ProgressListener.

+1

finalmente .. dopo una lunga ricerca .. hail Stack Overflow !!! – faruk

+0

è già collegato nella risposta @SiamakSiaSoft –

0

Se si desidera ottenere il massimo valore al fine di mostrare su un ProgressDialog, di notifica, ecc

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