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

Android Java:调用相机Intent获取结果时openInputStream触发空指针异常

Fixing NullPointerException: uri When Getting Camera Image InputStream

Hey there! Let's break down why you're hitting that NullPointerException at getContentResolver().openInputStream(data.getData()) and how to fix it.

The Root Cause

When you use the default camera Intent (MediaStore.ACTION_IMAGE_CAPTURE), the system only returns a thumbnail in the data.getExtras().get("data") bundle. The data.getData() call returns null because the camera app doesn't pass a URI for the full-size image by default—unless you explicitly tell it where to save the photo upfront.

The Solution: Specify a Save Path for the Camera Image

Instead of relying on the intent to return the full image URI, you'll need to:

  • Create a file to store the full-size photo before launching the camera.
  • Pass this file's URI to the camera intent so it saves the photo there.
  • Load the image directly from that file path in onActivityResult.

Step 1: Create a Method to Generate the Image File

This creates a temporary file in your app's private external storage (no extra permissions needed for Android 10+):

private String mCurrentPhotoPath; // Store the path globally

private File createImageFile() throws IOException {
    // Generate a unique filename using timestamp
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    
    return File.createTempFile(
        imageFileName,  // Prefix
        ".jpg",         // Suffix
        storageDir      // Save directory
    );
}

Step 2: Launch the Camera Intent with the Save URI

Use FileProvider (required for Android 7.0+) to get a safe URI for the file:

private void takePhotoWithCamera() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    
    // Check if a camera app exists to handle the intent
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        File photoFile = null;
        try {
            photoFile = createImageFile();
            mCurrentPhotoPath = photoFile.getAbsolutePath(); // Save the path
        } catch (IOException ex) {
            // Handle file creation errors
            ex.printStackTrace();
        }
        
        if (photoFile != null) {
            Uri photoURI = FileProvider.getUriForFile(
                this,
                "com.yourapp.package.fileprovider", // Replace with your app's authority
                photoFile
            );
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, CAMERA_PIC_REQUEST);
        }
    }
}

Step 3: Configure FileProvider in Your Manifest

Add this to your AndroidManifest.xml inside the <application> tag:

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="com.yourapp.package.fileprovider" // Match the authority above
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

Step 4: Create the File Paths XML

Make a new directory res/xml and add file_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Grants access to the Pictures directory in your app's external storage -->
    <external-files-path name="my_images" path="Pictures" />
</paths>

Step 5: Load the Full Image in onActivityResult

Now you can skip data.getData() and load directly from the saved file path:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    
    if (requestCode == CAMERA_PIC_REQUEST && resultCode == RESULT_OK) {
        // Show the thumbnail as before
        Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
        pic.setImageBitmap(thumbnail);
        
        // Load the full-size image from the saved path
        BitmapFactory.Options options = new BitmapFactory.Options();
        // Optional: Reduce image size to avoid out-of-memory errors
        options.inSampleSize = 2; 
        bitmapPic = BitmapFactory.decodeFile(mCurrentPhotoPath, options);
        
        // Use bitmapPic for your needs now!
    }
}

Why This Works

By specifying MediaStore.EXTRA_OUTPUT, you tell the camera app exactly where to save the full-size photo. Since you control the file path, you don't need to rely on the intent returning a URI (which it doesn't do by default).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:11:46