2014-04-28 11 views
34

Obecnie korzystam z Retrofit by Square do komunikacji sieciowej w systemie Android. Czy istnieje sposób, aby uzyskać postęp w trakcie zadania, aby utworzyć powiadomienie o postępie, coś podobnego do tego, co Facebook wykorzystuje podczas przesyłania obrazu?Android Retrofit - onProgressUpdate za wyświetlenie powiadomienia o postępach

Przypadek użycia to ładowanie obrazu z pełną jakością obrazu bez kompresji lub skalowania.

Widzę, jak to jest możliwe z asynktaską, ale to byłoby sprzeczne z celem używania Retrofitu. Jednak może to być droga, którą musiałbym pokonać.

+0

Czy ty opracować w przypadku użycia? Większość prostych wniosków o modernizację jest tak krótka, że ​​nie wymagają wskaźników postępu, ale domyślam się, że używasz PUT lub POST do przesłania pliku podobnego do obrazu? – Hober

+0

Precyzyjnie @Hober, czy zalecałbyś, aby nie używać modernizacji do przesyłania zdjęć? A jeśli tak, czy masz jakieś zalecenia? –

+0

Zaimplementowałem to jakiś czas temu, ale nie mogłem znaleźć rozwiązania, więc zamiast tego zrobiłem nieokreślony pasek postępu. – NujnaH

Odpowiedz

67

Ta odpowiedź dotyczy Retrofit 1. Rozwiązanie kompatybilne z Retrofit 2 see this answer.


miałem ten sam problem i wreszcie udało się zrobić. Używałem wcześniej języka źródłowego, a to, co pokazałem poniżej, działało na wiosnę, ale było niespójne, odkąd popełniłem błąd, używając go dla InputStream. Przeniosłem wszystkie moje API, aby użyć retrofitu i upload był ostatnim na liście, właśnie przesłoniłem TypedFile writeTo(), aby zaktualizować mnie na bajtach odczytanych do OutputStream. Może to można poprawić, ale jak już powiedziałem, zrobiłem to, kiedy używałem Springa, więc po prostu ponownie go użyłem. To jest kod do przesłania i działa dla mnie w mojej aplikacji, jeśli chcesz pobrać opinię, możesz użyć @Streaming i przeczytać 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]); 
    } 
} 

CountingTypedFile jest po prostu kopią TypedFile ale tym ProgressListener.

+1

w końcu .. po długich poszukiwaniach .. hail Stack Overflow !!! – faruk

+0

jest już połączony w odpowiedzi @SiamakSiaSoft –

0

Jeśli chcesz uzyskać wartość maksymalną w celu pokazania go na ProgressDialog, zawiadomienie itp

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(); 
     } 
    } 
} 
Powiązane problemy