Video Recording and Image Capture on Android using Camera Intents

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


You are currently reading the Eclipse - Android 4.4 Edition of this book.

Purchase the fully updated Android Studio 3.0 / Android 8 Edition of this publication in eBook ($24.99) or Print ($39.99) format

Android Studio 3.0 Development Essentials - Android 8 Edition Print and eBook (ePub/PDF/Kindle) editions contain 82 chapters and over 810 pages

Buy eBook Buy Print Preview Book


Many Android devices are equipped with at least one camera. There are a number of ways to allow the user to record video from within an Android application via these built-in cameras, but by far the easiest approach is to make use of a camera intent included with the Android operating system. This allows an application to invoke the standard Android 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.




Checking for Camera Support

Before attempting to access the camera on an Android device, it is essential that defensive code be implemented to verify the presence of camera hardware. This is of particular importance since not all Android devices include a camera.

The presence or otherwise of a camera can be identified via a call to the PackageManager.hasSystemFeature() method. In order to check for the presence of 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;
      }
}

The presence of a camera facing away from the device screen can be similarly verified using the PackageManager.FEATURE_CAMERA constant. A test for whether a device has any camera can be performed by referencing PackageManager.FEATURE_CAMERA_ANY.

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 Android build-in video recording intent 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 40-1) will launch and provide the user the opportunity to record video.


The Android Video Recording Intent running

Figure 40-1



Calling the Image Capture Intent

In addition to the video capture intent, the Android system 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 corresponding layout and fragment files named activity_camera_app and fragment_camera_app respectively.

You are currently reading the Eclipse - Android 4.4 Edition of this book.

Purchase the fully updated Android Studio 3.0 / Android 8 Edition of this publication in eBook ($24.99) or Print ($39.99) format

Android Studio 3.0 Development Essentials - Android 8 Edition Print and eBook (ePub/PDF/Kindle) editions contain 82 chapters and over 810 pages

Buy eBook Buy Print Preview Book

Designing the User Interface Layout

Within the Graphical Layout tool, delete the default Hello World text view from the fragment_camera_app.xml layout file 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:

<google>ADSDAQBOX_FLOW</google> The user interface of an example Android video recording app

Figure 40-2


Finally, change the ID of the button to recordButton. The corresponding XML in the fragment_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. For the purposes of this example, we will simply make use of the previously outlined hasCamera() method, this time checking for any camera type. 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.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
import android.content.pm.PackageManager;
import android.widget.Button;
import android.net.Uri;

public class CameraAppActivity extends Activity {

	private static final int VIDEO_CAPTURE = 101;
	private Uri fileUri;
	
	@Override 
	protected void onStart() {
		super.onStart();
		Button recordButton = 
                (Button) findViewById(R.id.recordButton);
		
		if (!hasCamera())
			recordButton.setEnabled(false);

	}

	private boolean hasCamera() {
	    if (getPackageManager().hasSystemFeature(
                       PackageManager.FEATURE_CAMERA_ANY)){
	        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.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
import android.content.pm.PackageManager;
import android.widget.Button;
import android.os.Environment;
import android.provider.MediaStore;
import android.content.Intent;

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.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
import android.content.pm.PackageManager;
import android.widget.Button;
import android.os.Environment;
import android.provider.MediaStore;
import android.content.Intent;

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 Android device, touch the record button and use the video capture intent to record some video. Once completed, stop the video recording. Play back the recording by selecting the play button on the screen. Finally, touch the Done (sometimes represented by a check mark) 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 a specific location on the device (the exact location will differ from one device type to another).

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 file path. Running the modified VideoPlayer application on the Android device should result in the previously recorded video being played back.

Summary

Most Android tablet and smartphone devices include a 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.


You are currently reading the Eclipse - Android 4.4 Edition of this book.

Purchase the fully updated Android Studio 3.0 / Android 8 Edition of this publication in eBook ($24.99) or Print ($39.99) format

Android Studio 3.0 Development Essentials - Android 8 Edition Print and eBook (ePub/PDF/Kindle) editions contain 82 chapters and over 810 pages

Buy eBook Buy Print Preview Book



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