Android: отказ в разрешении: запуск намерения с отозванным разрешением android.permission.CAMERA

Я пытаюсь запустить действие ACTION_IMAGE_CAPTURE, чтобы сделать снимок в моем приложении, и получаю сообщение об ошибке в теме.

Трассировки стека:

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

Разрешения камеры добавлены в файл manifest.xml, тьфу:

<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" />

Вот призыв открыть камеру:

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);
                }
            }
        }
    });

person David Faizulaev    schedule 13.03.2016    source источник
comment
Возможный дубликат Android M Camera Intent + ошибка разрешения?   -  person Doug Stevenson    schedule 13.03.2016
comment
@DougStevenson, это Nexus 5, на этом аппарате происходит?   -  person David Faizulaev    schedule 13.03.2016
comment
Дело не в устройстве, а в изменениях, внесенных в Android M. Если справочный вопрос вам не помогает, не обращайте на него внимания.   -  person Doug Stevenson    schedule 13.03.2016


Ответы (10)


привет, вы можете использовать это разрешение в своем файле манифеста с другим разрешением,

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

Если он все еще не работает, возможно, вы используете Android M, поэтому вам нужно программно добавить разрешения.

вот пример

привет, вот несколько шагов для настройки разрешения для Android M, и помните, что вы также должны объявить такое же разрешение в файле манифеста.

Шаг 1. Объявите глобальную переменную:

 public final int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 1;

//requests for runtime time permissions

 String CAMERA_PERMISSION = android.Manifest.permission.CAMERA;


 String READ_EXTERNAL_STORAGE_PERMISSION = android.Manifest.permission.READ_EXTERNAL_STORAGE;


String WRITE_EXTERNAL_STORAGE_PERMISSION = android.Manifest.permission.WRITE_EXTERNAL_STORAGE;


// for security permissions
@DialogType
private int mDialogType;
private String mRequestPermissions = "We are requesting the camera and Gallery permission as it is absolutely necessary for the app to perform it\'s functionality.\nPlease select \"Grant Permission\" to try again and \"Cancel \" to exit the application.";
private String mRequsetSettings = "You have rejected the camera and Gallery 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.\nPlease select \"Go to settings\" to go to application settings in your device and \"Cancel \" to exit the application.";
private String mGrantPermissions = "Grant Permissions";
private String mCancel = "Cancel";
private String mGoToSettings = "Go To Settings";
private String mPermissionRejectWarning = "Cannot Proceed Without Permissions</string>
<string name="explanation_permission_location_request">We are requesting the location permission as it is necessary for the app to perform search functionality properly.\nPlease select \"Grant Permission\" to try again and \"Cancel \" to deny permission.";

// создаем такой диалог.

// type of dialog opened in MainActivity
 @IntDef({DialogType.DIALOG_DENY, DialogType.DIALOG_NEVER_ASK})
 @Retention(RetentionPolicy.SOURCE)
 @interface DialogType {
    int DIALOG_DENY = 0, DIALOG_NEVER_ASK = 1;
 }

Шаг 2. Используйте этот код в своей основной деятельности.

@TargetApi(Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED && grantResults[2] == PackageManager.PERMISSION_GRANTED) {
                // Call your camera here.
            } else {
                boolean showRationale1 = shouldShowRequestPermissionRationale(CAMERA_PERMISSION);
                boolean showRationale2 = shouldShowRequestPermissionRationale(READ_EXTERNAL_STORAGE_PERMISSION);
                boolean showRationale3 = shouldShowRequestPermissionRationale(WRITE_EXTERNAL_STORAGE_PERMISSION);
                if (showRationale1 && showRationale2 && showRationale3) {
                    //explain to user why we need the permissions
                    mDialogType = ValueConstants.DialogType.DIALOG_DENY;
                    // Show dialog with 
                    openAlertDialog(mRequestPermissions, mGrantPermissions, mCancel, this, MyActivity.this);
                } else {
                    //explain to user why we need the permissions and ask him to go to settings to enable it
                    mDialogType = ValueConstants.DialogType.DIALOG_NEVER_ASK;
                    openAlertDialog(mRequsetSettings, mGoToSettings, mCancel, this, MyActivity.this);
                }
            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

//check for camera and storage access permissions
@TargetApi(Build.VERSION_CODES.M)
private void checkMultiplePermissions(int permissionCode, Context context) {

    String[] PERMISSIONS = {CAMERA_PERMISSION, READ_EXTERNAL_STORAGE_PERMISSION, WRITE_EXTERNAL_STORAGE_PERMISSION};
    if (!hasPermissions(context, PERMISSIONS)) {
        ActivityCompat.requestPermissions((Activity) context, PERMISSIONS, permissionCode);
    } else {
        // Open your camera here.
    }
}

private boolean hasPermissions(Context context, String... permissions) {
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
        for (String permission : permissions) {
            if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
    }
    return true;
}

Шаг 3. Вызовите этот метод в своем методе oncreate,

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            checkMultiplePermissions(REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS, MyActivity.this);
   } else {
            // Open your camera here.
   }

