【问题标题】:Android: "Permission Error" on Capture using CameraAndroid:使用相机拍摄时出现“权限错误”
【发布时间】:2022-02-17 22:22:31
【问题描述】:

在 Android 中,相机操作显示错误:

java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=android/com.android.internal.app.ResolverActivity } from ProcessRecord{beb99ec 32121:com.android.hawee/u0a369} (pid=32121, uid=10369) with revoked permission android.permission.CAMERA
                                                                       at android.os.Parcel.readException(Parcel.java:1620)

我请求清单的权限如下

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

在选择器对话框上点击相机

 if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, Constants.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE);
                } else {
                    Intent camera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                    activity.startActivityForResult(camera, Constants.IMAGE_CAPTURE_CAMERA);
                }

活动中

 @SuppressLint("NewApi")
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.frameContainer);
        fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

在片段上

public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        if (requestCode == Constants.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
                Intent camera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(camera, Constants.IMAGE_CAPTURE_CAMERA);
            } else {
                new CommonDialogOK(getActivity(), getString(R.string.Sorry), getString(R.string.Permissions_Not_Granted));
            }
        } else if (requestCode == Constants.PICK_IMAGE_PERMISSIONS_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Intent gallery = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(gallery, Constants.IMAGE_CAPTURE_GALLERY);
            } else {
                new CommonDialogOK(getActivity(), getString(R.string.Sorry), getString(R.string.Permissions_Not_Granted));
            }
        }
    }

但是从 ChooserDialog 中单击时总是出现上述错误。 如何同时请求写入外部和图像捕获的权限。

【问题讨论】:

  • 您实际上不需要CAMERA 权限即可通过Intent 拍照。但是,如果您在清单中列出该权限,如果未授予该权限,它将抛出该异常,以免混淆可能手动从您的应用中撤消该权限的用户。您可以简单地删除该 &lt;uses-permission&gt; 元素以及该特定请求的代码。

标签: android local-storage android-permissions android-image-capture


【解决方案1】:

如果您的应用同时需要摄像头和外部存储,您应该在 if 条件下|| 它们。

 if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, Constants.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE);
                } else {
                    Intent camera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                    activity.startActivityForResult(camera, Constants.IMAGE_CAPTURE_CAMERA);
                }

