Search code examples
androidimagebitmapuriuniversal-image-loader

Android Universal Image Loader fails to display image by uri


So my application works something like that:

In some point I switch to an activity that takes a photo, gets the created bitmap's url and passes it on to my main activity: public class CameraActivity extends AppCompatActivity {

static final int REQUEST_IMAGE_CAPTURE = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Uri imageUri = data.getData();

        Intent mainmenu = new Intent(this, MainActivity.class);
        mainmenu.putExtra("imageUri", imageUri.toString());
        setResult(Activity.RESULT_OK, mainmenu);
        finish();
    }
}

Then in my main activity I update my sqlite db with the new path

        switch(requestCode)
    {
        case CAMERA_RESULT:

            String imageUri = data.getStringExtra("imageUri");
            Task imageTask= tasks.get(taskImageSet);
            db.deleteTask(imageTask);
            adapter.remove(imageTask);

            imageTask.setImagePath(imageUri);

            db.addTask(imageTask);
            adapter.add(imageTask);
            adapter.notifyDataSetChanged();
            break;

(I know it's kinda silly doing it like this but I just try to make the image loader thing work...)

Then when the user clicks on something it switches to another activity which supposed to show the result:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.dialog_showimage);

    // UNIVERSAL IMAGE LOADER SETUP
    DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
            .cacheOnDisc(true).cacheInMemory(true)
            .imageScaleType(ImageScaleType.EXACTLY)
            .displayer(new FadeInBitmapDisplayer(300)).build();

    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
            getApplicationContext())
            .defaultDisplayImageOptions(defaultOptions)
            .memoryCache(new WeakMemoryCache())
            .discCacheSize(100 * 1024 * 1024).build();

    ImageLoader.getInstance().init(config);

    String url = getIntent().getStringExtra("url");

    Toast.makeText(this, url, Toast.LENGTH_LONG).show();

    ImageLoader imageLoader = ImageLoader.getInstance();
    DisplayImageOptions options = new DisplayImageOptions.Builder().cacheInMemory(true)
            .cacheOnDisc(true).resetViewBeforeLoading(true)
            .showImageForEmptyUri(R.drawable.at_save)
            .showImageOnFail(R.drawable.cv_fail)
            .showImageOnLoading(R.drawable.cv_loading).build();

    ImageView imageView = (ImageView) findViewById(R.id.ivTaskImage);


    imageLoader.displayImage(url, imageView, options);
}

But it doesn't and instead it show the cv_fail image.

Important to mention that I printed the path when the bitmap generated and before showing the image and it was the same, looking something like:

content://media/external/images/media/84443

I have the following permission in my manifest:

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Any help would be very much appreciated!


Solution

  • Instead of using URI, you also can use file path of the image that you can retrieve from URI. The reason why I prefer to use file because you can check if the image is really exist in your storage or not. You can check all the acceptables URIs here : Universal Image Loader

     Uri selectedImageUri = Uri.parse(imageUri);
     String photoPath = getRealPathFromURI(selectedImageUri);
    

    This is the method to get photo path

    private String getRealPathFromURI(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        @SuppressWarnings("deprecation")
        Cursor cursor = managedQuery(uri, projection, null, null, null);
        int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }
    

    Now you're getting result like this file:///mnt/sdcard/image.png. Then you can display the image as usual.

     imageLoader.displayImage(photoPath, imageView, options); 
     //make sure your photoPath contain this prefix: 'file:/'