You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:11:12