Android:"Permission Error" 使用相机拍摄

Android: "Permission Error" on Capture using Camera

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

在 activity

 @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 中点击总是出现上述错误。 我如何请求同时写入外部和图像捕获的权限。

试试这个:-

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
        }

如果您的应用需要相机和外部存储器,您应该 || 在 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);
                }

试试这个代码:

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

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

答案需要更多的赞成票,应该是关于相机权限的官方答案,其他答案没有解决 Android 10.

上的问题

我们怎么知道,适用于新版本的 answers/codes 也适用于旧版本。

帮助我们索引这个答案:

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