Video Recording and Image Capture on the Kindle Fire using Camera Intents

From Techotopia
Jump to: navigation, search
PreviousTable of ContentsNext
Implementing Video Playback on Android using the VideoView and MediaController ClassesKindle Fire Audio Recording and Playback using MediaPlayer and MediaRecorder


<google>BUY_KINDLE_FIRE</google>


All of the HD editions of the Kindle Fire are equipped with a front facing camera. There are a number of ways to allow the user to record video from within an Android application via this built-in camera, but by far the easiest approach is to make use of a camera intent included with the Android implementation on the Kindle Fire. This allows an application to invoke the standard Kindle Fire video recording interface. When the user has finished recording, the intent will return to the application, passing through a reference to the media file containing the recorded video.

As will be demonstrated in this chapter, this approach allows video recording capabilities to be added to applications with just a few lines of code.


Contents


Checking for Camera Support

Before attempting to access the camera on a Kindle Fire device, it is essential that defensive code be implemented to verify the presence of camera hardware. This is of particular importance since the first and second generation editions of the Kindle Fire did not include a camera.

The presence or otherwise of a camera can be identified via a call to the PackageManager.hasSystemFeature() method. Since those Kindle Fire editions that do have a camera only have a front-facing camera, the code needs to check for the presence of the PackageManager.FEATURE_CAMERA_FRONT feature. This can be encapsulated into the following convenience method:

private boolean hasCamera() {
	if (getPackageManager().hasSystemFeature(
           PackageManager.FEATURE_CAMERA_FRONT)){
	        return true;
      } else {
              return false;
      }
}

Calling the Video Capture Intent

Use of the video capture intent involves, at a minimum, the implementation of code to call the intent activity and a method to handle the return from the activity. The video recording intent on the Kindle Fire is represented by MediaStore.ACTION_VIDEO_CAPTURE and may be launched as follows:

private static final int VIDEO_CAPTURE = 101;

Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);	    
startActivityForResult(intent, VIDEO_CAPTURE);

When invoked in this way, the intent will place the recorded video into a file using a default location and file name. A specific location for the media file may be specified using the putExtra() method of the intent, referencing the MediaStore.EXTRA_OUTPUT key constant to pass through the target URI value. The following code, for example, specifies that the video should be stored on the SD card in a file named myvideo.mp4:

File mediaFile = 
   new File(Environment.getExternalStorageDirectory().getAbsolutePath() 
       + "/myvideo.mp4");
				
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
		
Uri videoUri = Uri.fromFile(mediaFile);
		
intent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
startActivityForResult(intent, VIDEO_CAPTURE);

When the user either completes or cancels the video recording session, the onActivityResult() method of the calling activity will be called. This method needs to check that the request code passed through as an argument matches that specified when the intent was launched, verify that the recording session was successful and extract the path of the video media file. The corresponding onActivityResult() method for the above intent launch code might, therefore, be implemented as follows:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == VIDEO_CAPTURE) {
	  if (resultCode == RESULT_OK) {
	     Toast.makeText(this, "Video saved to:\n" +
	               data.getData(), Toast.LENGTH_LONG).show();
	  } else if (resultCode == RESULT_CANCELED) {
	    	Toast.makeText(this, "Video recording cancelled.", 
                     Toast.LENGTH_LONG).show();
	  } else {
	     Toast.makeText(this, "Failed to record video", 
                     Toast.LENGTH_LONG).show();
        }
    }
}

The above code example simply displays a toast message indicating the success or otherwise of the recording intent session. In the event of a successful recording, the path to the stored video file is displayed.

When executed, the video capture intent (Figure 38-1) will launch and provide the user the opportunity to record video.


The Kindle Fire Camera Intent

Figure 38-1



Calling the Image Capture Intent

In addition to the video capture intent, the Android implementation running on the Kindle Fire also includes an intent designed for taking still photos using the built-in camera. This intent is launched by referencing MediaStore.ACTION_IMAGE_CAPTURE:

private static final int IMAGE_CAPTURE = 102;

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);	    
startActivityForResult(intent, IMAGE_CAPTURE);

As with video capture, the intent may be passed the location and file name into which the image is to be stored, or left to use the default location and naming convention.

Creating an Example Video Recording Project

In the remainder of this chapter, a very simple application will be created to demonstrate the use of the video capture intent. The application will consist of a single button which, when touched by the user, will launch the video capture intent. Once video has been recorded and the video capture intent dismissed, the application will simply display the path to the video file as a Toast message. The VideoPlayer application created in the previous chapter will then be modified to play back the recorded video.

