简体   繁体   中英

Loading image from uri android

I am currently trying to load a Uri of an image i have saved into my MySQLite database into a RecyclerView.

The code for the RecyclerViewAdapter :

public void onBindViewHolder(MyCatchesAdapter.MyViewHolder holder, int position) {
    MyCatch myCatch = myCatchArrayList.get(position);
    holder.txtName.setText(myCatch.get_name());
    holder.txtLocation.setText(myCatch.get_location());
    holder.txtDate.setText(myCatch.get_date());

    holder.catchImage.setImageURI(Uri.parse(myCatch.get_catchImage()));
}

All the data loads into the recycler view except the image. I get the following from the Logcat

Unable to open content: content://com.android.externalstorage.documents/document/primary%3ADownload%2Fsunrise.png

java.lang.SecurityException: Permission Denial: opening provider com.android.externalstorage.ExternalStorageProvider from ProcessRecord
{ee1a504 28074:com.example.pavlos.myproject/u0a74} (pid=28074, uid=10074) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS

And my Manifest permissions are :

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

Is there something that i am missing?

EDIT: How i get the Uri:

catchImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent,
                    "Select Picture"), SELECT_PICTURE);
        }
    });

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        if (requestCode == SELECT_PICTURE) {
            Uri selectedImageUri = data.getData();
            selectedImagePath = getPath(selectedImageUri);
            catchImage.setImageURI(selectedImageUri);
            imagePath = selectedImageUri;
            Log.d("imagePath","URI "+selectedImageUri);
        }
    }
}
public String getPath(Uri uri) {
    // just some safety built in
    if( uri == null ) {
        // TODO perform some logging or show user feedback
        return null;
    }
    // try to retrieve the image from the media store first
    // this will only work for images selected from gallery
    String[] projection = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(uri, projection, null, null, null);
    if( cursor != null ){
        int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String path = cursor.getString(column_index);
        cursor.close();
        return path;
    }
    // this is our fallback here
    return uri.getPath();
}

First, getPath() is completely wrong. At best, it will work for some subset of images returned from the MediaStore . Get rid of it entirely. Use an image-loading library to populate your ImageView .

In terms of your problem, the Uri that you get back from ACTION_GET_CONTENT can be used by your activity, for as long as that activity instance is around. You can pass that Uri to other components (eg, another activity), if and only if you include FLAG_GRANT_READ_URI_PERMISSION . Once your process terminates, you lose all rights to access the content. So, stop persisting the Uri to a database, or switch to ACTION_OPEN_DOCUMENT and take persistable Uri permissions.

Looks like you are getting the image URI (usually from gallery) which would come as a content URI (content://). This content URI comes with temporary permission which would get lost when it loses the current context. So when you load the URI next time, you might not have permission to load it in the current context.

I would suggest you to store the content of the image in DB and load it whenever required. Various image optimizations like image compression can be applied. You may also look this Glide library for image management which is recommended by Google.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM