こんにちは、Retrofit framework for Androidは初めてです。 RESTサービスからJSON応答を取得できましたが、レトロフィットを使用してpngをダウンロードする方法がわかりません。このURLからpngをダウンロードしようとしています: http: //wwwns.akamai.com/media_resources/globe_emea.png 。これを実現するために、Callback <>で指定される応答オブジェクトを指定します。
前述のように、実際に画像自体をダウンロードするためにRetrofitを使用しないでください。コンテンツを表示せずに単にダウンロードすることを目標とする場合は、Squareのライブラリの1つである OkHttp のようなHttpクライアントを使用できます。
この画像をダウンロードするコードの数行を次に示します。その後、InputStreamからデータを読み取ることができます。
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
}
});
Retrofitはあなたの質問に答える仕事ではありませんが、インターフェイス定義の署名はこれを好むでしょう。しかし、再びこれをしないでください。
public interface Api {
@GET("/media_resources/{imageName}")
void getImage(@Path("imageName") String imageName, Callback<Response> callback);
}
もちろん、通常はPicassoを使用して画像を読み込みますが、時々Retrofitを使用して特別な画像(captcha画像を取得するなど)を読み込む必要がある場合、ヘッダーを追加する必要があります要求、応答のヘッダーから値を取得します(もちろん、Picasso + OkHttpを使用することもできますが、プロジェクトではほとんどのネット要求を処理するために既にRetrofitを使用しています)。ここで、Retrofit 2.0.0(I私のプロジェクトに既に実装されています)。
重要な点は、okhttp3.ResponseBody
応答を受信する場合、Retrofitは応答データをバイナリデータではなくJSONとして解析します。
コード:
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
Bitmap bmp = BitmapFactory.decodeStream(response.body().byteStream());
imageView.setImageBitmap(bmp);
} else {
// TODO
}
} else {
// TODO
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
// TODO
}
});
RetrofitはRESTライブラリです。Retrofitは画像URLを取得するためにのみ使用できますが、画像を表示するにはPicassoを使用する必要があります。 http://square.github.io/picasso/
たとえば、Callを返すことを宣言します。
@GET("/api/{api}/bla/image.png")
Call<ResponseBody> retrieveImageData();
それを自分でビットマップに変換します:
ResponseBody body = retrofitService.retrieveImageData().execute().body();
byte[] bytes = body.bytes();
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
また、Retrofitを使用して_@GET
_を実行し、Response
を返すこともできます。次に、コードでisr = new BufferedInputStream(response.getBody().in())
を実行して、たとえばBitmapFactory.decodeStream(isr)
を実行することにより、画像の入力ストリームを取得し、ビットマップに書き込むことができます。
オブジェクト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))
}
})
}
}
RetrofitImage.getBitmapFrom(ANY_URL_STRING) {
// "it" - your bitmap
print("$it")
}
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!!)
}
}
}
拡張機能の使用法
imageView?.setBitmapFrom(ANY_URL_STRING)
次のコードがお役に立てば幸いです。
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());
}
});
}
以下は、画像のファイル処理コードです。
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;
}
}
これはAndroid Retrofit 2.0を使用して行われます。お役に立てば幸いです。
Retrofitは、バイト配列をベース64にエンコードしています。したがって、文字列をデコードすれば準備完了です。この方法で、画像のリストを取得できます。
public static Bitmap getBitmapByEncodedString(String base64String) {
String imageDataBytes = base64String.substring(base64String.indexOf(",")+1);
InputStream stream = new ByteArrayInputStream(Base64.decode(imageDataBytes.getBytes(), Base64.DEFAULT));
return BitmapFactory.decodeStream(stream);
}