Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - Camera permissions denied without prompting

I was running into issues with the manual process behind requesting permissions (just kept falling into the 'denied' code), so I switched over to using Dexter to simplify. I implemented the following code in onCreate(), and I did a fresh install of the app:

Dexter.withActivity(this)
            .withPermission(Manifest.permission.CAMERA)
            .withListener(new PermissionListener() {
                @Override public void onPermissionGranted(PermissionGrantedResponse response) {
                    Log.d(TAG, "GRANTED!");
                    initCamera();
                }
                @Override public void onPermissionDenied(PermissionDeniedResponse response) {
                    Log.d(TAG, "DENIED!");
                }
                @Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
                    Log.d(TAG, "PERMISSION RATIONAL SHOULD BE SHOWN!");

                }
            }).check();

It immediately falls into the "DENIED!" log, and it never even prompts me. I tried this particular code to attempt multiple permissions (which is ultimately what I need to do):

Dexter.withActivity(activity)
            .withPermissions(Manifest.permission.CAMERA,
                    Manifest.permission.RECORD_AUDIO,
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)
            .withListener(new MultiplePermissionsListener() {
                @Override
                public void onPermissionsChecked(MultiplePermissionsReport report) {
                    Log.d(TAG, "Accepted: " + report.getGrantedPermissionResponses().size() + " | Denied: " + report.getDeniedPermissionResponses().get(0).getPermissionName());
                }

                @Override
                public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
                    Log.d(TAG, "continuing permissions request..");

                    token.continuePermissionRequest();
                }
            })
            .check();

It prompts for permissions to Record Audio, then it asks about Access to photos/media/files on the device (it never asks about Camera). Then once that's done, it prints the log: "Accepted 3 | Denied: android.permission.CAMERA". It denies it without even prompting me again.

My Manifest is set properly to have CAMERA in the proper place (outside of the 'application' tag). See below for reference:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.my.app">

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

<permission
    android:name="${applicationId}.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

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

Odd thing is that when I go into Settings > Applications > MyApp, the Camera option is not even displayed in there.

I don't think it's an issue with Dexter, since it's doing basically the same thing when I set it up manually (and I confirmed that it's definitely setup properly in that case after looking at a few top S.O. posts).

Any thoughts on what the issue could be here? FYI - I'm using a Galaxy S6, OS 6.0.2. The other users experiencing this seem to be other devices with 6.0+ OS. Thanks in advance!

EDIT: Testing various devices, it works on some and does not work on some:

  • Moto X (OS 5.0) - Broken
  • Nexus 5 (OS 7.0) - Works
  • Samsung S6 (OS 6.0.1) - Broken
  • Broken Moto X (OS 6.0) - Works

Doesn't seem to be a solid pattern.. Definitely strange. I also started a brand new project and ran the same code - worked fine and allowed access to my camera. So it doesn't appear to be fully device-specific..

like image 458
svguerin3 Avatar asked Apr 04 '17 16:04

svguerin3


2 Answers

The issue with this turned out to be a third-party library, which had this line in their Manifest, overriding our own permission:

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

The solution was either to manually import their project as a module (rather than use gradle), and then comment out that line, OR more simple - you can add "tools:node="replace"" to the end of the main project's CAMERA permission line, and it works fine after that; no need to import the project with the latter approach.

like image 114
svguerin3 Avatar answered Nov 18 '22 01:11

svguerin3


What you need is native runtime permissions not dexter, Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process, since the user does not need to grant permissions when they install or update the app. It also gives the user more control over the app's functionality; for example, a user could choose to give a camera app access to the camera but not to the device location. The user can revoke the permissions at any time, by going to the app's Settings screen.

// Assume thisActivity is the current activity int permissionCheck = ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.YOUR_PERMISSION);

then what you need is to request a certain permission if that check is false,

 ActivityCompat.requestPermissions(thisActivity,
            new String[]{Manifest.permission.YOUR_PERMISSION},
            MY_PERMISSION_CODE);

Bare in ind that you need to as well declare them also in the manifest, based on what you have shown still that was already done. For more information.

like image 32
Remario Avatar answered Nov 18 '22 00:11

Remario