Шаг 4. Диалог для отказа в разрешении

public static void openAlertDialog(String message, String positiveBtnText, String negativeBtnText,
                            final OnDialogButtonClickListener listener,Context mContext) {

    AlertDialog.Builder builder = new AlertDialog.Builder(mContext, R.style.AlertDialogCustom);
    builder.setPositiveButton(positiveBtnText, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            dialogInterface.dismiss();
            listener.onPositiveButtonClicked();
        }
    });
    builder.setPositiveButton(positiveBtnText, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            dialogInterface.dismiss();
            listener.onNegativeButtonClicked();
        }
    });

    builder.setTitle(mContext.getResources().getString(R.string.app_name));
    builder.setMessage(message);
    builder.setIcon(android.R.drawable.ic_dialog_alert);
    builder.setCancelable(false);
    builder.create().show();
}

// Создаем этот интерфейс

public interface OnDialogButtonClickListener {

void onPositiveButtonClicked();

void onNegativeButtonClicked();
}

и реализуйте это в своей деятельности, где необходимо добавить разрешения.

@Override
public void onPositiveButtonClicked() {
    switch (mDialogType) {
        case ValueConstants.DialogType.DIALOG_DENY:
            checkMultiplePermissions(REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS, MyActivity.this);
            break;
        case ValueConstants.DialogType.DIALOG_NEVER_ASK:
            redirectToAppSettings(MyActivity.this);
            break;

    }
}

@Override
public void onNegativeButtonClicked() {

}

И любое разрешение, которое вы можете вызвать отсюда, и каждый результат, который вы можете получить в методе переопределения onRequestPermissionsResult этого.

Спасибо

надеюсь, это поможет вам (Y).

person Saveen    schedule 13.03.2016
comment
Вызов камеры не входит в основное действие, следует ли мне все же поместить методы в основное действие? - person David Faizulaev; 13.03.2016
comment
Да, вы можете вызвать это разрешение в первом действии. - person Saveen; 13.03.2016
comment
Пробовал, не помогло. - person David Faizulaev; 13.03.2016
comment
Можете ли вы попробовать это один раз stackoverflow.com/questions/26377171/ - person Saveen; 14.03.2016
comment
это исключение только для Android M. Просто передайте соответствующее разрешение камеры, и всякий раз, когда приложение запускается, появляется одно всплывающее окно, в котором нужно сделать «да», тогда вы получите разрешение на использование вещей камеры в своем приложении. - person Saveen; 14.03.2016
comment
По-прежнему получаю исключение. - person David Faizulaev; 14.03.2016
comment
Вы шутите, я только что сделал тот же пример, и он отлично работает, вот ссылка dropbox.com/s/w29sljy0zpwwm61/MyApplication.zip?dl=0 - person Saveen; 14.03.2016
comment
Я тестировал Nexus 5 с Android M - person Saveen; 14.03.2016
comment
Позвольте нам продолжить это обсуждение в чате. - person Saveen; 14.03.2016

Удалить это разрешение

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

Я столкнулся с этой ошибкой при выполнении своего приложения в Android 7. После тестов я заметил, что разрешения пользователя не было в проекте A, но оно было в проекте B, который я тестировал только на устройствах Android 5. Поэтому я удаляю это разрешение в проекте B, чтобы запустить его на другом устройстве, предназначенном для Android 7, и, наконец, он может открыться.

Кроме того, я добавил код файлового провайдера, который предлагает Android здесь https://developer.android.com/training/camera/photobasics.html Надеюсь, это поможет.

