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

12

53

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);
                }
            }
        }
    });
Lechery answered 13/3, 2016 at 17:17 Comment(3)
Possible duplicate of Android M Camera Intent + permission bug?Cindy
@DougStevenson, It's a Nexus 5, does it occur on this device?Lechery
It's not about the device, it's about changes made in Android M. If the reference question doesn't help you, feel free to ignore it.Cindy
L
87

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.

Livelihood answered 21/9, 2017 at 16:48 Comment(7)
Strange how removing the permission, actually removed the error for requiring permission!!!!Gamely
Its work on Android N, but use @Saveen first answer as permission on your manifest. Tested by meMarybelle
Plus one from me, your answer is the only one that worked for me.. It's weird though!Patty
OMG! seriously It is working. Although from starting phase of development I was to add this line in menifest.Burden
But my app has both like call Camera through Intent and also like inbuilt camera. Giving permission make working Inbuilt and without permission Intent camera is workingSchwaben
Strange, but it worked for me too.. However in my case I removed that and replaced it with <uses-feature android:name="android.hardware.camera" android:required="false" />Hirsute
@ArnoldBrown so did you replaced intent fire with your custom camera impl. to cater this issue? I am also facing the same case.Haim
C
28

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).

Comitia answered 13/3, 2016 at 17:24 Comment(8)
The call to the camera in not in the main activity, should I still place the methods in the main activity?Lechery
Yes, you can call this permission in first activity.Comitia
Tried it, did not help.Lechery
can you try it once #26377671Comitia
this exception is only for Android M, Just pass proper camera permission and whenever application start one popup will appear need to do yes,then you'll get permission to use camera things in your app.Comitia
Still get the exception.Lechery
I have tested in Nexus 5 with Android MComitia
Let us continue this discussion in chat.Comitia
G
25

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.

Gorgonian answered 14/7, 2020 at 8:2 Comment(0)
C
15

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.sstatic.net/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.sstatic.net/dJ8wG.pngEnjoy

Now you can use your camera on your emulator :)

Carrasco answered 1/11, 2017 at 19:2 Comment(1)
Worked for me :)Congratulate
Y
9
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);
}
Yulma answered 31/8, 2018 at 6:22 Comment(1)
This is the most up to date answer that works with the "dangerous permissions" release on v6 (marshmallow)Martijn
K
3

As some have pointed out, one solution is removing the Camera Permission from AndroidManifest.xml, i.e., 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" />
Kosak answered 15/9, 2020 at 23:35 Comment(1)
it doesn't work, but it seems like requesting permission as usual worksBattista
T
2

short answer ...its looking for permissions , upon failing permissions it throws exception ; moreover in this case its looking for Two Permissions i.e. 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 ;)

Torrance answered 27/6, 2020 at 16:40 Comment(0)
A
2

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 time, possibly your app will 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.

Argot answered 22/3, 2022 at 13:51 Comment(1)
You're right, when using both <uses-permission> and <uses-feature>, my app crashes on API 26. But if I don't have <uses-permission> then I can't implement camera preview in my app along with MediaStore.ACTION_IMAGE_CAPTURE intent. It's crazy.Disappointed
N
0

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

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

Naze answered 12/9, 2018 at 5:28 Comment(0)
C
0

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.

Chloromycetin answered 16/7, 2019 at 11:25 Comment(0)
S
0

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.

Shortridge answered 20/1, 2022 at 12:51 Comment(0)
S
-10

in your androidManifest, you have to add :

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

here is an full Manifest example of android camera project

Sicular answered 13/3, 2016 at 17:24 Comment(1)
This is not what the question is looking for. This line should be added to the Manifest if you are using the Camera inside your app, not calling other Camera App and wait for a result.Ul

© 2022 - 2024 — McMap. All rights reserved.