简体   繁体   中英

Android: Permission Denial: starting Intent with revoked permission android.permission.CAMERA

I'm trying to start a ACTION_IMAGE_CAPTURE activity in order to take a picture in my app and I'm getting the error in the subject.

Stacktrace:

FATAL EXCEPTION: main
Process: il.ac.shenkar.david.todolistex2, PID: 3293
java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=com.google.android.GoogleCamera/com.android.camera.CaptureActivity } from ProcessRecord{22b0eb2 3293:il.ac.shenkar.david.todolistex2/u0a126} (pid=3293, uid=10126) 
with revoked permission android.permission.CAMERA

The camera permissions is added to the manifest.xml fie:

<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_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />

Here is the call to open the camera:

RadioGroup radioGroup = (RadioGroup) findViewById(R.id.statusgroup);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId)
        {
            RadioButton rb = (RadioButton) findViewById(R.id.donestatusRBtn);
            if(rb.isChecked())
            {
                Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                    startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
                }
            }
        }
    });

Remove this permission

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

I faced this error executing my app in android 7. After tests I noticed user permission wasn't in project A but it was in project B, that I only tested in android 5 devices. So I remove that permission in project B in order to run it on other device that targets android 7 and it finally could open.

In adittion I added the fileprovider code that Android suggests here https://developer.android.com/training/camera/photobasics.html Hope this helps.

hi you can use these permission in your manifest file with other permission,

<uses-feature
    android:name="android.hardware.camera.any"
    android:required="true" />
<uses-feature
    android:name="android.hardware.camera.autofocus"
    android:required="false" />

Now we have very sorted way for permission handling. So,here is the steps. I have added here for kotlin.

Step 1. Declare this as global variable or any where.

private val permissions = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { granted ->
        granted.entries.forEach {
            when (it.value) {
                true -> {
                    // Call whatever you want to do when someone allow the permission. 
                }
                false -> {
                    showPermissionSettingsAlert(requireContext())
                }
            }
        }
    }

Step 2.

// You can put this line in constant.
val storagePermission = arrayOf(
    Manifest.permission.READ_EXTERNAL_STORAGE
)

// You can put this in AppUtil. 
fun checkPermissionStorage(context: Context): Boolean {
        val result =
            ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE)

        return result == PackageManager.PERMISSION_GRANTED
 }


// Put this where you need Permission check. 

    if (!checkPermissionStorage(requireContext())) {
        permissions.launch(
                storagePermission
        )
    } else {
        // Permission is already added. 
    }

Step 3. Permission rejection Dialog. If you want you can use this.

fun showPermissionSettingsAlert(context: Context) {
    val builder = AlertDialog.Builder(context)
    builder.setTitle("Grant Permission")
    builder.setMessage("You have rejected the Storage permission for the application. As it is absolutely necessary for the app to perform you need to enable it in the settings of your device. Please select \"Go to settings\" to go to application settings in your device.")
    builder.setPositiveButton("Allow") { dialog, which ->
        val intent = Intent()
        intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
        val uri = Uri.fromParts("package", context.packageName, null)
        intent.data = uri
        context.startActivity(intent)
    }
    builder.setNeutralButton("Deny") { dialog, which ->

        dialog.dismiss()
    }
    val dialog = builder.create()
    dialog.show()
}

Thankyou

hope this will help you (Y).

In my case the problem was related to my emulator permissions ,

To fix the issue :

1- Go to Settings of your emulator.

2- Look for Apps and Notifications.

3- Click on Add Permission.

see the pic : https://i.stack.imgur.com/z4GfK.png

4- Select Camera of the list.

5- Look for your Application in the provided list.

6- Enable Camera.

see the pic : https://i.stack.imgur.com/dJ8wG.pngEnjoy

Now you can use your camera on your emulator :)

Here is how I solved mine:

First of all I think the issue arises when you try to use your device Camera on (SDK < 26) without FULL permissions.

Yes, even though you have already included this permission:

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

To solve this issue I changed that to this :

<uses-permission android:name="android.permission.CAMERA" 
                 android:required="true" 
                 android:requiredFeature="true"/>

This information from the Android Docs, might be really helpful

If your application uses, but does not require a camera in order to function, instead set android:required to false . In doing so, Google Play will allow devices without a camera to download your application. It's then your responsibility to check for the availability of the camera at runtime by calling hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY) . If a camera is not available, you should then disable your camera features.

private String [] permissions = {"android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.ACCESS_FINE_LOCATION", "android.permission.READ_PHONE_STATE", "android.permission.SYSTEM_ALERT_WINDOW","android.permission.CAMERA"};

