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

Posted

技术标签:

【中文标题】Android:权限拒绝:以撤销权限启动 Intent android.permission.CAMERA【英文标题】:Android: Permission Denial: starting Intent with revoked permission android.permission.CAMERA 【发布时间】:2016-06-28 15:31:46 【问题描述】:

我正在尝试启动 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 ProcessRecord22b0eb2 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);
                
            
        
    );

【问题讨论】:

Android M Camera Intent + permission bug?的可能重复 @DougStevenson,这是一个 Nexus 5,它会出现在这个设备上吗? 这与设备无关,而是与 Android M 中所做的更改有关。如果参考问题对您没有帮助,请随时忽略它。 【参考方案1】:

删除此权限

  <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 希望这会有所帮助。

【讨论】:

奇怪怎么去掉权限,居然去掉了需要权限的错误!!! 它在 Android N 上工作,但使用 @Saveen 第一个答案作为清单的权限。经我测试 另外一个来自我,你的答案是唯一对我有用的答案。不过这很奇怪! 天啊!认真它正在工作。虽然从开发的开始阶段我就在清单中添加了这一行。 但是我的应用既喜欢通过 Intent 调用摄像头,也喜欢内置摄像头。给予许可使工作内置且未经许可意图相机正在工作【参考方案2】:

您可以在清单文件中将这些权限与其他权限一起使用,

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

【讨论】:

对相机的调用不在主活动中,我还应该将方法放在主活动中吗? 是的,您可以在第一个活动中调用此权限。 试过了,没用。 你可以试一次吗***.com/questions/26377171/… 你在开玩笑吗,我刚刚做了同样的例子,它工作正常这里是链接dropbox.com/s/w29sljy0zpwwm61/MyApplication.zip?dl=0【参考方案3】:

在我的情况下,问题与我的模拟器权限有关,

解决问题:

1- 转到模拟器的设置。

2- 查找应用和通知。

3- 点击添加权限。

见图片:https://i.stack.imgur.com/z4GfK.png

4- 选择列表中的相机。

5- 在提供的列表中查找您的应用程序。

6- 启用相机。

见图片:https://i.stack.imgur.com/dJ8wG.pngEnjoy

现在您可以在模拟器上使用相机了 :)

【讨论】:

为我工作:)【参考方案4】:

这是我的解决方法:

首先,我认为当您尝试在没有完整权限的情况下(SDK

是的,即使您已经包含此权限:

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

为了解决这个问题,我将 that 更改为 this

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

来自 Android Docs 的这些信息可能真的很有帮助

如果您的应用程序使用但不需要摄像头来运行,请将android:required 设置为false。这样做时,Google Play 将允许没有摄像头的设备下载您的应用程序。然后,您有责任通过调用hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY) 在运行时检查相机的可用性。如果相机不可用,则应禁用相机功能。

【讨论】:

【参考方案5】:
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);

【讨论】:

这是最新的答案,适用于 v6 (marshmallow) 上的“危险权限”版本【参考方案6】:

正如一些人所指出的,一种解决方案是从 AndroidManifest.xml 中删除相机权限,即 remove 这一行:

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

但是,这对我来说还不够,因为我需要相机权限才能在我的应用中使用其他东西。所以对我有用的是将该权限标记为不需要,如下所示:

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

【讨论】:

【参考方案7】:

简短回答 ...它正在寻找权限,如果权限失败,它会抛出异常;此外,在这种情况下,它正在寻找两个权限,即第一个存储和第二个摄像头。

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

    在 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" />
    检查或请求权限
  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);
            
        
    

    添加 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();是我在获得存储和相机权限后调用意图(开始意图)的地方。

不要因阅读大量错误而感到困惑;)

【讨论】:

【参考方案8】:

供以后参考,如果有人在flutter相关的android项目中遇到问题:

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

【讨论】:

【参考方案9】:

万一其他人遇到这个问题,我的问题是应用程序在我运行时没有请求任何权限。似乎小米设备自动拒绝通过 adb 安装的应用程序的权限。我刚刚通过设置启用了权限,它起作用了。

【讨论】:

【参考方案10】:

如果你需要保留

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

清单中的权限,只需确保在打开系统摄像头之前已授予权限。 在现代 android 中,您可以这样做:

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

您可以按如下方式使用cameraPermissionResult:

cameraPermissionResult.launch(Manifest.permission.CAMERA)

如果您的应用已获得该权限,它只会调用openSystemCamera(),而无需任何用户操作。 在其他情况下,将显示权限对话框并根据用户选择的权限打开系统摄像头。

【讨论】:

【参考方案11】:

在您的 androidManifest 中,您必须添加:

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

here 是一个完整的 android 相机项目的 Manifest 示例

【讨论】:

这不是问题要找的。如果您在应用程序中使用相机,则应将此行添加到清单中,而不是调用其他相机应用程序并等待结果。

以上是关于Android:权限拒绝:以撤销权限启动 Intent android.permission.CAMERA的主要内容,如果未能解决你的问题,请参考以下文章

Android M:以编程方式撤销权限

Android M:以编程方式撤销权限

Android:java.lang.SecurityException:权限拒绝:启动意图

Android - java.lang.SecurityException:权限拒绝:启动意图

Android - 由于设置撤销了位置权限导致应用崩溃

如何判断android用户拒绝了某项权限?