简体   繁体   English

java.lang.SecurityException:Permission Denial:在Android中读取com.android.providers.media.MediaProvider同时从图库中获取图片

[英]java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider in Android while taking picture from gallery

I'm trying to select the image from gallery , but my application is getting exception of 'Something went wrong' message . 我正在尝试从图库中选择图像,但是我的应用程序除了“出错了”消息之外。 I thought i set up the android WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE permission correctly, but i keep getting errors What should i do to have it working? 我以为我正确设置了android WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE权限,但我一直收到错误我应该怎么做让它工作?

Here is my Log cat error 这是我的Log cat错误

06-07 12:07:27.567    1692-1711/? E/DatabaseUtils﹕ Writing exception to parcel
    java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/359 from pid=2818, uid=10057 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
            at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:605)
            at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:480)
            at android.content.ContentProvider$Transport.query(ContentProvider.java:211)
            at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
            at android.os.Binder.execTransact(Binder.java:453)

Here is my Activity code 这是我的活动代码

public class MainActivity extends Activity {
    private static int RESULT_LOAD_IMG = 1;
    String imgDecodableString;

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

    public void loadImagefromGallery(View view) {
        // Create intent to Open Image applications like Gallery, Google Photos
        Intent galleryIntent = new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        // Start the Intent
        startActivityForResult(galleryIntent, RESULT_LOAD_IMG);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        try {
            // When an Image is picked
            if (requestCode == RESULT_LOAD_IMG && resultCode == RESULT_OK
                    && null != data) {
                // Get the Image from data

                Uri selectedImage = data.getData();
                String[] filePathColumn = { MediaStore.Images.Media.DATA };

                // Get the cursor
                Cursor cursor = getContentResolver().query(selectedImage,
                        filePathColumn, null, null, null);
                // Move to first row
                cursor.moveToFirst();

                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                imgDecodableString = cursor.getString(columnIndex);
                cursor.close();
                ImageView imgView = (ImageView) findViewById(R.id.imgView);
                // Set the Image in ImageView after decoding the String
                imgView.setImageBitmap(BitmapFactory
                        .decodeFile(imgDecodableString));

            } else {
                Toast.makeText(this, "You haven't picked Image",
                        Toast.LENGTH_LONG).show();
            }
        } catch (Exception e) {
            Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
                    .show();
        }
    }
}

Here is my Menifest.xml file code 这是我的Menifest.xml文件代码

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

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

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

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

</manifest>

For checking manual permissions for API level 23 and above i use this code. 要检查API级别23及更高级别的手动权限,请使用此代码。

public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 123;

public boolean checkPermissionREAD_EXTERNAL_STORAGE(
            final Context context) {
        int currentAPIVersion = Build.VERSION.SDK_INT;
        if (currentAPIVersion >= android.os.Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(context,
                    Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(
                        (Activity) context,
                        Manifest.permission.READ_EXTERNAL_STORAGE)) {
                    showDialog("External storage", context,
                            Manifest.permission.READ_EXTERNAL_STORAGE);

                } else {
                    ActivityCompat
                            .requestPermissions(
                                    (Activity) context,
                                    new String[] { Manifest.permission.READ_EXTERNAL_STORAGE },
                                    MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
                }
                return false;
            } else {
                return true;
            }

        } else {
            return true;
        }
    }

showDialog() 的ShowDialog()

public void showDialog(final String msg, final Context context,
            final String permission) {
        AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
        alertBuilder.setCancelable(true);
        alertBuilder.setTitle("Permission necessary");
        alertBuilder.setMessage(msg + " permission is necessary");
        alertBuilder.setPositiveButton(android.R.string.yes,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions((Activity) context,
                                new String[] { permission },
                                MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
                    }
                });
        AlertDialog alert = alertBuilder.create();
        alert.show();
    }

in your activity check like this. 在你的活动检查这样。

if (checkPermissionREAD_EXTERNAL_STORAGE(this)) {
            // do your stuff..
        }