【讨论】:

    【解决方案2】:

    试试这个:-

    public static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1;
    

    在 onCreate() 中

    private void checkAndroidVersion() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                checkAndRequestPermissions();
    
            } 
    
        }
    

    这个方法

    private boolean checkAndRequestPermissions() {
            int camera = ContextCompat.checkSelfPermission(getActivity(),
                    Manifest.permission.CAMERA);
            int wtite = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
            int read = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE);
            List<String> listPermissionsNeeded = new ArrayList<>();
            if (wtite != PackageManager.PERMISSION_GRANTED) {
                listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            }
            if (camera != PackageManager.PERMISSION_GRANTED) {
                listPermissionsNeeded.add(Manifest.permission.CAMERA);
            }
            if (read != PackageManager.PERMISSION_GRANTED) {
                listPermissionsNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
            }
            if (!listPermissionsNeeded.isEmpty()) {
                ActivityCompat.requestPermissions(getActivity(), listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
                return false;
            }
            return true;
        }
    

    那就用这个

    @Override
        public void onRequestPermissionsResult(int requestCode,
                                               String permissions[], int[] grantResults) {
            Log.d("in fragment on request", "Permission callback called-------");
            switch (requestCode) {
                case REQUEST_ID_MULTIPLE_PERMISSIONS: {
    
                    Map<String, Integer> perms = new HashMap<>();
                    // Initialize the map with both permissions
                    perms.put(Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED);
                    perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
                    perms.put(Manifest.permission.READ_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
                    // Fill with actual results from user
                    if (grantResults.length > 0) {
                        for (int i = 0; i < permissions.length; i++)
                            perms.put(permissions[i], grantResults[i]);
                        // Check for both permissions
                        if (perms.get(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
                                && perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                            Log.d("in fragment on request", "CAMERA & WRITE_EXTERNAL_STORAGE READ_EXTERNAL_STORAGE permission granted");
                            // process the normal flow
                            //else any one or both the permissions are not granted
                        } else {
                            Log.d("in fragment on request", "Some permissions are not granted ask again ");
                            //permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
    //                        // shouldShowRequestPermissionRationale will return true
                            //show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
                            if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) || ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)) {
                                showDialogOK("Camera and Storage Permission required for this app",
                                        new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                switch (which) {
                                                    case DialogInterface.BUTTON_POSITIVE:
                                                        checkAndRequestPermissions();
                                                        break;
                                                    case DialogInterface.BUTTON_NEGATIVE:
                                                        // proceed with logic by disabling the related features or quit the app.
                                                        break;
                                                }
                                            }
                                        });
                            }
                            //permission is denied (and never ask again is  checked)
                            //shouldShowRequestPermissionRationale will return false
                            else {
                                Toast.makeText(getActivity(), "Go to settings and enable permissions", Toast.LENGTH_LONG)
                                        .show();
                                //                            //proceed with logic by disabling the related features or quit the app.
                            }
                        }
                    }
                }
            }
    
        }
    
        private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
            new AlertDialog.Builder(getActivity())
                    .setMessage(message)
                    .setPositiveButton("OK", okListener)
                    .setNegativeButton("Cancel", okListener)
                    .create()
                    .show();
        }
    

    当你保存个人资料时,最后点击按钮

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (!checkAndRequestPermissions()) {
    
                }
                else {
                    // do your stuff here
                }
    
            } else {
                // do your stuff here
            }
    

    【讨论】:

      【解决方案3】:

      试试这个代码:

      为了检查权限,我创建了一个单独的类,如下所示:

      public class MarshMallowPermission {
      
      public static final int RECORD_PERMISSION_REQUEST_CODE = 1;
      public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE = 2;
      public static final int CAMERA_PERMISSION_REQUEST_CODE = 3;
      Activity activity;
      
      public MarshMallowPermission(Activity activity) {
          this.activity = activity;
      }
      
      public boolean checkPermissionForRecord(){
          int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO);
          if (result == PackageManager.PERMISSION_GRANTED){
              return true;
          } else {
              return false;
          }
      }
      
      public boolean checkPermissionForExternalStorage(){
          int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
          if (result == PackageManager.PERMISSION_GRANTED){
              return true;
          } else {
              return false;
          }
      }
      
      public boolean checkPermissionForCamera(){
          int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
          if (result == PackageManager.PERMISSION_GRANTED){
              return true;
          } else {
              return false;
          }
      }
      
      public void requestPermissionForRecord(){
          if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.RECORD_AUDIO)){
             Toast.makeText(activity, "Microphone permission needed for recording. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
          } else {
              ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.RECORD_AUDIO},RECORD_PERMISSION_REQUEST_CODE);
          }
      }
      
      public void requestPermissionForExternalStorage(){
          if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
              Toast.makeText(activity, "External Storage permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
          } else {
              ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
          }
      }
      
      public void requestPermissionForCamera(){
          if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)){
              Toast.makeText(activity, "Camera permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
          } else {
              ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.CAMERA},CAMERA_PERMISSION_REQUEST_CODE);
          }
      }
       }
      

      然后

      MarshMallowPermission marshMallowPermission = new 
      MarshMallowPermission(this);
      
      
       public void getPhotoFromCamera() {
      
      if (!marshMallowPermission.checkPermissionForCamera()) {
          marshMallowPermission.requestPermissionForCamera();
      } else {
          if (!marshMallowPermission.checkPermissionForExternalStorage()) {
              marshMallowPermission.requestPermissionForExternalStorage();
          } else {
              Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
              File mediaStorageDir = new File(
                      Environment.getExternalStorageDirectory()
                              + File.separator
                              + getString(R.string.directory_name_corp_chat)
                              + File.separator
                              + getString(R.string.directory_name_images)
              );
      
              if (!mediaStorageDir.exists()) {
                  mediaStorageDir.mkdirs();
              }
      
              String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
                      Locale.getDefault()).format(new Date());
              try {
                  mediaFile = File.createTempFile(
                          "IMG_" + timeStamp,  /* prefix */
                          ".jpg",         /* suffix */
                          mediaStorageDir      /* directory */
                  );
                  takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mediaFile));
                  startActivityForResult(takePictureIntent, PICK_FROM_CAMERA);
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
      }
      

      【讨论】:

      • 不完整,如果我拒绝权限则不起作用
      【解决方案4】:

      答案需要更多点赞,应该是关于相机权限的官方答案,其他答案在 Android 10 上没有解决问题。

      我们如何知道,适用于新版本的答案/代码适用于旧版本。

      帮助我们索引这个答案:

      if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                          ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, Constants.CAMERA_CAPTURE_PERMISSIONS_REQUEST_CODE);
                      } else {
                          Intent camera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                          activity.startActivityForResult(camera, Constants.IMAGE_CAPTURE_CAMERA);
                      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-02
        • 1970-01-01
        相关资源
        最近更新 更多