简体   繁体   中英

Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider

I am trying to allow the user to access his photo library to get a profile picture, and that save that profile picture to SharedPreferences. I also have a navbar that gets this picture from SharedPreferences

I am getting the following error:

java.lang.SecurityException: 
Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord
{a601c1c 3379:com.example.foo.finalapp/u0a60} (pid=3379, uid=10060) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS

Here is the code for getting the picture:

MainActivity

       ImageView prof_pic = (ImageView) header.findViewById(R.id.profPic);
        pref = getSharedPreferences(Profile.pref_filename, 0);
        String uri = pref.getString("target_uri", "");
        TextView tv_name = (TextView) header.findViewById(R.id.tv_name);
        String name = pref.getString("name", "");
        if(!uri.equals("")) {
            Uri urii = Uri.parse(uri);
            try {
                Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(urii));
                tv_name.setText(name);
                prof_pic.setImageBitmap(bitmap);
            } catch (FileNotFoundException e) {

            }
        }
        else {
            prof_pic.setImageResource(R.drawable.ic_android_black_24dp);
        }
    }

profile_pic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                Intent intent = new Intent(Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, 0);
                */
                Intent intent;

                if (Build.VERSION.SDK_INT < 19) {
                    intent = new Intent();
                    intent.setAction(Intent.ACTION_GET_CONTENT);
                    intent.setType("*/*");
                    startActivityForResult(intent, KITKAT_VALUE);
                } else {
                    intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    intent.setType("*/*");
                    startActivityForResult(intent, KITKAT_VALUE);
                }
            }
        });

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == KITKAT_VALUE) {
            if (resultCode == RESULT_OK) {
                targetUri = data.getData();
                //Bitmap bitmap;
                try {
                    bitmap = BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(targetUri));
                /*
                SharedPreferences.Editor edit = pref.edit();
                edit.putString("target_uri", targetUri.toString());
                edit.apply();
                */
                    sTargetUri = targetUri.toString();
                    profile_pic.setImageBitmap(bitmap);
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

Here is my manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.finalapp">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".JobViewActivity"></activity>
    </application>

</manifest>
public static final int GALLERY_INTENT_CALLED = 1;
    public static final int GALLERY_KITKAT_INTENT_CALLED = 2;

if (Build.VERSION.SDK_INT <19){
                    Intent intent = new Intent();
                    intent.setType("*/*");
                    intent.setAction(Intent.ACTION_GET_CONTENT);
                    startActivityForResult(intent, GALLERY_INTENT_CALLED);
                } else {
                    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    intent.setType("*/*");
                    startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED);
                }



public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
            if (resultCode == RESULT_OK) {
                Uri originalUri = null;
                if (Build.VERSION.SDK_INT < 19) {
                    originalUri = data.getData();
                } else {
                    originalUri = data.getData();
                    final int takeFlags = data.getFlags()
                            & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

                    try {
                        getActivity().getContentResolver().takePersistableUriPermission(originalUri, takeFlags);
                    }
                    catch (SecurityException e){
                        e.printStackTrace();
                    }
                }
                try {
                    bitmap = BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(originalUri));
...

In my case, the image resource file in my device was removed and the android system could not find the correct path. Clearing my room database and running the app again solved the issue.

Once first URI is opened with success run:

getContentResolver().takePersistableUriPermission(myURI, (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION));

In order to save read and write permissions.

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