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

如何通过Intent传递拍摄图片到其他Activity并解决空指针异常

解决Android相机拍照后传递图片到另一个Activity的崩溃问题

嗨,我来帮你搞定这个问题!从你的Logcat报错能明确看到是**NullPointerException**,触发点在bottom_bar.java的186行——也就是你调用data.getData()的地方。这是因为默认调用相机的MediaStore.ACTION_IMAGE_CAPTURE Intent,并不会返回完整的图片Uri(只有缩略图会存在data.getExtras()里),直接拿data.getData()自然会得到null,进而导致崩溃。

下面是完整的修正方案,分步骤来:

第一步:提前指定相机拍照的图片保存路径

我们需要先创建一个文件来存储拍摄的图片,然后把这个文件的Uri传给相机Intent,这样拍照完成后,图片会直接保存到这个路径,我们就能准确拿到Uri了。

首先添加权限(如果是Android 6.0+还要处理动态权限,先加静态权限到AndroidManifest.xml):

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />

然后修改你的openCamera()方法:

private static final int CAMERA_REQUEST = 1888;
private Uri photoUri; // 全局变量保存图片Uri

private void openCamera() {
    // 创建保存图片的文件
    File photoFile = null;
    try {
        photoFile = createImageFile();
    } catch (IOException ex) {
        // 处理文件创建失败的情况
        ex.printStackTrace();
        Toast.makeText(this, "无法创建图片文件", Toast.LENGTH_SHORT).show();
        return;
    }
    if (photoFile != null) {
        // 获取文件Uri(Android N及以上要使用FileProvider)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            photoUri = FileProvider.getUriForFile(this, 
                    getPackageName() + ".fileprovider", photoFile);
        } else {
            photoUri = Uri.fromFile(photoFile);
        }
        // 启动相机Intent,传入Uri
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
        startActivityForResult(takePictureIntent, CAMERA_REQUEST);
        dialog.dismiss();
    }
}

// 创建图片文件的工具方法
private File createImageFile() throws IOException {
    // 生成唯一文件名
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    return File.createTempFile(
        imageFileName,  /* 前缀 */
        ".jpg",         /* 后缀 */
        storageDir      /* 存储目录 */
    );
}

注意:如果是Android 7.0及以上,必须使用FileProvider来获取Uri,需要在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="my_images" path="Pictures" />
</paths>

然后在AndroidManifest.xml中注册FileProvider:

<application>
    ...
    <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>
</application>

第二步:修正onActivityResult方法

现在拍照完成后,我们直接用之前保存的photoUri,不需要从data里拿了(因为data会是null):

private static final int GALLERY_REQUEST = 1889; // 假设你定义的相册请求码

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case GALLERY_REQUEST:
            if (resultCode == RESULT_OK && data != null) {
                Uri selectedImage = data.getData();
                // 处理相册图片逻辑
            }
            break;
        case CAMERA_REQUEST:
            if (resultCode == RESULT_OK) {
                // 直接用全局变量photoUri,转成字符串传递避免Parcelable问题
                Intent i = new Intent(bottom_bar.this, fotograf_cekildikten_sonra_kaydet_iptal_yeri.class);
                i.putExtra("imageUri", photoUri.toString());
                startActivity(i);
            }
            break;
    }
}

第三步:修正接收图片的Activity代码

你之前用setImageResource()是错误的,这个方法是加载资源id的,应该用setImageURI()或者Glide等图片加载库来显示:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fotograf_cekildikten_sonra_kaydet_iptal_yeri);

    ImageView imageView = findViewById(R.id.telefon_arama_ImageView);
    String uriString = getIntent().getStringExtra("imageUri");
    if (uriString != null) {
        Uri uri = Uri.parse(uriString);
        imageView.setImageURI(uri);
        // 或者用Glide加载更稳定(需要添加Glide依赖):
        // Glide.with(this).load(uri).into(imageView);
    }
}

为什么之前会崩溃?

默认的MediaStore.ACTION_IMAGE_CAPTURE Intent,当你不指定EXTRA_OUTPUT时,系统只会把拍摄的缩略图放在data.getExtras().get("data")里,而data.getData()会返回null,这就是你触发NullPointerException的原因。指定EXTRA_OUTPUT后,图片会保存到你指定的路径,我们直接用这个路径的Uri就不会有问题了。

内容的提问来源于stack exchange,提问作者Berkay Isıkoglu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:23:15