Null Pointer Exception in Android Camera Intent Handling: Complete Solution for ResultCode and Data Validation

Dec 08, 2025 · Programming · 16 views · 7.8

Keywords: Android Development | Camera Intent | Null Pointer Exception | onActivityResult | ResultCode Validation

Abstract: This article provides an in-depth analysis of the common RuntimeException in Android development: Failure delivering result ResultInfo{who=null, request=1888, result=0, data=null} to activity. Through a typical camera photo capture scenario, it explains the root cause where resultCode returns RESULT_CANCELED (value 0) and data becomes null when users cancel camera operations, leading to NullPointerException. Based on the best practice answer, the article systematically explains the importance of validating both resultCode and data integrity in the onActivityResult method, provides complete solutions in both Java and Kotlin, and compares the advantages and disadvantages of different validation strategies. Finally, it discusses the underlying principles of result delivery in Android Intent mechanisms and best practices for defensive programming.

Problem Background and Error Analysis

In Android application development, implementing camera photo capture functionality is a common requirement. Developers typically launch the camera application using the startActivityForResult method and handle the returned photo data in the onActivityResult callback. However, when users cancel the photo capture operation (such as pressing the back button or cancel button), improper handling of the returned result can cause application crashes.

Root Cause: Missing resultCode and Data Validation

The core issue in the original code is that the onActivityResult method only checks the requestCode while ignoring validation of resultCode and data validity. When users cancel the operation, the system returns resultCode as RESULT_CANCELED (with a value of 0) and the data parameter as null. Directly calling data.getExtras() in this situation throws a NullPointerException.

Complete Solution

Based on best practices, the correct implementation of onActivityResult should include multiple layers of validation:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // First layer: Check if operation was cancelled
    if (resultCode != RESULT_CANCELED) {
        // Second layer: Check if request code matches
        if (requestCode == CAMERA_REQUEST) {
            // Third layer: Check if returned data is valid
            if (data != null && data.getExtras() != null) {
                Bitmap photo = (Bitmap) data.getExtras().get("data");
                if (photo != null) {
                    imageView.setImageBitmap(photo);
                } else {
                    // Handle null bitmap data
                    Log.w("Camera", "Received null bitmap from camera");
                }
            } else {
                // Handle null data or extras
                Log.w("Camera", "No data received from camera");
            }
        }
    } else {
        // Handle user cancellation
        Log.d("Camera", "User cancelled camera operation");
    }
}

Kotlin Implementation

For developers using Kotlin, pay attention to parameter nullability declarations:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    
    if (resultCode != RESULT_CANCELED) {
        if (requestCode == CAMERA_REQUEST) {
            data?.extras?.get("data")?.let { photoData ->
                (photoData as? Bitmap)?.let { bitmap ->
                    imageView.setImageBitmap(bitmap)
                } ?: run {
                    Log.w("Camera", "Received non-bitmap data from camera")
                }
            } ?: run {
                Log.w("Camera", "No valid data received from camera")
            }
        }
    } else {
        Log.d("Camera", "Camera operation cancelled by user")
    }
}

Comparison of Validation Strategies

Different answers propose different validation strategies:

  1. Best Practice (Answer 1): First checks resultCode != RESULT_CANCELED, which is the most reasonable approach as it directly handles user cancellation scenarios and avoids unnecessary subsequent validations.
  2. Data Validation Approach (Answer 3): Only checks data != null. While this prevents null pointer exceptions, it's incomplete because even if data is not null, resultCode might still indicate operation failure.
  3. Kotlin Considerations (Answer 2): Emphasizes the importance of parameter nullability in Kotlin, but needs to be combined with complete validation logic to form a comprehensive solution.

Underlying Mechanisms and Best Practices

Android's startActivityForResult mechanism follows this process:

  1. Call startActivityForResult(intent, requestCode) to launch the target Activity
  2. The target Activity sets return results via setResult(resultCode, data)
  3. The system calls the original Activity's onActivityResult method to deliver results
  4. When users cancel operations, the target Activity typically calls setResult(RESULT_CANCELED)

Best practices for defensive programming include:

  1. Always validate resultCode, distinguishing between success (RESULT_OK), cancellation (RESULT_CANCELED), and custom result codes
  2. Perform null checks on data and its contents
  3. Use type-safe approaches for data retrieval and conversion
  4. Add appropriate logging and error handling
  5. Consider using more modern APIs like Activity Result API (AndroidX) to simplify result handling

Extended Application Scenarios

This validation pattern applies not only to camera applications but to all scenarios using startActivityForResult, including:

Through systematic validation strategies, developers can build more robust Android applications, avoiding crashes caused by user cancellations or abnormal return data.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.