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; } } }
补充说明
- 权限配置:需要在
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" />
- 原图获取:
ACTION_IMAGE_CAPTURE默认返回缩略图,若需高清原图,需通过MediaStore.EXTRA_OUTPUT指定拍照文件保存Uri,后续从该路径读取图片。 - AndroidX新API:若项目使用AndroidX,建议用
ActivityResultContracts替代startActivityForResult,这是Google推荐的更稳定的生命周期兼容方案。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