person jan4co    schedule 21.09.2017
comment
Странно, как сняв разрешение, на самом деле убрали ошибку с требованием разрешения !!!! - person sai; 20.01.2018
comment
Он работает на Android N, но используйте первый ответ @Saveen в качестве разрешения в своем манифесте. Проверено мной - person MrX; 07.02.2018
comment
Плюс один от меня, ваш ответ - единственный, который у меня сработал ... Хотя это странно! - person Yahya; 02.03.2018
comment
МОЙ БОГ! серьезно работает. Хотя с самого начала разработки я должен был добавить эту строчку в манифест. - person Ankit Dubey; 04.12.2019
comment
Но в моем приложении есть как вызов камеры через намерение, так и встроенная камера. Предоставление разрешения заставить работать Встроенный и без разрешения Камера намерения работает - person Arnold Brown; 24.02.2020
comment
Странно, но у меня это тоже сработало .. Однако в моем случае я удалил это и заменил на ‹uses-feature android: name = android.hardware.camera android: required = false /› - person Eddie; 19.05.2020
comment
Андроид 10, заработало - person BugliL; 04.12.2020

В моем случае проблема была связана с разрешениями моего эмулятора

Чтобы исправить проблему:

1- Зайдите в настройки вашего эмулятора.

2- Ищите приложения и уведомления.

3- Нажмите «Добавить разрешение».

см. изображение: https://i.stack.imgur.com/z4GfK.png

4- Выберите камеру из списка.

5- Найдите свое приложение в предоставленном списке.

6- Включить камеру.

см. изображение: https://i.stack.imgur.com/dJ8wG.pngEnjoy

Теперь вы можете использовать свою камеру на своем эмуляторе :)

person Monsif EL AISSOUSSI    schedule 01.11.2017
comment
Сработало у меня :) - person paulsm4; 17.02.2021

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"};

на вашем OnCreate добавьте это:

int requestCode = 200;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    requestPermissions(permissions, requestCode);
}
person saurabh yadav    schedule 31.08.2018
comment
Это самый последний ответ, который работает с опасным выпуском разрешений на v6 (зефир) - person Dan Anderson; 29.11.2018

Вот как я решил свою:

Прежде всего, я думаю, что проблема возникает, когда вы пытаетесь использовать камеру своего устройства на (SDK ‹26) без ПОЛНЫХ разрешений.

Да, даже если вы уже включили это разрешение:

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

Чтобы решить эту проблему, я изменил это на это:

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

Эта информация из Документов Android может быть действительно полезной

Если ваше приложение использует камеру, но не требует ее для работы, вместо этого установите android:required на false. При этом Google Play позволит устройствам без камеры загружать ваше приложение. Затем вы обязаны проверить доступность камеры во время выполнения, позвонив hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY). Если камера недоступна, вам следует отключить функции камеры.

person Favour Felix Chinemerem    schedule 14.07.2020

короткий ответ ... он ищет разрешения, при сбое разрешения выдает исключение; более того, в этом случае он ищет два разрешения, то есть первое хранилище и вторую камеру.

длинный ответ ..... Дайте ему разрешение на запись, чтобы он работал на всех версиях Android. Я зацикливаюсь, чтобы получить как хранилище разрешений, так и камеру, чтобы он работал с намерением.

  1. поддерживать в 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. проверить или запросить разрешения
  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. добавить 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);
                                }
                            });

                }
        }
    }

в приведенном выше коде takePicture (); Это то место, где я призываю к намерению (начальному намерению) после получения разрешений на хранилище и камеру.

Не запутайтесь, много читая об ошибках;)

person user17795    schedule 27.06.2020

Как отмечали некоторые, одним из решений является удаление разрешения камеры из AndroidManifest.xml, то есть удалить эту строку:

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

Однако для меня этого было недостаточно, поскольку мне требовалось разрешение камеры для чего-то еще в моем приложении. Что сработало для меня, так это пометить это разрешение как ненужное, например:

<uses-permission android:name="android.permission.CAMERA" android:required="false" />
person Chaulio Ferreira    schedule 15.09.2020

На будущее, если кто-то столкнется с проблемой в проектах Android, связанных с флаттером:

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

person Vidor Vistrom    schedule 12.09.2018

Если эта проблема возникла у кого-то еще, моя проблема заключалась в том, что приложение не запрашивало никаких разрешений, когда я его запускал. Кажется, что устройства xiaomi автоматически запрещают разрешения для приложений, установленных через adb. Я просто включил разрешения в настройках, и это сработало.

person Joseph Sang    schedule 16.07.2019

в вашем androidManifest вам нужно добавить:

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

здесь полный манифест пример проекта камеры android

person boblinux    schedule 13.03.2016
comment
Вопрос не в этом. Эту строку следует добавить в манифест, если вы используете камеру внутри своего приложения, а не вызываете другое приложение камеры и ждете результата. - person IgniteCoders; 10.05.2018