Android: Null data returned from Camera Intent

Anyone who has tried calling the image or video capture intent using the default Camera activity probably has been met with much frustration. There are many approaches and workarounds for various phones and API levels because of the insane fragmentation of Android. Most of us just want a simple way to call the default Camera activity, have the video or image stored in the Gallery, and retrieve a the Camera intent results for further processing.

The Android documentation provides what appear to be a very straight forward way to capture images and video and either save them in the default location or a folder of your choosing. The resources available for doing so can be found here:

Image capture intent
Saving Media Files

However, I am not sure Google actually tests their Android examples on real phones (developer phones). Testing the method for capturing images on a Galaxy Nexus or Nexus One both return a null value for the data when receiving the camera intent result. However, capturing video seems to work as expected. Though both the image and video files are written to the specified folders on the device.

So naturally, as a developer you are stuck with a borked example that must be modified for a real world implementation. Luckily for my needs I didn’t need to store images or video in an external folder, I wanted the camera application to store the requested media in the default location with a default name. This is usually the Camera folder.

Below is my modification to the onActivityResult() method of the Activity for retrieving the Uri of the captured image. I have left the rest of the code from the Android Camera example for storing video and images in the activity in case you are feeling particularly brave and want to store your images in a different location.

You might ask why I couldn’t insert the video into the MediaStore the same way I am inserting the captured image (by passing the Uri and ContentValues). Doing this for video actually created two files for me, one in the Media Store, and an 0kb file in the external video folder on the SD card. This only happened on the Nexus One (Android 2.3.4) and not the Galaxy Nexus (4.0.2). So you end up with two different methods for making sure media appears in the MediaStore.



import java.text.SimpleDateFormat;
import java.util.Date;

import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;

public class AndroidCameraTestsActivity extends Activity 
	private static final String TAG = AndroidCameraTestsActivity.class.getSimpleName(); 
	private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
	private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
	public static final int MEDIA_TYPE_IMAGE = 1;
    public static final int MEDIA_TYPE_VIDEO = 2;

    private Uri fileUri;
    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) 

     * **/
    public void onCaptureImage(View v) 
        // give the image a name so we can store it in the phone's default location
    	String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        ContentValues values = new ContentValues();
		values.put(MediaStore.Images.Media.TITLE, "IMG_" + timeStamp + ".jpg");

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        //fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image (this doesn't work at all for images)
        fileUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); // store content values
		intent.putExtra( MediaStore.EXTRA_OUTPUT,  fileUri);
        // start the image capture Intent
        startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
     * **/
    public void onCaptureVideo(View v) 
    	 //create new Intent
        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

        //fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);  // create a file to save the video in specific folder (this works for video only)
        //intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);  // set the image file name
        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high

        // start the Video Capture Intent
        startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    	super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
            	// Originally I was going to iterate through the list of images and grab last added to the MediaStore.
            	// But this is not necessary if we store the Uri in the image
            	String[] projection = {MediaStore.Images.ImageColumns._ID};
            	String sort = MediaStore.Images.ImageColumns._ID + " DESC";

            	Cursor cursor = this.managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, projection, null, null, sort);

            		Long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns._ID));
            		fileUri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String.valueOf(id));
            	} finally{
				if(fileUri != null) {
					Log.d(TAG, "Image saved to:\n" + fileUri);
					Log.d(TAG, "Image path:\n" + fileUri.getPath());
					Log.d(TAG, "Image name:\n" + getName(fileUri)); // use uri.getLastPathSegment() if store in folder
            } else if (resultCode == RESULT_CANCELED) {
                // User cancelled the image capture
            } else {
                // Image capture failed, advise user

        if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                // Video captured and saved to fileUri specified in the Intent
            	fileUri = (Uri) data.getData();
				if(fileUri != null) {
					Log.d(TAG, "Video saved to:\n" + fileUri);
					Log.d(TAG, "Video path:\n" + fileUri.getPath());
					Log.d(TAG, "Video name:\n" + getName(fileUri)); // use uri.getLastPathSegment() if store in folder
            } else if (resultCode == RESULT_CANCELED) {
                // User cancelled the video capture
            } else {
                // Video capture failed, advise user
    /** Create a file Uri for saving an image or video to specific folder
     * */
    private static Uri getOutputMediaFileUri(int type)
          return Uri.fromFile(getOutputMediaFile(type));

    /** Create a File for saving an image or video */
    private static File getOutputMediaFile(int type)
        // To be safe, you should check that the SDCard is mounted
    	if(Environment.getExternalStorageState() != null) {
    		// this works for Android 2.2 and above
    		File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "AndroidCameraTestsFolder");
            // This location works best if you want the created images to be shared
            // between applications and persist after your app has been uninstalled.

            // Create the storage directory if it does not exist
            if (! mediaStorageDir.exists()) {
                if (! mediaStorageDir.mkdirs()) {
                    Log.d(TAG, "failed to create directory");
                    return null;

            // Create a media file name
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            File mediaFile;
            if (type == MEDIA_TYPE_IMAGE){
                mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                "IMG_"+ timeStamp + ".jpg");
            } else if(type == MEDIA_TYPE_VIDEO) {
                mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                "VID_"+ timeStamp + ".mp4");
            } else {
                return null;

            return mediaFile;
    	return null;

    // grab the name of the media from the Uri
    protected String getName(Uri uri) 
		String filename = null;

		try {
			String[] projection = { MediaStore.Images.Media.DISPLAY_NAME };
			Cursor cursor = managedQuery(uri, projection, null, null, null);

			if(cursor != null && cursor.moveToFirst()){
				int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
				filename = cursor.getString(column_index);
			} else {
				filename = null;
		} catch (Exception e) {
			Log.e(TAG, "Error getting file name: " + e.getMessage());

		return filename;


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""
    android:orientation="vertical" >

    <Button android:text="Capture Image" android:onClick="onCaptureImage" 
	<Button android:text="Capture Video" android:onClick="onCaptureVideo"


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=""
    android:versionName="1.0" >

    <uses-sdk android:targetSdkVersion="15" android:minSdkVersion="8"/>
    <uses-permission android:name="android.permission.CAMERA"/>
 	<uses-feature android:name="" />
 	<uses-feature android:name=""/>
  	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

        android:label="@string/app_name" >
            android:label="@string/app_name" >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />


Additional Resources:

Android Camera Test Project
Null Intent passed back On Samsung Galaxy Tab…



  1. I found the answer for writting the image in custom folder here:

    it works fine for me and with no dublicate files

    I bypass from original:

    File imagesFolder = new File(Environment.getExternalStorageDirectory(), “MyImages”);
    imagesFolder.mkdirs(); // <—-
    File image = new File(imagesFolder, "image_001.jpg");
    Uri uriSavedImage = Uri.fromFile(image);
    imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);

    Thanx for both of you

  2. Image capture was nightmare for me as data was always null. Your article is really helpful. I got it working in Android 4.0.3.

  3. Hi
    Great solution.

    I am having the same problem but with video, works fine on the simulator but fails on the phone – data.getData() returns null. Image capture works perfectly. I have tried your video example and it still fails. The phone I have tried it on is an HTC.

  4. hi. this is great solution but. i have some problem. i can running take video an save to dcim/camera/sdcard. but i can’t running when i choose take image. always force close. what the problem with ACTION_IMAGE_CAPTURE?

Comments are closed.