Android 9启动相机崩溃:ScanLibrary应用动态权限申请问题排查
Android 9下ScanLibrary启动相机崩溃的权限解决方案
嘿,我仔细看了你的问题和堆栈日志,核心原因已经很清楚了:你没有在代码中实现动态权限申请流程。虽然你手动在设置里开了权限,但Android 6.0(API级别23)及以上系统要求,危险权限(比如相机、存储)必须在App运行时主动向用户申请,仅在Manifest里声明是不够的——这就是为什么你在Android KitKat(API19,不需要动态权限)没问题,但Android9(API28)直接崩溃的原因。
requestLegacyExternalStorage="true" 是用来适配Android 10+的分区存储机制的,和你当前的相机权限崩溃无关,所以加了也没用。
下面是具体的解决步骤和代码修改建议:
步骤1:在PickImageFragment中添加权限检查与申请逻辑
你需要在调用openCamera()之前,先检查相机权限是否已经授予,如果没有就主动申请:
首先,定义需要申请的权限数组:
private static final int PERMISSIONS_REQUEST_CODE = 100; private String[] REQUIRED_PERMISSIONS = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
然后添加权限检查方法:
private boolean hasAllPermissions() { for (String permission : REQUIRED_PERMISSIONS) { if (ContextCompat.checkSelfPermission(getActivity(), permission) != PackageManager.PERMISSION_GRANTED) { return false; } } return true; } private void requestPermissions() { ActivityCompat.requestPermissions(getActivity(), REQUIRED_PERMISSIONS, PERMISSIONS_REQUEST_CODE); }
步骤2:修改handleIntentPreference()方法,确保先拿权限再启动相机
把原来直接调用openCamera()的逻辑改成先检查权限:
private void handleIntentPreference() { int preference = getIntentPreference(); if (preference == ScanConstants.OPEN_CAMERA) { if (hasAllPermissions()) { openCamera(); } else { requestPermissions(); } } else if (preference == ScanConstants.OPEN_MEDIA) { if (hasAllPermissions()) { openMediaContent(); } else { requestPermissions(); } } }
步骤3:处理权限申请的回调结果
在PickImageFragment中重写权限回调方法,用户同意后再执行对应的操作:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PERMISSIONS_REQUEST_CODE) { boolean allGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allGranted = false; break; } } if (allGranted) { // 用户同意了所有权限,再次执行原来的操作 handleIntentPreference(); } else { // 用户拒绝了权限,这里可以弹提示告诉用户需要权限才能使用功能 Toast.makeText(getActivity(), "需要相机和存储权限才能继续", Toast.LENGTH_SHORT).show(); getActivity().finish(); } } }
额外说明
- 为什么手动开权限还不行?因为即使你在设置里开了权限,如果App在启动时没有通过代码确认权限状态,有些场景下系统还是会判定权限未被“主动授予”(比如App进程重启后)。
- 存储权限的申请:因为你要保存相机拍摄的图片,所以WRITE_EXTERNAL_STORAGE也是必须的,一起申请避免后续的存储权限问题。
这样修改后,App启动时会自动弹出权限申请弹窗,用户同意后就能正常调用相机了。
内容的提问来源于stack exchange,提问作者Ishak Benaissa
相关产品推荐
相关产品推荐

