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

Android Studio(Koala)实现相册选图与相机拍照功能的问题求助

Android相机拍照与相册选图功能修复与实现

你的代码存在的核心问题

  • 成员变量初始化时机错误:private final ImageView image = findViewById(R.id.cameraImage); 在Activity创建前调用findViewById,此时布局还未加载,会直接抛出空指针异常。
  • 未使用正确的Activity启动方式:调用相机需要用startActivityForResult来接收拍照结果,你用了startActivity导致onActivityResult无法正确获取数据。
  • onActivityResult逻辑不严谨:没有判断返回结果是否成功(resultCode == RESULT_OK),也未匹配请求码,会导致无效数据处理。
  • 冗余注解:@SuppressLint("WrongViewCast") 属于多余操作,若布局中R.id.camera确实是Button,无需添加该注解,反而会隐藏潜在的类型转换问题。
  • 缺少权限处理:Android 6.0(API 23)及以上版本,调用相机需要动态申请权限,否则会直接崩溃。

修正后的完整代码

package com.task;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class MainActivity extends AppCompatActivity {

    private ImageView image;
    private static final int REQUEST_CAMERA_PERMISSION = 100;
    private static final int REQUEST_IMAGE_CAPTURE = 101;
    private static final int REQUEST_PICK_IMAGE = 102;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // 布局加载完成后再初始化控件
        image = findViewById(R.id.cameraImage);
        Button camButton = findViewById(R.id.camera);
        camButton.setOnClickListener(this::onCameraClick);
        
        // 初始化相册选择按钮
        Button albumButton = findViewById(R.id.album);
        albumButton.setOnClickListener(this::onAlbumClick);
    }

    public void onClickHistory(View view){
        startActivity(new Intent(MainActivity.this, ActivityHistory.class));
    }

    // 相机点击事件
    private void onCameraClick(View view) {
        // 检查相机权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
            return;
        }
        // 启动相机
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
    }

    // 相册选择点击事件
    private void onAlbumClick(View view) {
        Intent pickImageIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(pickImageIntent, REQUEST_PICK_IMAGE);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CAMERA_PERMISSION) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 权限同意后再次启动相机
                onCameraClick(findViewById(R.id.camera));
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // 先判断结果是否成功
        if (resultCode != RESULT_OK || data == null) {
            return;
        }

        switch (requestCode) {
            case REQUEST_IMAGE_CAPTURE:
                // 获取相机返回的缩略图
                Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
                image.setImageBitmap(thumbnail);
                break;
            case REQUEST_PICK_IMAGE:
                // 获取相册选中的图片Uri
                Uri imageUri = data.getData();
                image.setImageURI(imageUri);
                break;
        }
    }
}

补充说明

  1. 权限配置:需要在AndroidManifest.xml中添加以下权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Android 13+ 可使用细分权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
  1. 原图获取:ACTION_IMAGE_CAPTURE默认返回缩略图,若需高清原图,需通过MediaStore.EXTRA_OUTPUT指定拍照文件保存Uri,后续从该路径读取图片。
  2. AndroidX新API:若项目使用AndroidX,建议用ActivityResultContracts替代startActivityForResult,这是Google推荐的更稳定的生命周期兼容方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:22:10