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

Android应用点击拍照按钮崩溃,相机权限相关问题求助

问题解决方案

1. 修正Manifest权限拼写错误

你的Manifest中READ_EXTERNAL_STORAGE权限的包名是大写的,Android权限名区分大小写,必须改为小写,否则权限声明无效:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

2. 添加动态权限申请(Android 6.0+ 强制要求)

仅在Manifest中声明危险权限(如相机、存储)不够,Android 6.0及以上系统需要在运行时向用户主动申请。在TrackFragment中添加权限检查与申请逻辑:

private final int CAMERA_REQ_CODE = 100;
private ImageView imgCamera;
// 定义需要申请的权限列表
private final String[] REQUIRED_PERMISSIONS = {
    Manifest.permission.CAMERA,
    Manifest.permission.READ_EXTERNAL_STORAGE,
    Manifest.permission.WRITE_EXTERNAL_STORAGE
};

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    imgCamera = view.findViewById(R.id.imgCamera);
    Button btnCamera = view.findViewById(R.id.btnCamera);

    btnCamera.setOnClickListener(v -> {
        // 先检查权限是否已授予
        if (hasAllPermissions()) {
            startCamera();
        } else {
            // 请求权限
            requestPermissions(REQUIRED_PERMISSIONS, CAMERA_REQ_CODE);
        }
    });
}

// 检查所有必需权限是否已授予
private boolean hasAllPermissions() {
    for (String permission : REQUIRED_PERMISSIONS) {
        if (ContextCompat.checkSelfPermission(requireContext(), permission) != PackageManager.PERMISSION_GRANTED) {
            return false;
        }
    }
    return true;
}

// 处理权限申请结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == CAMERA_REQ_CODE) {
        boolean allGranted = true;
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                allGranted = false;
                break;
            }
        }
        if (allGranted) {
            startCamera();
        } else {
            Toast.makeText(requireContext(), "需要相机和存储权限才能使用此功能", Toast.LENGTH_SHORT).show();
        }
    }
}

// 启动相机Intent,增加相机应用可用性检查
private void startCamera() {
    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // 确保有应用能处理这个Intent,避免崩溃
    if (cameraIntent.resolveActivity(requireContext().getPackageManager()) != null) {
        startActivityForResult(cameraIntent, CAMERA_REQ_CODE);
    } else {
        Toast.makeText(requireContext(), "未找到可用的相机应用", Toast.LENGTH_SHORT).show();
    }
}

3. 替换过时的startActivityForResult(推荐)

如果希望使用最新API替代已过时的方法,用registerForActivityResult重构相机结果回调:

private ActivityResultLauncher<Intent> cameraLauncher;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 注册相机结果回调
    cameraLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        result -> {
            if (result.getResultCode() == Activity.RESULT_OK) {
                Intent data = result.getData();
                if (data != null && data.getExtras() != null) {
                    Bitmap img = (Bitmap) data.getExtras().get("data");
                    imgCamera.setImageBitmap(img);
                }
            }
        }
    );
}

// 修改startCamera方法
private void startCamera() {
    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (cameraIntent.resolveActivity(requireContext().getPackageManager()) != null) {
        cameraLauncher.launch(cameraIntent);
    } else {
        Toast.makeText(requireContext(), "未找到可用的相机应用", Toast.LENGTH_SHORT).show();
    }
}

同时删除原有的onActivityResult方法。

4. 修复潜在空指针问题

你代码中private final Context trackFragmentContext = this.getContext();存在初始化时机问题:Fragment创建阶段getContext()尚未赋值,会导致空指针异常。直接删除该变量,在需要Context的地方使用requireContext()(确保Fragment已关联Activity)或getContext()(需判空)。

额外注意事项

  • 若App目标SDK为33+,WRITE_EXTERNAL_STORAGE权限已被废弃,无需申请,改用MediaStore API存储图片。
  • 测试时确保设备安装了可用的相机应用,避免因无相机应用导致崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 06:25:06