Search code examples
androidimageimageviewuripicasso

Image uri doesn't display images on ImageView on some android device


I have an ImageView. When you click on a ImageView, it will open gallery and you pick up a image and show it on ImageView. I have a condition that when I close my app and then I open it, the image will retain there . So for that, I am storing image Uri on sharedprefrence. And on opening the application i am retrieving the same Uri and tries to display the image on imageView.

However in some phones - image appears perfect like Mi(Lollipop), Samsung(KitKat) but it doesn't appear in phones like - Motorola(Marshmallow) ,One Plus One (Marshmallow). Any idea why it's happening ? Here is my code

For picking up an image i am using

Intent intent=new Intent();intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), Constants.SELECT_PICTURE);

And on OnActivityResult() code is

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     super.onActivityResult(requestCode, resultCode, data);

     if(requestCode==Constants.SELECT_PICTURE && resultCode==RESULT_OK && null!=data) {
         Uri uri=data.getData();
         Picasso.with(UsersProfileActivity.this)
             .load(uri)
             .centerCrop()
             .resize(200,200)
             .into(img_photo);

         // This profile image i am storing into a sharedpreference        
         profile_image=uri.toString();
     }

And while retrieving from sharedprefrence I convert String to uri by using Uri.parse(profile_image)

However if I notice, uri returns for different android phone is as follows

Mi(Lollipop)- Uri=content://media/external/images/media/12415
samsung(KitKat)-Uri=content://media/external/images/media/786
Motorola(Marshmallow)- Uri=content://com.android.providers.media.documents/document/image%3A30731
One Plus One (Marshmallow)- Uri=content://com.android.providers.media.documents/document/image%3A475

Hence when uri content is -content://media/external/images/media/ is display image on ImageView Perfect and in other cases it is not


Solution

  • Try this

    I developed and tested and working on

    1. Lenovo K3 Note(Marshmallow)
    2. Motorola(Lollipop)
    3. Samsung(KitKat)

    In your MainActivity.java add

        profilePicture = (ImageView)findViewById(R.id.imgProfilePicture);
        sharedPreferences = getSharedPreferences(getString(R.string.app_name)+"_ProfileDetails",MODE_PRIVATE);
    
        // get uri from shared preference
        String profilePicUri = sharedPreferences.getString("profilePicUrl","");
    
        // if uri not found
        if (profilePicUri.equalsIgnoreCase("")){
            // code for open gallery to select image
            Intent intent;
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
                intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
                intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
            }else{
                intent = new Intent(Intent.ACTION_GET_CONTENT);
            }
            intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setType("image/*");
    
            startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE_CONSTANT);
        }else{
            try{
                final int takeFlags =  (Intent.FLAG_GRANT_READ_URI_PERMISSION
                        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                // Check for the freshest data.
                getContentResolver().takePersistableUriPermission(Uri.parse(profilePicUri), takeFlags);
                // convert uri to bitmap
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), Uri.parse(profilePicUri));
                // set bitmap to imageview
                profilePicture.setImageBitmap(bitmap);
            }
            catch (Exception e){
                //handle exception
                e.printStackTrace();
            }
        }
    

    Now Handle onActivityResult.

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == SELECT_PICTURE_CONSTANT && resultCode == RESULT_OK && null != data) {
            Uri uri = data.getData();
            // This profile image i am storing into a sharedpreference
            SharedPreferences.Editor editor = sharedPreferences.edit();
            // save uri to shared preference
            editor.putString("profilePicUrl",uri.toString());
            editor.commit();
            profilePicture.setImageURI(uri);
        }
    }
    

    In your Manifest file add permission

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

    Note:

    Assuming you added code for take permission for Marshmallow

    Result Uri

    lenovo K3 Note: content://com.android.externalstorage.documents/document/primary%3ADCIM%2FCamera%2FIMG_20160606_212815.jpg

    samsung: content://com.android.providers.media.documents/document/image%3A2086

    motorola: content://com.android.providers.media.documents/document/image%3A15828