简体   繁体   English

在Android> 6.0中第二次访问图库时获取安全权限异常

[英]In Android >6.0 getting Security Permission Exception while accessing image from gallery the second time

I am new to android and I am working in an android existing project.The app is crashing on android version >6.0, with below exception.Basically app is selecting photo from gallery which is working fine for the first time and on second time onwards the app is crashing giving permission denial exception. 我是Android的新手,我在Android现有项目中工作。应用程序崩溃在Android版本> 6.0,以下异常。基本应用程序是从库中选择照片,这是第一次工作正常,第二次以后应用程序崩溃给予权限拒绝例外。

java.lang.SecurityException: Permission Denial: reading com.google.android.apps.photos.contentprovider.MediaContentProvider uri content://com.google.android.apps.photos.contentprovider/0/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F1022/ORIGINAL/NONE/256350537 from pid=7789, uid=10145 requires the provider be exported, or grantUriPermission() java.lang.SecurityException:Permission Denial:读取com.google.android.apps.photos.contentprovider.MediaContentProvider uri content://com.google.android.apps.photos.contentprovider/0/1/content%3A%2F% 2Fmedia%2Fexternal%2Fimages%2Fmedia%2F1022 / ORIGINAL / NONE / 256350537来自pid = 7789,uid = 10145要求提供者被导出,或者grantUriPermission()

I have gone through few links and checked that android has introduce run time permissions and I have used below code to check the runtime permission. 我已经通过几个链接并检查android已经引入了运行时权限,我使用下面的代码来检查运行时权限。

The things I have tried so far... 到目前为止我尝试过的事情......

  1. Added permission in manifest. 在清单中添加了权限。

2.Checking the runtime permission from code. 2.从代码中检查运行时权限。

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    Log.d("Enter", "onRequestPermissionsResult: ");

    switch (requestCode){
        case REQUEST_CODE_PERMISSION:{
            Map<String,Integer> perms = new HashMap<>();
            //Initialize the map with the permissions
            perms.put(Manifest.permission.ACCESS_COARSE_LOCATION,PackageManager.PERMISSION_GRANTED);
            perms.put(Manifest.permission.CAMERA,PackageManager.PERMISSION_GRANTED);
            perms.put(Manifest.permission.READ_EXTERNAL_STORAGE,PackageManager.PERMISSION_GRANTED);
           // perms.put(Manifest.permission.READ_USER_DICTIONARY,PackageManager.PERMISSION_GRANTED);

            //Fill with actual results from user
            if (grantResults.length > 0){
                for (int i = 0 ; i < permissions.length ; i++){
                    perms.put(permissions[i],grantResults[i]);
                    //check for all permissions
                    if (perms.get(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
                            && perms.get(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
                            && perms.get(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED){

                        Log.d("Permission Granted", "onRequestPermissionsResult: ");

                    }else{
                        Log.d("Some", "onRequestPermissionsResult: ");
                        //if (perms.get(Manifest.permission.ACCESS_COARSE_LOCATION))
                        if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA)
                                || ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.ACCESS_COARSE_LOCATION)
                                || ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.READ_EXTERNAL_STORAGE)){

                            new DialogInterface.OnClickListener(){
                                @Override
                                public void onClick (DialogInterface dialog, int which){
                                    switch (which){
                                        case DialogInterface.BUTTON_POSITIVE:
                                            checkAndRequestPermission();
                                            break;
                                        case DialogInterface.BUTTON_NEGATIVE:
                                            break;
                                    }
                                }
                            };

                        }else{
                            Toast.makeText(this,"Go to Settings and enable Permissions",Toast.LENGTH_LONG).show();
                        }

                    }

                }
            }
        }
    }
}

private  void showDialogOK(String message, DialogInterface.OnClickListener okListener){
    new AlertDialog.Builder(this)
            .setMessage(message)
            .setPositiveButton("OK",okListener)
            .setNegativeButton("Cancel",okListener)
            .create()
            .show();
}

} }

And the line where it is crashing is :- 它崩溃的线是: -

if (checkAndRequestPermission()){

        InputStream fis = getContentResolver().openInputStream(Uri.parse(url)); //Crashing Line
        BitmapFactory.decodeStream(fis, null, o);
        fis.close();
    }

Below are the permissions used in My Manifest: 以下是My Manifest中使用的权限:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_USER_DICTIONARY"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>
<uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS"/>
<!--  <uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS"/>-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<!-- The following two permissions are not required to use
     Google Maps Android API v2, but are recommended. -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-feature android:name="android.hardware.location" android:required="true" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />

