Android请求相机权限时应用闪退,授权后恢复的问题排查与修复
问题原因
- 核心问题是**
checkPermissionAndOpenCamera()方法逻辑错误**:当相机权限未授予时,代码先发起权限请求,但未终止后续流程,紧接着就执行startActivityForResult()启动相机Intent。此时因缺少相机权限,系统会强制终止当前应用进程以处理权限申请,所以出现“应用先关闭,再弹出权限对话框”的现象。 - 额外问题:权限请求码
storageRequestCode、相机请求码cameraRequestCode未在代码中定义,且onRequestPermissionsResult中的请求码判断与实际发起请求时的变量不匹配,存在逻辑混淆。
修复方案
1. 修正权限判断逻辑
仅在权限已授予时启动相机Intent,权限未授予时仅发起权限请求:
private void checkPermissionAndOpenCamera() { if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(getActivity(), new String[] {Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE); } else { // 权限已授予,执行相机启动逻辑 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, CAMERA_REQUEST_CODE); } }
2. 统一请求码常量
在Fragment类中定义全局常量,避免硬编码和逻辑混淆:
// 在CameraFragment类顶部添加常量定义 private static final int CAMERA_REQUEST_CODE = 100;
3. 修正权限回调逻辑
确保回调中的请求码判断与发起请求时一致,同时处理权限被拒绝的场景:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == CAMERA_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限授予成功,启动相机 checkPermissionAndOpenCamera(); } else { // 权限被拒绝,提示用户 Toast.makeText(getContext(), "需要相机权限才能使用拍照功能", Toast.LENGTH_SHORT).show(); } } }
4. 优化拍照结果处理逻辑
添加空值判断,避免拍照取消或异常导致的空指针:
@Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == CAMERA_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) { Bitmap capturedImage = (Bitmap) data.getExtras().get("data"); if (capturedImage != null) { imageIv.setImageBitmap(capturedImage); } } }
5. 补充变量定义
确保Fragment中的控件变量正确声明:
// 在CameraFragment类中添加变量定义 private Button takePicture; private ImageView imageIv;
关键说明
权限请求是异步流程,发起请求后必须等待用户操作完成(通过onRequestPermissionsResult回调),才能执行需要权限的操作,不能在发起请求后直接执行后续逻辑。同时必须处理权限被拒绝的场景,给用户明确的操作提示。
内容的提问来源于stack exchange,提问作者AKD2022
相关产品推荐
相关产品推荐

