Utilizza retrofit per scaricare il file image

Utilizzo Retrofit 1.6.0 sul mio progetto Android,

l'url della richiesta:

  • L'applicazione Android non riesce a caricare su alcuni telefoni in PathClassLoader
  • Disegnare Rectagle con limiti esterni
  • L'image mdpi è troppo piccola per la compressa android da 10 "
  • Come aprire Google Maps utilizzando l'indirizzo?
  • Posso utilizzare lo stesso id in layout diverso in Android?
  • Avvia l'applicazione preinstallata dall'attività (Google Voice Search) Android
  • https://example.com/image/thumbs/filename/sample.png

    La mia interface come questa:

    public interface ImageService { @GET("/image/thumbs/filename/{filename}") @Streaming void getThumbs( @Path("filename") String filename, Callback<Response> callback ); } 

    La richiesta HTTP è stata un successo, ma c'è qualche errore

     D/Retrofit(27613): ---> HTTP GET https://example.com/image/thumbs/filename/sample.png D/Retrofit(27613): ---> END HTTP (no body) D/Retrofit(27613): <--- HTTP 200 https://example.com/image/thumbs/filename/sample.png (451ms) D/Retrofit(27613): : HTTP/1.1 200 OK D/Retrofit(27613): Connection: Keep-Alive D/Retrofit(27613): Content-Disposition: inline; filename="sample.png" D/Retrofit(27613): Content-Type: image/png; charset=binary D/Retrofit(27613): Date: Wed, 11 Jun 2014 06:02:31 GMT D/Retrofit(27613): Keep-Alive: timeout=5, max=100 D/Retrofit(27613): OkHttp-Received-Millis: 1402466577134 D/Retrofit(27613): OkHttp-Response-Source: NETWORK 200 D/Retrofit(27613): OkHttp-Sent-Millis: 1402466577027 D/Retrofit(27613): Server: Apache/2.2.22 (Ubuntu) D/Retrofit(27613): Transfer-Encoding: chunked D/Retrofit(27613): X-Powered-By: PHP/5.4.28-1+deb.sury.org~precise+1 D/Retrofit(27613): ---- ERROR https://example.com/image/thumbs/filename/sample.png D/Retrofit(27613): java.io.UnsupportedEncodingException: binary D/Retrofit(27613): at java.nio.charset.Charset.forNameUEE(Charset.java:322) D/Retrofit(27613): at java.lang.String.<init>(String.java:228) D/Retrofit(27613): at retrofit.RestAdapter.logAndReplaceResponse(RestAdapter.java:478) D/Retrofit(27613): at retrofit.RestAdapter.access$500(RestAdapter.java:109) D/Retrofit(27613): at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:333) D/Retrofit(27613): at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220) D/Retrofit(27613): at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278) D/Retrofit(27613): at retrofit.CallbackRunnable.run(CallbackRunnable.java:42) D/Retrofit(27613): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) D/Retrofit(27613): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) D/Retrofit(27613): at retrofit.Platform$Android$2$1.run(Platform.java:142) D/Retrofit(27613): at java.lang.Thread.run(Thread.java:841) D/Retrofit(27613): Caused by: java.nio.charset.UnsupportedCharsetException: binary D/Retrofit(27613): at java.nio.charset.Charset.forName(Charset.java:309) D/Retrofit(27613): at java.nio.charset.Charset.forNameUEE(Charset.java:320) D/Retrofit(27613): ... 11 more D/Retrofit(27613): ---- END ERROR 

    Come risolvere questo problema?

  • Leggere tutti gli events di oggi usando CalendarContract - Android 4.0+
  • Leggete solo il file system su Android
  • Perché i conteggi dei conteggi di Google Fit differiscono
  • Chiamare context.getResources () restituisce null
  • Binding onScrolling ascoltatore alla list Android di ListView
  • Come mostrare Snackbar quando inizia l'attività?
  • 4 Solutions collect form web for “Utilizza retrofit per scaricare il file image”

    Il problema è che l'intestazione del tipo di contenuto nella risposta include un carattere falso:

     Content-Type: image/png; charset=binary 

    Retrofit vede questo e conclude che la risposta è text che può accedere. Dovresti segnalare il problema all'amministratore del server.

    Se segnalate il problema al tracker di emissione di Retrofit su GitHub, possiamo probabilmente ripristinare questo problema piuttosto che sospendere.

    Sto giocando con rxjava e retrofit in questi giorni, ho una rapida dimostrazione qui. La conversazione è a buon mercato, ti mostra il mio codice direttamente, spero che aiuta.

     public interface ImageService { String ENDPOINT = "HTTP://REPLACE.ME"; @GET @Streaming Observable<Bitmap> getThumbs(@Url String filepath); /******** * Helper class that sets up a new services *******/ class Instance { static ImageService instance; public static ImageService get() { if (instance == null) instance = newImageService(); return instance; } public static ImageService newImageService() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(ImageService.ENDPOINT) .addConverterFactory(BitmapConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); return retrofit.create(ImageService.class); } } } 

    E ho scritto il mio BitmapConverterFactory per convertire il stream di byte in bitmap:

     public final class BitmapConverterFactory extends Converter.Factory { public static BitmapConverterFactory create() { return new BitmapConverterFactory(); } private BitmapConverterFactory() { } @Override public Converter<ResponseBody, Bitmap> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { if (type == Bitmap.class) { return new Converter<ResponseBody, Bitmap>(){ @Override public Bitmap convert(ResponseBody value) throws IOException { return BitmapFactory.decodeStream(value.byteStream()); } }; } else { return null; } } @Override public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { return null; } } 

    Le dependencies di Gradle qui:

     final RETROFIT_VERSION = '2.0.0-beta3' compile "com.squareup.retrofit2:retrofit:$RETROFIT_VERSION" compile "com.squareup.retrofit2:adapter-rxjava:$RETROFIT_VERSION" 

    Acclamazioni, festa

    Naturalmente usiamo Picasso per caricare l'image, ma a volte abbiamo davvero bisogno di utilizzare Retrofit per caricare un'image speciale (come recuperare un'image captcha), è necessario aggiungere qualche intestazione per la richiesta, get un valore dall'intestazione di risposta (ovviamente puoi utilizzare anche Picasso + OkHttp, ma in un progetto che già utilizza Retrofit per gestire la maggior parte delle richieste di networking), quindi qui esplici come implementare da Retrofit 2.0.0 (ho già implementato nel mio progetto).

    Il punto chiave è che è necessario utilizzare okhttp3.ResponseBody per ricevere la risposta, altrimenti Retrofit analizzerà i dati di risposta come JSON, non i dati binari.

    codici:

     public interface Api { // don't need add 'Content-Type' header, it not works for Retrofit 2.0.0 // @Headers({"Content-Type: image/png"}) @GET Call<ResponseBody> fetchCaptcha(@Url String url); } Call<ResponseBody> call = api.fetchCaptcha(url); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { if (response.isSuccessful()) { if (response.body() != null) { // display the image data in a ImageView or save it Bitmpa bm = BitmapFactory.decodeStream(response.body().byteStream()); ivCaptcha.setImageBitmap(bm); } else { // TODO } } else { // TODO } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { // TODO } }); 

    Un altro modo è quello di distriggersre la logging completa, quindi il retrofit.RestAdapter.logAndReplaceResponse non cercherà di consumare il corpo di risposta

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.