And don't forget to add onRequestPermissionsResult . 并且不要忘记添加onRequestPermissionsResult

@Override
    public void onRequestPermissionsResult(int requestCode,
            String[] permissions, int[] grantResults) {
        switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // do your stuff
            } else {
                Toast.makeText(Login.this, "GET_ACCOUNTS Denied",
                        Toast.LENGTH_SHORT).show();
            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions,
                    grantResults);
        }
    }

Happy Coding.. 快乐编码..

You have two solutions for your problem. 您有两个解决方案可以解决您的问题 The quick one is to lower targetApi to 22 (build.gradle file). 快速的是将targetApi降低到22(build.gradle文件)。 Second is to use the new runtimePermission model: Since your target api is 23 you should add the permissions on runtime too. 其次是使用新的runtimePermission模型:由于你的目标api是23,你也应该在运行时添加权限。

if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
        != PackageManager.READ_EXTERNAL_STORAGE) {

    // Should we show an explanation?
    if (shouldShowRequestPermissionRationale(
            Manifest.permission.READ_EXTERNAL_STORAGE)) {
        // Explain to the user why we need to read the contacts
    }

    requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
            MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);

    // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
    // app-defined int constant

    return;
}

Sniplet found here: https://developer.android.com/training/permissions/requesting.html Sniplet在这里找到: https//developer.android.com/training/permissions/requesting.html

There is an easy way, set an action to your "galleryIntent" so the OS will not panick (I test this on Andorid Emulator API 23 and it works): 有一个简单的方法,为你的“galleryIntent”设置一个动作,这样操作系统就不会恐慌(我在Andorid Emulator API 23上测试它并且它有效):

galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

Also, don't forget to set a type too: 另外,不要忘记设置类型:

galleryIntent.setType("image/*");

You need to set permissions explicitly to all packages match your intent. 您需要明确地将权限设置为符合您意图的所有包。 you can use this utility to do that : 你可以使用这个实用程序来做到这一点:

List<ResolveInfo> resInfoList = getContext().getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    for (ResolveInfo resolveInfo : resInfoList) {
        String packageName = resolveInfo.activityInfo.packageName;
        getContext().grantUriPermission(packageName, imageFileUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }
  • Change: 更改:
    Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

  • To: 至:
    Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

=> done ! =>完成!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 java.lang.SecurityException:权限拒绝:阅读com.android.providers.media.MediaProvider - java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider 拒绝权限:阅读com.android.providers.media.MediaProvider uri content:// media / external / images / media / 38 - Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media/38 应用程序崩溃引发权限拒绝异常:读取com.android.providers.media.MediaProvider - App Crashes throwing an exception of permission denial:reading com.android.providers.media.MediaProvider java.lang.SecurityException:权限被拒绝:打开提供程序 com.android.providers.media.Media - java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.Media java.lang.SecurityException:权限拒绝:打开提供程序 com.android.providers.calendar.CalendarProvider2 - java.lang.SecurityException: Permission Denial: opening provider com.android.providers.calendar.CalendarProvider2 java.lang.SecurityException:权限拒绝:阅读 - java.lang.SecurityException: Permission Denial: reading java.lang.SecurityException:Permission Denial:需要com.huawei.android.launcher.permission.WRITE_SETTINGS - java.lang.SecurityException: Permission Denial: requires com.huawei.android.launcher.permission.WRITE_SETTINGS Android:java.lang.SecurityException:权限拒绝:启动意图 - Android: java.lang.SecurityException: Permission Denial: start Intent Android - java.lang.SecurityException:权限拒绝:启动 Intent - Android - java.lang.SecurityException: Permission Denial: starting Intent java.lang.SecurityException:权限拒绝:打开提供者com.google.android.apps.photos.content.GooglePhotosImageProvider - java.lang.SecurityException: Permission Denial: opening provider com.google.android.apps.photos.content.GooglePhotosImageProvider
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM