Adaptation de L'API pour récupérer une image png
Salut je suis nouveau pour Retrofit framework pour Android. Je pourrais obtenir des réponses JSON des services de repos en l'utilisant, Mais je ne sais pas comment télécharger un png en utilisant retrofit. Je suis en train de télécharger le fichier png à partir de cette url: http://wwwns.akamai.com/media_resources/globe_emea.png<!--2. Quel devrait être l'objet de réponse à spécifier dans le Callback pour réaliser ceci.
7 réponses
comme mentionné, vous ne devriez pas utiliser Retrofit pour télécharger l'image elle-même. Si votre objectif est tout simplement de télécharger le contenu sans l'afficher ensuite, vous pouvez simplement utiliser un client Http comme OkHttp qui est une autre des bibliothèques de Square.
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://wwwns.akamai.com/media_resources/globe_emea.png")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
System.out.println("request failed: " + e.getMessage());
}
@Override
public void onResponse(Response response) throws IOException {
response.body().byteStream(); // Read the data from the stream
}
});
même si Retrofit n'est pas l'homme pour le travail de répondre à votre question, la signature de votre définition D'Interface voudrait ceci. Mais encore une fois de ne pas le faire.
public interface Api {
@GET("/media_resources/{imageName}")
void getImage(@Path("imageName") String imageName, Callback<Response> callback);
}
bien sûr nous utilisons habituellement Picasso pour charger l'image, mais parfois nous avons vraiment besoin D'utiliser Retrofit pour charger une image spéciale (comme fetch a captcha image), vous avez besoin d'ajouter un en-tête pour la requête, obtenir une certaine valeur de l'en-tête de réponse (bien sûr, vous pouvez également utiliser Picasso + OkHttp, mais dans un projet, vous avez déjà utilisé Retrofit pour traiter la plupart des requêtes net), alors voici comment mettre en œuvre par Retrofit 2.0.0 (j'ai déjà mis en œuvre dans mon projet).
Le point clé est que vous besoin d'utiliser okhttp3.ResponseBody
pour recevoir de réponse, sinon Rénovation va analyser les données de réponse en JSON, pas de données binaires.
codes:
public interface Api {
// don't need add 'Content-Type' header, it's useless
// @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
}
});
Rénovation est un RESTE de la bibliothèque, vous pouvez utiliser la Rénovation que pour obtenir l'URL de l'image mais pour l'affichage de l'Image, vous devez utiliser Picasso: http://square.github.io/picasso/
Déclarer retour d'Appel par exemple:
@GET("/api/{api}/bla/image.png")
Call<ResponseBody> retrieveImageData();
puis convertissez-le en Bitmap vous-même:
ResponseBody body = retrofitService.retrieveImageData().execute().body();
byte[] bytes = body.bytes();
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
vous pouvez également utiliser Retrofit pour effectuer le @GET
et il suffit de retourner le Response
. Puis en code vous pouvez faire isr = new BufferedInputStream(response.getBody().in())
pour obtenir le flux d'entrée de l'image et de l'écrire dans une image, disons, en faisant BitmapFactory.decodeStream(isr)
.
j'espère code suivant va vous aider:
incluez la fonction suivante à l'intérieur de MainActivity.java
:
void getRetrofitImage() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitImageAPI service = retrofit.create(RetrofitImageAPI.class);
Call<ResponseBody> call = service.getImageDetails();
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Response<ResponseBody> response, Retrofit retrofit) {
try {
Log.d("onResponse", "Response came from server");
boolean FileDownloaded = DownloadImage(response.body());
Log.d("onResponse", "Image is downloaded and saved ? " + FileDownloaded);
} catch (Exception e) {
Log.d("onResponse", "There is an error");
e.printStackTrace();
}
}
@Override
public void onFailure(Throwable t) {
Log.d("onFailure", t.toString());
}
});
}
voici le code de gestion de fichier pour l'image:
private boolean DownloadImage(ResponseBody body) {
try {
Log.d("DownloadImage", "Reading and writing file");
InputStream in = null;
FileOutputStream out = null;
try {
in = body.byteStream();
out = new FileOutputStream(getExternalFilesDir(null) + File.separator + "AndroidTutorialPoint.jpg");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
}
catch (IOException e) {
Log.d("DownloadImage",e.toString());
return false;
}
finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
int width, height;
ImageView image = (ImageView) findViewById(R.id.imageViewId);
Bitmap bMap = BitmapFactory.decodeFile(getExternalFilesDir(null) + File.separator + "AndroidTutorialPoint.jpg");
width = 2*bMap.getWidth();
height = 6*bMap.getHeight();
Bitmap bMap2 = Bitmap.createScaledBitmap(bMap, width, height, false);
image.setImageBitmap(bMap2);
return true;
} catch (IOException e) {
Log.d("DownloadImage",e.toString());
return false;
}
}
cela se fait en utilisant Android Retrofit 2.0. J'espère que cela vous a aidé.
Détails
- Android studio 3.1.4
- Kotlin 1.2.60
- Rénovation 2.4.0
- vérifié dans minSdkVersion 19
Solution
objet RetrofitImage
object RetrofitImage {
private fun provideRetrofit(): Retrofit {
return Retrofit.Builder().baseUrl("https://google.com").build()
}
private interface API {
@GET
fun getImageData(@Url url: String): Call<ResponseBody>
}
private val api : API by lazy { provideRetrofit().create(API::class.java) }
fun getBitmapFrom(url: String, onComplete: (Bitmap?) -> Unit) {
api.getImageData(url).enqueue(object : retrofit2.Callback<ResponseBody> {
override fun onFailure(call: Call<ResponseBody>?, t: Throwable?) {
onComplete(null)
}
override fun onResponse(call: Call<ResponseBody>?, response: Response<ResponseBody>?) {
if (response == null || !response.isSuccessful || response.body() == null || response.errorBody() != null) {
onComplete(null)
return
}
val bytes = response.body()!!.bytes()
onComplete(BitmapFactory.decodeByteArray(bytes, 0, bytes.size))
}
})
}
}
Utilisation 1
RetrofitImage.getBitmapFrom(ANY_URL_STRING) {
// "it" - your bitmap
print("$it")
}
Utilisation 2
Extension pour ImageView
fun ImageView.setBitmapFrom(url: String) {
val imageView = this
RetrofitImage.getBitmapFrom(url) {
val bitmap: Bitmap?
bitmap = if (it != null) it else {
// create empty bitmap
val w = 1
val h = 1
val conf = Bitmap.Config.ARGB_8888
Bitmap.createBitmap(w, h, conf)
}
Looper.getMainLooper().run {
imageView.setImageBitmap(bitmap!!)
}
}
}
Utilisation de l'extension
imageView?.setBitmapFrom(ANY_URL_STRING)