Begin the application creation process by launching Eclipse and creating a new Android Application project named CameraApp using the appropriate Android SDK versions and package name and including a blank activity named CameraAppActivity with a corresponding layout named activity_camera_app.

Designing the User Interface Layout

Within the Graphical Layout tool, delete the default Hello World text view and replace it with a Button view positioned in the center of the display canvas. Change the text on the button to read Record Video and assign an onClick property to the button so that it calls a method named startRecording() when selected by the user:


The UI for an Android Camera application

Figure 38-2


Finally, change the ID of the button to recordButton. The corresponding XML in the activity_camera_app.xml file should approximately resemble the following listing:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".CameraAppActivity" >

    <Button
        android:id="@+id/recordButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:onClick="startRecording"
        android:text="@string/button_string" />

</RelativeLayout>

Save the layout file before proceeding.

Checking for the Camera

Before attempting to launch the video capture intent, the application first needs to verify that the device on which it is running actually has a camera. Given that this application is targeting the Kindle Fire family of devices, this check needs to look for a front facing camera. For the purposes of this example, we will simply make use of the previously outlined hasCamera() method. In the event that a camera is not present, the Record Video button will be disabled.

Select the CameraAppActivity.java file and modify it as follows:

package com.example.cameraapp;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.content.pm.PackageManager;
import android.widget.Button;

public class CameraAppActivity extends Activity {

	private static final int VIDEO_CAPTURE = 101;
	private Uri fileUri;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_camera_app);
		
		Button recordButton = 
                (Button) findViewById(R.id.recordButton);
		
		if (!hasCamera())
			recordButton.setEnabled(false);
	}

	private boolean hasCamera() {
	    if (getPackageManager().hasSystemFeature(
                       PackageManager.FEATURE_CAMERA_FRONT)){
	        return true;
	    } else {
	        return false;
	    }
	}
.
.
.
}

Launching the Video Capture Intent

The objective is for the video capture intent to launch when the user selects the Record Video button. Since this is now configured to call a method named startRecording(), the next logical step is to implement this method within the CameraAppActivity.java source file:

package com.example.cameraapp;

import java.io.File;

import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.view.Menu;
import android.view.View;
import android.widget.Button;

public class CameraAppActivity extends Activity {

	private static final int VIDEO_CAPTURE = 101;
	private Uri fileUri;

	public void startRecording(View view)
	{
	    File mediaFile = new
        File(Environment.getExternalStorageDirectory().getAbsolutePath() 
              + "/myvideo.mp4");	
	
	    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
	    fileUri = Uri.fromFile(mediaFile);
		
 	    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
	    startActivityForResult(intent, VIDEO_CAPTURE);
	}
.
.
.
}

Handling the Intent Return

When control returns back from the intent to the application’s main activity the onActivityResult() method will be called. All that this method needs to do for this example is verify the success or otherwise of the video capture and display the path of the file into which the video has been stored:

package com.example.cameraapp;

import java.io.File;

import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class CameraAppActivity extends Activity {
.
.
.
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {	    
	    if (requestCode == VIDEO_CAPTURE) {
	        if (resultCode == RESULT_OK) {
	             Toast.makeText(this, "Video has been saved to:\n" +
	                data.getData(), Toast.LENGTH_LONG).show();
	        } else if (resultCode == RESULT_CANCELED) {
	        	Toast.makeText(this, "Video recording cancelled.", 
                      Toast.LENGTH_LONG).show();
	        } else {
	        	Toast.makeText(this, "Failed to record video", 
                      Toast.LENGTH_LONG).show();
	        }
	    }
	}
.
.
}

Testing the Application

Compile and run the application on a physical Kindle Fire HD device, touch the record button and use the video capture intent to record some video. Once completed, stop the video recording and touch the Done button on the screen to return to the CameraApp application. On returning, a Toast message should appear stating that the video has been stored in:

file:///mnt/sdcard/myvideo.mp4

From the Eclipse Package Explorer panel, locate the VideoPlayer project created in the previous chapter, navigate to the VideoPlayerActivity.java file and modify the setVideoPath() method call to reference the newly recorded video:

videoView.setVideoPath("file:///mnt/sdcard/myvideo.mp4");

Running the modified VideoPlayer application on the Kindle Fire device should result in the previously recorded video being played back.

Summary

The HD range of Kindle Fire devices includes a front facing camera that can be accessed by applications. Whilst there are a number of different approaches to adding camera support to applications, the Android video and image capture intents provide a simple and easy solution to capturing video and images.


<google>BUY_KINDLE_FIRE</google>



PreviousTable of ContentsNext
Implementing Video Playback on Android using the VideoView and MediaController ClassesKindle Fire Audio Recording and Playback using MediaPlayer and MediaRecorder