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

Android Studio相机Intent无法唤起+startActivityForResult废弃问题排查

问题分析与解决方案

一、相机无法唤起的可能原因及排查方向

  • 权限未正确申请:Android 6.0(API 23)及以上版本,调用相机需动态申请CAMERA权限。先确认AndroidManifest.xml已声明权限,再在代码中动态请求:
    <!-- AndroidManifest.xml中添加 -->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" android:required="false" />
    
    动态请求代码示例:
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
    } else {
        launchCameraIntent();
    }
    
  • ImagePickerActivity未注册:如果是自定义Activity,必须在AndroidManifest.xml中注册;如果是第三方库提供,确认依赖已正确添加,配置步骤无遗漏。
  • Intent参数不匹配:检查ImagePickerActivity.REQUEST_IMAGE_CAPTURE常量值是否正确,传递的宽高、比例等extra参数是否符合该Activity的预期,参数错误可能导致相机逻辑无法触发。

二、替换废弃的startActivityForResult

AndroidX已废弃startActivityForResult和onActivityResult,推荐使用Activity Result API,改造代码如下:

1. 注册ActivityResultLauncher

在Activity的onCreate方法中注册(或声明为类成员变量):

private ActivityResultLauncher<Intent> cameraLauncher;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.your_layout);
    
    // 注册相机结果回调
    cameraLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
        if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
            handleCameraResult(result.getData());
        }
    });
}

2. 修改launchCameraIntent方法

private void launchCameraIntent() {
    Intent intent = new Intent(ClientInformation.this, ImagePickerActivity.class);
    intent.putExtra(ImagePickerActivity.INTENT_IMAGE_PICKER_OPTION, ImagePickerActivity.REQUEST_IMAGE_CAPTURE);

    // 设置宽高比
    intent.putExtra(ImagePickerActivity.INTENT_LOCK_ASPECT_RATIO, true);
    intent.putExtra(ImagePickerActivity.INTENT_ASPECT_RATIO_X, 1);
    intent.putExtra(ImagePickerActivity.INTENT_ASPECT_RATIO_Y, 1);

    // 设置最大位图尺寸
    intent.putExtra(ImagePickerActivity.INTENT_SET_BITMAP_MAX_WIDTH_HEIGHT, true);
    intent.putExtra(ImagePickerActivity.INTENT_BITMAP_MAX_WIDTH, 1000);
    intent.putExtra(ImagePickerActivity.INTENT_BITMAP_MAX_HEIGHT, 1000);

    // 启动相机选择页
    cameraLauncher.launch(intent);
}

3. 抽离结果处理逻辑

private void handleCameraResult(Intent data) {
    Uri uri = Objects.requireNonNull(data).getParcelableExtra("path");
    try {
        // 替换废弃的MediaStore.Images.Media.getBitmap
        Bitmap bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(getContentResolver(), uri));
        idFilePath = uri.getPath();
        Log.d(TAG, "handleCameraResult: " + idFilePath);
        imgID.setImageBitmap(bitmap);

        String filename = String.valueOf(System.currentTimeMillis());
        File imageID1 = new File(getExternalFilesDir(null), filename.concat(".jpg"));

        // 使用try-with-resources自动关闭流,避免泄漏
        try (FileOutputStream fos = new FileOutputStream(imageID1)) {
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
        } catch (Exception e) {
            e.printStackTrace();
        }
        uriID1 = Uri.fromFile(imageID1); // 替代Uri.parse,路径解析更可靠
        idChecker1 = "new";
        uriString = uriID1.toString();
        Log.d(TAG, "handleCameraResult: ID1" + uriString);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

三、其他代码优化点

  • 弃用方法替换:MediaStore.Images.Media.getBitmap已废弃,改用ImageDecoder.decodeBitmap适配高版本系统。
  • 资源管理:文件输出流使用try-with-resources语法,避免手动关闭时的异常导致资源泄漏。
  • Uri获取:用Uri.fromFile()替代Uri.parse(),对文件路径的解析更稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 01:52:52