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

Android 12+应用启动相机偶发崩溃,无日志且调试器断开

Android 12+ 相机偶发崩溃问题排查与修复

一、先修正致命的权限检查逻辑错误

当前权限检查代码完全颠倒,导致你无法正确判断相机权限状态,这是引发权限误判的核心原因:

// 错误代码逻辑:判断未授权时,却打印"Permission granted"
if (ContextCompat.checkSelfPermission(DocCollectionActivity.this,
                        Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED) {
                    Log.e(TAG, "onCameraClickListener: Permission granted");
                }

正确的权限处理方式

// 1. 检查相机权限
if (ContextCompat.checkSelfPermission(DocCollectionActivity.this, Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED) {
    Log.e(TAG, "onCameraClickListener: 相机权限未授权");
    // 发起权限申请
    registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
        if (isGranted) {
            launchCamera(); // 权限通过后启动相机
        } else {
            // 处理权限拒绝逻辑,比如引导用户到设置页开启
        }
    }).launch(Manifest.permission.CAMERA);
} else {
    Log.d(TAG, "onCameraClickListener: 相机权限已授权");
    launchCamera();
}

// 2. 特殊权限 MANAGE_APP_ALL_FILES_ACCESS_PERMISSION 的单独处理
if (!Environment.isExternalStorageManager()) {
    Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
    intent.setData(Uri.parse("package:" + getPackageName()));
    startActivity(intent);
}

二、适配Android 12+ 相机文件输出URI

直接传递自定义URI给MediaStore.EXTRA_OUTPUT,在Android 12+会因文件权限限制导致相机无法写入,进而引发偶发崩溃。改用FileProvider生成安全URI是标准解决方案:

1. 注册FileProvider(AndroidManifest.xml)

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

2. 创建文件路径配置(res/xml/file_paths.xml)

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="camera_photos" path="Pictures/" />
</paths>

3. 修改图片URI生成逻辑

public static Uri setImageUri(Context context) {
    // 用应用私有目录存储临时照片,避免权限问题
    File photoDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File photoFile = new File(photoDir, "temp_camera_photo_" + System.currentTimeMillis() + ".jpg");
    return FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", photoFile);
}

4. 启动相机时添加URI临时授权

private void launchCamera() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    Uri photoUri = GeneralFunctions.setImageUri(DActivity.this);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);

    // 给相机应用授予临时读写权限,避免写入失败
    List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    for (ResolveInfo resolveInfo : resInfoList) {
        String packageName = resolveInfo.activityInfo.packageName;
        grantUriPermission(packageName, photoUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }

    startActivityForResult(intent, ConstantVariables.IMAGE_REQUEST_CODE);
}

三、调试器断开&无日志问题排查

偶发崩溃且调试器断开,大概率是Native层崩溃,Java层Logcat不会输出相关日志,可通过以下方式排查:

  • 打开Logcat的No Filters过滤器,查看系统级崩溃日志(标记崩溃进程的DEBUG/ERROR日志);
  • 若设备已root,可读取/data/tombstones目录下的崩溃 tombstone 文件,分析Native层崩溃原因;
  • 在build.gradle中开启Native调试开关:
    android {
        buildTypes {
            debug {
                debuggable true
                jniDebuggable true
            }
        }
    }
    

内容的提问来源于stack exchange,提问作者komal Mane

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 15:43:23