Android includes support for various cameras and camera features
available on devices and allows you to capture pictures and videos for use in
your applications. This tutorial shows a quick, simple approach to capture images
and videos in your application.
1.
Considerations
You should consider a
few questions about how your app intends to use the cameras feature before
enabling your application to use them on Android devices.
ü Camera Necessity - Is the camera so imperative for your
application that you do not want it to be installed on a device that does not
have a camera? If yes, you should declare the camera requirement in your
manifest file.
ü Storage - Are the media your application generates supposed to be
visible only to your application or are they shared so that other applications
such as Gallery or other media and social apps can use them? Do you need the
pictures and videos to be available even when your application is uninstalled? View
the Saving Media Files part to see how to implement these options.
2. The Basics
The Android framework allows
capturing images and videos through the Camera API or camera Intent.
The relevant classes are:
- Camera
This class is the
primary API to control device cameras. This class is used to shoot pictures or
videos when you are building a camera application.
- SurfaceView
This class is used for
presenting a live camera preview to the user.
- MediaRecorder
This class is used for
recording video from the camera.
- Intent
An intent action type
of MediaStore.ACTION_IMAGE_CAPTURE or MediaStore.ACTION_VIDEO_CAPTURE can
be used to capture images or videos without directly using the Camera object.
3.
Manifest
Declarations
Before initiating
development on your application with the Camera API, make sure that your
manifest file has the appropriate declarations to allow the use of camera
hardware and other related features.
· Camera
Permission - Your
application must solicit permission to use a device camera.
<uses-permission android:name="android.permission.CAMERA" />
Note: If you are using the camera via an intent, your application
need not request this permission
· Camera
Features - Your
application must also declare use of camera features, for example:
Adding camera features
to your manifest file causes the app stores to prevent your application from
being installed on devices that do not have a camera or do not support the
camera features that you specify.
If your
application can use a
camera or camera feature for normal operation, but does not necessarily require it, you should specify
this in the manifest by including the android:required attribute, and setting it to false:
<uses-feature android:name="android.hardware.camera" android:required="false" />
· Storage
Permission - If your
application saves images or videos to the device's external storage (SD Card),
you must also mention this in the manifest file.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
· Audio
Recording Permission - For recording
audio along with video, your application must also request the audio capture
permission.
<uses-permission android:name="android.permission.RECORD_AUDIO" />
· Location
Permission - If your
application tags images with the device’s GPS location information, you must
request location permission:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
4.
Using
Existing Camera Apps
A speedy way to enable
shooting pictures or videos in your application without a lot of additional
code is to use an Intent to invoke an existing camera application. A
camera intent requests an existing camera app to capture a picture or video
clip and then returns the control back to your application. This section demonstrates
how to capture an image or video using this technique.
The procedure for
invoking a camera intent follows these general steps:
i. Compose
a Camera Intent - Create
an Intent that requests an image or video, using one of these intent
types:
o MediaStore.ACTION_IMAGE_CAPTURE - To
request an image from an existing camera application.
o MediaStore.ACTION_VIDEO_CAPTURE - To
request a video from an existing camera application.
ii. Start
the Camera Intent - Use the startActivityForResult() method
to execute the camera intent. After you start the intent, the camera
application user interface would appear on the device screen and the user can
take a picture or a video.
iii.Receive
the Intent Result - Set up
an onActivityResult() method in your application to receive the
callback and data from the camera intent. When the user finishes taking a
picture or video or cancels the operation, the system calls this method.
5.
Image
capture intent
Capturing images using
a camera intent is a quick way to let your application take pictures with
minimal coding. An image capture intent can include the following additional
information:
· MediaStore.EXTRA_OUTPUT -
This setting requires a Uri object specifying a path and file name
where you would like to save the picture. This setting is optional but strongly
recommended. If you do not mention this value, the camera application would save
the requested picture in the default location with a default name, as specified
by the returned intent's Intent.getData() field.
The following example shows
how to construct an image capture intent and execute it. The getOutputMediaFileUri() method
in this example refers to the sample code shown in Saving Media Files.
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private
Uri
fileUri;
@Override
public
void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// create Intent to
take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to
save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file
name
// start the image
capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
When the startActivityForResult() method
is executed, users can see a camera application interface on their screen.
After the user finishes taking a picture or cancels the operation, the user
interface returns to your application, and you must intercept the onActivityResult() method
to receive the result of the intent and continue your application’s smooth
execution.
6.
Video
capture intent
Capturing video using
camera intent is a quick way to let your application take videos with minimal
coding. A video capture intent can include the following additional
information:
· MediaStore.EXTRA_OUTPUT -
This setting requires a Uri specifying a path and file name where you
would like to save the video. This setting is optional but strongly
recommended. If you do not specify this value, the Camera application saves the
requested video in the default location with a default name, as specified in
the returned intent's Intent.getData() field.
· MediaStore.EXTRA_VIDEO_QUALITY -
This value should be set to 0 for lowest quality and smallest file size, or 1
for highest quality and larger file size.
· MediaStore.EXTRA_DURATION_LIMIT -
This value can be used to limit the length of the video being captured, in seconds.
· MediaStore.EXTRA_SIZE_LIMIT -
This value can be used to limit the file size, in bytes, of the video being
captured.
The following example shows
how to construct a video capture intent and execute it. The getOutputMediaFileUri() method
in this example refers to the sample code shown in Saving Media Files.
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
private
Uri
fileUri;
@Override
public
void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//create new Intent
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO); // create a file to
save the video
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);
}
When
the startActivityForResult() method
is executed, users can see a camera application interface. After the user
finishes taking a video or cancels the operation, the user interface returns to
your application, and you must intercept the onActivityResult() method to receive the result of the
intent and continue your application’s smooth execution.
- Camera
- SurfaceView
- MediaRecorder
- Intent
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private Uri fileUri;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
private Uri fileUri;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
private
Uri
fileUri;
@Override
public
void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//create new Intent
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO); // create a file to
save the video
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);
}
7. Receiving camera intent
result
After finishing
the construction and execution of an image or video camera intent, your
application must be properly configured to receive the result of the intent.
This section demonstrates how to intercept the callback from a camera intent so
that your application can further process the captured image or video.
For
receiving the result of an intent, you must override the onActivityResult() in the
activity that started the intent. The following example shows how to override onActivityResult() to
capture the result of the image camera intent or video
camera intent examples shown above.
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE)
{
if (resultCode == RESULT_OK)
{
// Image captured and saved to fileUri specified in the Intent
Toast.makeText(this, "Image saved to:\n" +
data.getData(), Toast.LENGTH_LONG).show();
}
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
Toast.makeText(this, "Video saved to:\n" +
data.getData(), Toast.LENGTH_LONG).show();
}
else if (resultCode == RESULT_CANCELED)
{
// User cancelled the video capture
}
else
{
// Video capture failed, advise user
}
}
}
Once your activity receives a successful result, the captured image or
video is available in the specified location for your application to access.
Code snippets taken from:
http://developer.android. com/guide/topics/media/camera. html
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE)
{
if (resultCode == RESULT_OK)
{
// Image captured and saved to fileUri specified in the Intent
Toast.makeText(this, "Image saved to:\n" + data.getData(), Toast.LENGTH_LONG).show();
}
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
Toast.makeText(this, "Video saved to:\n" + data.getData(), Toast.LENGTH_LONG).show();
}
else if (resultCode == RESULT_CANCELED)
{
// User cancelled the video capture
}
else
{
// Video capture failed, advise user
}
}
}
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE)
{
if (resultCode == RESULT_OK)
{
// Image captured and saved to fileUri specified in the Intent
Toast.makeText(this, "Image saved to:\n" + data.getData(), Toast.LENGTH_LONG).show();
}
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
Toast.makeText(this, "Video saved to:\n" + data.getData(), Toast.LENGTH_LONG).show();
}
else if (resultCode == RESULT_CANCELED)
{
// User cancelled the video capture
}
else
{
// Video capture failed, advise user
}
}
}