on your OnCreate add this:

int requestCode = 200;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    requestPermissions(permissions, requestCode);
}

As some have pointed out, one solution is removing the Camera Permission from AndroidManifest.xml, ie, remove this line:

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

However, that was not enough for me, as I needed the Camera Permission for something else in my app. So what worked for me was tagging that permission as not required, like this:

<uses-permission android:name="android.permission.CAMERA" android:required="false" />

short answer ...its looking for permissions , upon failing permissions it throws exception ; moreover in this case its looking for Two Permissions ie first Storage and second Camera.

long answer.....Give it the permissions write way to work on all Versions of Android.I am looping to get both permissions Storage and Camera, So that it will work with Intent.

  1. maintain in AndroidManifest.xml
<uses-feature
        android:name="android.hardware.camera.any"
        android:required="true" />
    <uses-feature
        android:name="android.hardware.camera.autofocus"
        android:required="false" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  1. check or request permissions by
  private void myStoragePermission() {
        if (ContextCompat.checkSelfPermission(Activity_Scan_QR.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            myCameraPermission();
        } else {
            //changed here
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
            }
        }
    }

    //+10 changed its sinature as Fragment; without it  onRequestPermissionsResult won't bbe called
    private void myCameraPermission() {
        if (ContextCompat.checkSelfPermission(Activity_Scan_QR.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            takePicture();
        } else {
            //changed here
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
            }
        }
    }

  1. add onRequestPermissionsResult
 @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case REQUEST_WRITE_PERMISSION:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    myStoragePermission();
                } else {

                    showSnackbar(R.string.act_ScanQR_txt13, R.string.settings,
                            new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    // Build intent that displays the App settings screen.
                                    Intent intent = new Intent();
                                    intent.setAction(
                                            Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    Uri uri = Uri.fromParts("package",
                                            BuildConfig.APPLICATION_ID, null);
                                    intent.setData(uri);
                                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(intent);
                                }
                            });
                }
            case REQUEST_CAMERA_PERMISSION:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    takePicture();
                } else {

                    showSnackbar(R.string.act_ScanQR_txt14, R.string.settings,
                            new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    // Build intent that displays the App settings screen.
                                    Intent intent = new Intent();
                                    intent.setAction(
                                            Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    Uri uri = Uri.fromParts("package",
                                            BuildConfig.APPLICATION_ID, null);
                                    intent.setData(uri);
                                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(intent);
                                }
                            });

                }
        }
    }

in above code takePicture(); is where I call for intent (start intent) , upon getting both the Storage and Camera permissions.

Don't get confused by reading a lot on error ;)

For future references, if someone encounters the problem in flutter related android projects:

https://github.com/apptreesoftware/flutter_barcode_reader/issues/32#issuecomment-420516729

In case anyone else get's this issue, my problem was that the app wasn't requesting any permissions when I ran it. It seems xiaomi devices automatically deny permissions to apps installed through adb. I just enabled the permissions through settings and it worked.

In case you need to keep

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

permission in manifest, just make sure it is granted before opening system camera. In modern android, you can do that like this:

   val cameraPermissionResult =
    registerForActivityResult(ActivityResultContracts.RequestPermission()) { permitted ->
        if (permitted) {
            openSystemCamera()
        }
    }

You can use cameraPermissionResult as follows:

cameraPermissionResult.launch(Manifest.permission.CAMERA)

If your app has already that permission granted it will just call openSystemCamera() without any user action required. In other case permission dialog will be shown and system camera will be opened based on permission user chooses.

I'm quite late but please check this because there's always some update

As per official developer page - https://developer.android.com/training/camera/photobasics , you don't need to use uses-permission in Manifest.xml instead use uses-feature :

<uses-feature
    android:name="android.hardware.camera"
    android:required="false" />

Notice - it's uses-feature , not uses-permission ,

Check properly, if you are using uses-permission and uses-feature both at the same, possibly you will the same crash (this note is most important then updated content from official page, because i used both of the params at the same time and faced this crash, also when i started working on camera module in my app, i don't know why i wasn't faced this issue but now app just started crashing suddenly)

more info about android:required from developer page :

If your application uses, but does not require a camera in order to function, instead set android:required to false. In doing so, Google Play will allow devices without a camera to download your application. It's then your responsibility to check for the availability of the camera at runtime by calling hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY). If a camera is not available, you should then disable your camera features.

in your androidManifest, you have to add :

 <uses-feature android:name="android.hardware.camera" />

here is an full Manifest example of android camera project

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