The problem is not with your manifest permissions, but rather the URI being used. 问题不在于您的清单权限,而在于使用的URI。 How did you get the URI? 你是怎么得到URI的? The logcat output tells you that the URI is for a content provider which was not exported or that the URI was not provided in an Intent which granted temporary access to the ContentProvider . logcat输出告诉您URI是针对未导出的内容提供程序,或者是在授予临时访问ContentProviderIntent未提供URI。

After a lot of research I was able to fix the issue.The error was causing since the google photos needs a persistable URI of images,even if you have all codes for runtime permission and flags in Manifest file. 经过大量的研究后,我能够解决这个问题。由于谷歌照片需要一个可持久的图像URI,即使你拥有运行许可的所有代码和清单文件中的标志,也会导致错误。

With the help of below answer I have fixed my issue. 在以下答案的帮助下,我解决了我的问题。 https://stackoverflow.com/a/29588566/1842304 https://stackoverflow.com/a/29588566/1842304

Note down all your permission that are working in manifest below android M. We dont need any additional permission for android M. We have to just request at runtime. 记下你在android M下面的清单中工作的所有权限。我们不需要任何对android M的额外权限。我们必须在运行时请求。

And request your permission like this. 并请求您的许可。 Change your permission(only dangerous permissions) as they are in manifest. 更改您在清单中的权限(仅限危险权限)。 Put this in onCreate 把它放在onCreate上

///  granting permission  ////
    if(!checkPermission())
    {
        requestPermission();
    }
 /////////////////////////////

And in class add these 在课堂上添加这些

    ///////////////////////   permission for marshmallow  ///////////////////

private boolean checkPermission(){
    int result1 = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
    int result2 = ContextCompat.checkSelfPermission(this, Manifest.permission.MODIFY_PHONE_STATE);
    int result3 = ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_OUTGOING_CALLS);
    int result4 = ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_INCOMING_CALLS);
    int result5   = ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE);

    if (result1 == PackageManager.PERMISSION_GRANTED && result2 == PackageManager.PERMISSION_GRANTED &&
            result3 == PackageManager.PERMISSION_GRANTED && result4 == PackageManager.PERMISSION_GRANTED
            && result5 == PackageManager.PERMISSION_GRANTED){

        return true;

    } else {

        //Toast.makeText(this,"You don't have permission to use further features",Toast.LENGTH_LONG).show();
        return false;

    }
}

private void requestPermission(){

    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE) &&
            ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.MODIFY_PHONE_STATE) &&
            ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.PROCESS_OUTGOING_CALLS)  &&
            ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.PROCESS_INCOMING_CALLS) &&
                    ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHONE)){

        Toast.makeText(this,"Application needs permission to use your camera, calls, storage and location.",Toast.LENGTH_LONG).show();

    } else {

        ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_PHONE_STATE,
                 Manifest.permission.MODIFY_PHONE_STATE, Manifest.permission.PROCESS_OUTGOING_CALLS,
                Manifest.permission.PROCESS_INCOMING_CALLS, Manifest.permission.CALL_PHONE},1);

    }
}


@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 1:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[1] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[2] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[3] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[4] == PackageManager.PERMISSION_GRANTED) {

                Toast.makeText(this,"Permission Granted.",Toast.LENGTH_LONG).show();

            } else {

                Toast.makeText(this,"Permission Denied.",Toast.LENGTH_LONG).show();

            }
            break;
    }
}

////////////////////////////////////////////////////////////////////////

Try this Solution 试试这个解决方案

in your OnCreate() method 在您的OnCreate()方法中

@Override
    protected void onCreate(Bundle savedInstanceState)
     {

       // your code
       .................

       // call dynamic permission
       check_SD_CARD_Permissions();
    }

public void check_SD_CARD_Permissions()  
{

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

       int permissionCheck = this.checkSelfPermission("Manifest.permission.WRITE_EXTERNAL_STORAGE");
            permissionCheck += this.checkSelfPermission("Manifest.permission.READ_EXTERNAL_STORAGE");
            if (permissionCheck != 0) {
                this.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 1001); //Any number
            }
        }else{
        Log.d(TAG, "checkBTPermissions: No need to check permissions. SDK version < LOLLIPOP.");
 }
}

in AndroidManifest.xml 在AndroidManifest.xml中

add these permissions 添加这些权限

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

and targetSdkVersion must be 23 和targetSdkVersion必须是23

<uses-sdk
        android:minSdkVersion="13"
        android:targetSdkVersion="23" />

Build your project with 使用。构建您的项目

Version : Android 6.0

and finally in project.properties target must be 23 最后在project.properties中,target必须是23

target=android-23

it's working for me 它对我有用

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

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