简体   繁体   English

Android:权限拒绝:以撤销权限启动 Intent android.permission.CAMERA

[英]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.我正在尝试启动ACTION_IMAGE_CAPTURE活动以在我的应用程序中拍照,但我收到了主题错误。

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:相机权限被添加到 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" />

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.我在android 7中执行我的应用程序时遇到了这个错误。经过测试,我注意到用户权限不在项目A中,而是在项目B中,我只在android 5设备中进行了测试。 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.因此,我删除了项目 B 中的该权限,以便在其他针对 android 7 的设备上运行它并最终可以打开。

In adittion I added the fileprovider code that Android suggests here https://developer.android.com/training/camera/photobasics.html Hope this helps.另外,我添加了 Android 在此处建议的文件提供程序代码https://developer.android.com/training/camera/photobasics.html希望这会有所帮助。

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.我在这里添加了 kotlin。

Step 1. Declare this as global variable or any where.步骤 1. 将其声明为全局变量或任何位置。

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.第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.步骤 3. 权限拒绝对话框。 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).希望这会帮助你(Y)。

In my case the problem was related to my emulator permissions ,就我而言,问题与我的模拟器权限有关,

To fix the issue :要解决此问题:

1- Go to Settings of your emulator. 1-转到模拟器的设置。

2- Look for Apps and Notifications. 2- 寻找应用程序和通知。

3- Click on Add Permission. 3- 单击添加权限。

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

4- Select Camera of the list. 4- 选择列表中的相机。

5- Look for your Application in the provided list. 5- 在提供的列表中查找您的应用程序。

6- Enable Camera. 6-启用相机。

see the pic : https://i.stack.imgur.com/dJ8wG.pngEnjoy看图片: 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.首先,我认为当您尝试在没有完全权限的情况下使用设备相机(SDK < 26)时会出现问题。

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来自 Android Docs 的这些信息可能真的很有帮助

If your application uses, but does not require a camera in order to function, instead set android:required to false .如果您的应用程序使用但不需要摄像头才能运行,请将android:required设置为false In doing so, Google Play will allow devices without a camera to download your application.这样一来,Google Play 将允许没有摄像头的设备下载您的应用程序。 It's then your responsibility to check for the availability of the camera at runtime by calling hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY) .然后,您有责任通过调用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:在你的OnCreate添加这个:

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:正如一些人所指出的,一种解决方案是从 AndroidManifest.xml 中删除相机权限,即删除以下行:

<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.长答案.....给它权限写入方式以在所有版本的 Android 上工作。我正在循环获取权限存储和相机,以便它可以与 Intent 一起使用。

  1. maintain in AndroidManifest.xml在 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添加 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();在上面的代码中 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:供以后参考,如果有人在flutter相关的android项目中遇到问题:

https://github.com/apptreesoftware/flutter_barcode_reader/issues/32#issuecomment-420516729 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.似乎小米设备会自动拒绝通过 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:在现代 android 中,你可以这样做:

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

You can use cameraPermissionResult as follows:您可以使用 cameraPermissionResult 如下:

cameraPermissionResult.launch(Manifest.permission.CAMERA)

If your app has already that permission granted it will just call openSystemCamera() without any user action required.如果您的应用程序已经授予该权限,它将只调用openSystemCamera() ,而无需任何用户操作。 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 :根据官方开发者页面 - https://developer.android.com/training/camera/photobasics ,您无需在Manifest.xml中使用uses-permission而是使用uses-feature

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

Notice - it's uses-feature , not uses-permission ,注意- 它是uses-feature ,而不是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)检查正确,如果您同时使用uses-permissionuses-feature ,则可能会发生相同的崩溃(此注释最重要,然后是官方页面的更新内容,因为我同时使用了这两个参数并且面对这个崩溃,当我开始在我的应用程序中处理相机模块时,我不知道为什么我没有遇到这个问题,但现在应用程序突然开始崩溃)

more info about android:required from developer page :有关android:required的更多信息来自开发者页面:

If your application uses, but does not require a camera in order to function, instead set android:required to false.如果您的应用程序使用但不需要摄像头来运行,请将 android:required 设置为 false。 In doing so, Google Play will allow devices without a camera to download your application.这样一来,Google Play 将允许没有摄像头的设备下载您的应用程序。 It's then your responsibility to check for the availability of the camera at runtime by calling hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY).然后,您有责任通过调用 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 :在您的 androidManifest 中,您必须添加:

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

here is an full Manifest example of android camera project 是android相机项目的完整清单示例

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

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