I am trying to convert string value (path of an image from the server using Retrofit) to a bitmap with the use of Glide. I used the opposite method (convert bitmap to a string and then save the path in the server, and that works fine). But when I try to do the opposite way, it shows some logs about Glide and the adapter, and the images do not shows in the activity, only the titles (texts) of the images appears. All related code is below.
ApiClient.java:
package com.example.retrofit;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class ApiClient {
private static final String BASE_URL = "http://10.0.2.2/imageupload/";
private static Retrofit retrofit;
protected static Retrofit getApiClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create()).build();
}
return retrofit;
}
}
ApiInterface.java:
package com.example.retrofit;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
public interface ApiInterface {
@GET("getinfo.php")
Call<List<Model>> getInfo(@Query("item_type") String item_type);
@FormUrlEncoded
@POST("upload.php")
Call<Model> uploadImage(@Field("title") String title, @Field("image") String image);
}
Model.java:
package com.example.retrofit;
import com.google.gson.annotations.SerializedName;
public class Model {
@SerializedName("title")
private String Title;
@SerializedName("path")
private String path;
@SerializedName("response")
private String Response;
public String getResponse() {
return Response;
}
public String getTitle() {
return Title;
}
public String getPath() {
return path;
}
}
MyAdapter.java:
package com.example.retrofit;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.widget.RecyclerView;
import android.util.Base64;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import java.io.ByteArrayOutputStream;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private Context context;
private List<Model> models;
public MyAdapter(Context context, List<Model> models)
{
this.context = context;
this.models = models;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_items, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.Name.setText(models.get(position).getTitle());
// Here, trying to get the path as a string to convert it to a bitmap.
//String image = Glide.with(context).load(models.get(position).getPath()).into(holder.Img_Path).toString();
String image1 = String.valueOf(Glide.with(context).load(models.get(position).getPath()).into(holder.Img_Path));
stringToBitmap(image1);
}
// Convert the string to a bitmap.
private Bitmap stringToBitmap(String image) {
try {
byte[] encodeByte = Base64.decode(image, Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
return bitmap;
} catch(Exception e) {
e.getMessage();
return null;
}
}
@Override
public int getItemCount() {
if(models != null)
return models.size();
return 0;
}
public static class MyViewHolder extends RecyclerView.ViewHolder
{
private TextView Name;
private ImageView Img_Path;
public MyViewHolder(View itemView) {
super(itemView);
Name = (TextView) itemView.findViewById(R.id.textView);
Img_Path = (ImageView) itemView.findViewById(R.id.imgView);
}
}
}
ListActivity.java:
package com.example.retrofit;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class ListActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private List<Model> models;
private MyAdapter adapter;
private ApiInterface apiInterface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
recyclerView = (RecyclerView) findViewById(R.id.rv);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
if(getIntent().getExtras() != null)
{
String type = getIntent().getExtras().getString("type");
getInfo(type);
}
}
private void getInfo(String type)
{
apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
Call<List<Model>> call = apiInterface.getInfo(type);
call.enqueue(new Callback<List<Model>>() {
@Override
public void onResponse(Call<List<Model>> call, Response<List<Model>> response) {
models = response.body();
adapter = new MyAdapter(ListActivity.this, models);
recyclerView.setAdapter(adapter);
}
@Override
public void onFailure(Call<List<Model>> call, Throwable t) {
}
});
}
}
MainActivity.java:
...
...
...
@Override
public void onClick(View v) {
switch (v.getId()) {
...
...
...
case R.id.secondActivityBtn:
Intent intent1 = new Intent(this, ListActivity.class);
intent1.putExtra("type", "m");
startActivity(intent1);
break;
}
}
getinfo.php (Server side):
<?php
require "init.php";
$type = $_GET['item_type'];
if($type == 'm')
{
$sql = "select * from imageinfo";
$response = array();
$result = mysqli_query($con, $sql);
while($row = mysqli_fetch_array($result))
{
array_push($response, array('title'=>$row['title'], 'path'=>$row['path']));
}
echo json_encode($response);
}
mysqli_close($con);
?>
LOG:
07-07 23:10:05.817 11051-11051/com.example.retrofit D/NetworkSecurityConfig: No Network Security Config specified, using platform default
07-07 23:10:06.039 11051-11051/com.example.retrofit E/RecyclerView: No adapter attached; skipping layout
07-07 23:10:06.103 11051-11051/com.example.retrofit W/Glide: Failed to find GeneratedAppGlideModule. You should include an annotationProcessor compile dependency on com.github.bumptech.glide:glide:compiler in your application and a @GlideModule annotated AppGlideModule implementation or LibraryGlideModules will be silently ignored
07-07 23:10:06.255 11051-11080/com.example.retrofit D/EGL_emulation: eglMakeCurrent: 0xaa205120: ver 2 0 (tinfo 0xaa203730)
07-07 23:10:06.347 11051-11080/com.example.retrofit D/EGL_emulation: eglMakeCurrent: 0xaa205120: ver 2 0 (tinfo 0xaa203730)
07-07 23:10:06.439 11051-11080/com.example.retrofit D/EGL_emulation: eglMakeCurrent: 0xaa205120: ver 2 0 (tinfo 0xaa203730)
07-07 23:10:06.466 11051-11051/com.example.retrofit W/Glide: Load failed for uploads/Android.jpg with size [1440x420]
class com.bumptech.glide.load.engine.GlideException: Failed to load resource
Cause (1 of 1): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class java.io.InputStream, LOCAL
Cause (1 of 1): class com.bumptech.glide.load.engine.GlideException: Fetch failed
Cause (1 of 1): class java.io.FileNotFoundException: /uploads/Android.jpg (No such file or directory)
07-07 23:10:06.466 11051-11051/com.example.retrofit E/Glide: class com.bumptech.glide.load.engine.GlideException: Failed to load resource
07-07 23:10:06.466 11051-11051/com.example.retrofit I/Glide: Root cause (1 of 1)
java.io.FileNotFoundException: /uploads/Android.jpg (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:146)
at java.io.FileInputStream.<init>(FileInputStream.java:99)
at android.content.ContentResolver.openInputStream(ContentResolver.java:702)
at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResourceFromUri(StreamLocalUriFetcher.java:79)
at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:55)
at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:16)
at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:40)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:95)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:61)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:282)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:252)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:222)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:347)
07-07 23:10:06.467 11051-11051/com.example.retrofit W/Glide: Load failed for uploads/Test.jpg with size [1440x420]
class com.bumptech.glide.load.engine.GlideException: Failed to load resource
Cause (1 of 2): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class java.io.InputStream, LOCAL
Cause (1 of 1): class com.bumptech.glide.load.engine.GlideException: Fetch failed
Cause (1 of 1): class java.io.FileNotFoundException: /uploads/Test.jpg (No such file or directory)
Cause (2 of 2): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class android.os.ParcelFileDescriptor, LOCAL
Cause (1 of 1): class com.bumptech.glide.load.engine.GlideException: Fetch failed
Cause (1 of 1): class java.io.FileNotFoundException: No such file or directory
07-07 23:10:06.468 11051-11051/com.example.retrofit E/Glide: class com.bumptech.glide.load.engine.GlideException: Failed to load resource
07-07 23:10:06.470 11051-11051/com.example.retrofit I/Glide: Root cause (1 of 2)
java.io.FileNotFoundException: /uploads/Test.jpg (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:146)
at java.io.FileInputStream.<init>(FileInputStream.java:99)
at android.content.ContentResolver.openInputStream(ContentResolver.java:702)
at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResourceFromUri(StreamLocalUriFetcher.java:79)
at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:55)
at com.bumptech.glide.load.data.StreamLocalUriFetcher.loadResource(StreamLocalUriFetcher.java:16)
at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:40)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:95)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:61)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:282)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:252)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:222)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:347)
07-07 23:10:06.471 11051-11051/com.example.retrofit I/Glide: Root cause (2 of 2)
java.io.FileNotFoundException: No such file or directory
at android.os.Parcel.openFileDescriptor(Native Method)
at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:283)
at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:200)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:979)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:907)
at com.bumptech.glide.load.data.FileDescriptorLocalUriFetcher.loadResource(FileDescriptorLocalUriFetcher.java:21)
at com.bumptech.glide.load.data.FileDescriptorLocalUriFetcher.loadResource(FileDescriptorLocalUriFetcher.java:13)
at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:40)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:95)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:61)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:282)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:377)
at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailed(SourceGenerator.java:118)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.startNextOrFail(MultiModelLoader.java:146)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.onLoadFailed(MultiModelLoader.java:138)
at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:45)
at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:95)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:61)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:282)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:252)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:222)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:347)
SOME CODE AND HINTS THAT MAY HELP...
Convert bitmap to a string value (works fine for me):
// Convert the "bitmap" to a string value.
private String imgToString() {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// Compress or change the extension of the image (bitmap) to jpeg and save it to
// byteArrayOutputStream.
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
byte[] imgBytes = byteArrayOutputStream.toByteArray();
return Base64.encodeToString(imgBytes, Base64.DEFAULT);
}
Screenshot from the database (imageinfo table):