183bf11697
Change-Id: I380b65341200c0519a93e2f8969f70f64aec0264
1504 lines
70 KiB
Plaintext
1504 lines
70 KiB
Plaintext
page.title=Camera
|
||
parent.title=Multimedia and Camera
|
||
parent.link=index.html
|
||
@jd:body
|
||
|
||
<div id="qv-wrapper">
|
||
<div id="qv">
|
||
<h2>In this document</h2>
|
||
<ol>
|
||
<li><a href="#considerations">Considerations</a></li>
|
||
<li><a href="#basics">The Basics</a>
|
||
<li><a href="#manifest">Manifest Declarations</a></li>
|
||
<li><a href="#intents">Using Existing Camera Apps</a>
|
||
<ol>
|
||
<li><a href="#intent-image">Image capture intent</a></li>
|
||
<li><a href="#intent-video">Video capture intent</a></li>
|
||
<li><a href="#intent-receive">Receiving camera intent result</a></li>
|
||
</ol>
|
||
<li><a href="#custom-camera">Building a Camera App</a>
|
||
<ol>
|
||
<li><a href="#detect-camera">Detecting camera hardware</a></li>
|
||
<li><a href="#access-camera">Accessing cameras</a></li>
|
||
<li><a href="#check-camera-features">Checking camera features</a></li>
|
||
<li><a href="#camera-preview">Creating a preview class</a></li>
|
||
<li><a href="#preview-layout">Placing preview in a layout</a></li>
|
||
<li><a href="#capture-picture">Capturing pictures</a></li>
|
||
<li><a href="#capture-video">Capturing videos</a></li>
|
||
<li><a href="#release-camera">Releasing the camera</a></li>
|
||
</ol>
|
||
</li>
|
||
<li><a href="#saving-media">Saving Media Files</a></li>
|
||
<li><a href="#camera-features">Camera Features</a>
|
||
<ol>
|
||
<li><a href="#check-feature">Checking feature availability</a></li>
|
||
<li><a href="#using-features">Using camera features</a></li>
|
||
<li><a href="#metering-focus-areas">Metering and focus areas</a></li>
|
||
<li><a href="#face-detection">Face detection</a></li>
|
||
<li><a href="#time-lapse-video">Time lapse video</a></li>
|
||
</ol>
|
||
</li>
|
||
</ol>
|
||
<h2>Key Classes</h2>
|
||
<ol>
|
||
<li>{@link android.hardware.Camera}</li>
|
||
<li>{@link android.view.SurfaceView}</li>
|
||
<li>{@link android.media.MediaRecorder}</li>
|
||
<li>{@link android.content.Intent}</li>
|
||
</ol>
|
||
<h2>See also</h2>
|
||
<ol>
|
||
<li><a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a></li>
|
||
<li><a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a></li>
|
||
</ol>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<p>The Android framework includes support for various cameras and camera features available on
|
||
devices, allowing you to capture pictures and videos in your applications. This document discusses a
|
||
quick, simple approach to image and video capture and outlines an advanced approach for creating
|
||
custom camera experiences for your users.</p>
|
||
|
||
<h2 id="considerations">Considerations</h2>
|
||
<p>Before enabling your application to use cameras on Android devices, you should consider a few
|
||
questions about how your app intends to use this hardware feature.</p>
|
||
|
||
<ul>
|
||
<li><strong>Camera Requirement</strong> - Is the use of a camera so important to your
|
||
application that you do not want your application installed on a device that does not have a
|
||
camera? If so, you should declare the <a href="#manifest">camera requirement in your
|
||
manifest</a>.</li>
|
||
|
||
<li><strong>Quick Picture or Customized Camera</strong> - How will your application use the
|
||
camera? Are you just interested in snapping a quick picture or video clip, or will your application
|
||
provide a new way to use cameras? For a getting a quick snap or clip, consider
|
||
<a href="#intents">Using Existing Camera Apps</a>. For developing a customized camera feature, check
|
||
out the <a href="#custom-camera">Building a Camera App</a> section.</li>
|
||
|
||
<li><strong>Storage</strong> - Are the images or videos your application generates intended to be
|
||
only visible to your application or shared so that other applications such as Gallery or other
|
||
media and social apps can use them? Do you want the pictures and videos to be available even if your
|
||
application is uninstalled? Check out the <a href="#saving-media">Saving Media Files</a> section to
|
||
see how to implement these options.</li>
|
||
</ul>
|
||
|
||
|
||
|
||
<h2 id="basics">The Basics</h2>
|
||
<p>The Android framework supports capturing images and video through the
|
||
{@link android.hardware.Camera} API or camera {@link android.content.Intent}. Here are the relevant
|
||
classes:</p>
|
||
|
||
<dl>
|
||
<dt>{@link android.hardware.Camera}</dt>
|
||
<dd>This class is the primary API for controlling device cameras. This class is used to take
|
||
pictures or videos when you are building a camera application.</dd>
|
||
|
||
<dt>{@link android.view.SurfaceView}</dt>
|
||
<dd>This class is used to present a live camera preview to the user.</dd>
|
||
|
||
<dt>{@link android.media.MediaRecorder}</dt>
|
||
<dd>This class is used to record video from the camera.</dd>
|
||
|
||
<dt>{@link android.content.Intent}</dt>
|
||
<dd>An intent action type of {@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE
|
||
MediaStore.ACTION_IMAGE_CAPTURE} or {@link android.provider.MediaStore#ACTION_VIDEO_CAPTURE
|
||
MediaStore.ACTION_VIDEO_CAPTURE} can be used to capture images or videos without directly
|
||
using the {@link android.hardware.Camera} object.</dd>
|
||
</dl>
|
||
|
||
|
||
<h2 id="manifest">Manifest Declarations</h2>
|
||
<p>Before starting development on your application with the Camera API, you should make sure
|
||
your manifest has the appropriate declarations to allow use of camera hardware and other
|
||
related features.</p>
|
||
|
||
<ul>
|
||
<li><strong>Camera Permission</strong> - Your application must request permission to use a device
|
||
camera.
|
||
<pre>
|
||
<uses-permission android:name="android.permission.CAMERA" />
|
||
</pre>
|
||
<p class="note"><strong>Note:</strong> If you are using the camera <a href="#intents">via an
|
||
intent</a>, your application does not need to request this permission.</p>
|
||
</li>
|
||
<li><strong>Camera Features</strong> - Your application must also declare use of camera features,
|
||
for example:
|
||
<pre>
|
||
<uses-feature android:name="android.hardware.camera" />
|
||
</pre>
|
||
<p>For a list of camera features, see the manifest
|
||
<a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#hw-features">Features
|
||
Reference</a>.</p>
|
||
<p>Adding camera features to your manifest causes Google Play to prevent your application from
|
||
being installed to devices that do not include a camera or do not support the camera features you
|
||
specify. For more information about using feature-based filtering with Google Play, see <a
|
||
href="{@docRoot}guide/topics/manifest/uses-feature-element.html#market-feature-filtering">Google
|
||
Play and Feature-Based Filtering</a>.</p>
|
||
<p>If your application <em>can use</em> a camera or camera feature for proper operation, but does
|
||
not <em>require</em> it, you should specify this in the manifest by including the {@code
|
||
android:required} attribute, and setting it to {@code false}:</p>
|
||
<pre>
|
||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||
</pre>
|
||
|
||
</li>
|
||
<li><strong>Storage Permission</strong> - If your application saves images or videos to the
|
||
device's external storage (SD Card), you must also specify this in the manifest.
|
||
<pre>
|
||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||
</pre>
|
||
</li>
|
||
<li><strong>Audio Recording Permission</strong> - For recording audio with video capture, your
|
||
application must request the audio capture permission.
|
||
<pre>
|
||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||
</pre>
|
||
</li>
|
||
<li><strong>Location Permission</strong> - If your application tags images with GPS location
|
||
information, you must request location permission:
|
||
<pre>
|
||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||
</pre>
|
||
<p>For more information about getting user location, see
|
||
<a href="{@docRoot}guide/topics/location/strategies.html">Location Strategies</a>.</p>
|
||
</li>
|
||
</ul>
|
||
|
||
|
||
<h2 id="intents">Using Existing Camera Apps</h2>
|
||
<p>A quick way to enable taking pictures or videos in your application without a lot of extra code
|
||
is to use an {@link android.content.Intent} to invoke an existing Android camera application. A
|
||
camera intent makes a request to capture a picture or video clip through an existing camera app and
|
||
then returns control back to your application. This section shows you how to capture an image or
|
||
video using this technique.</p>
|
||
|
||
<p>The procedure for invoking a camera intent follows these general steps:</p>
|
||
|
||
<ol>
|
||
<li><strong>Compose a Camera Intent</strong> - Create an {@link android.content.Intent} that
|
||
requests an image or video, using one of these intent types:
|
||
<ul>
|
||
<li>{@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE MediaStore.ACTION_IMAGE_CAPTURE} -
|
||
Intent action type for requesting an image from an existing camera application.</li>
|
||
<li>{@link android.provider.MediaStore#ACTION_VIDEO_CAPTURE MediaStore.ACTION_VIDEO_CAPTURE} -
|
||
Intent action type for requesting a video from an existing camera application. </li>
|
||
</ul>
|
||
</li>
|
||
<li><strong>Start the Camera Intent</strong> - Use the {@link
|
||
android.app.Activity#startActivityForResult(android.content.Intent, int) startActivityForResult()}
|
||
method to execute the camera intent. After you start the intent, the Camera application user
|
||
interface appears on the device screen and the user can take a picture or video.</li>
|
||
<li><strong>Receive the Intent Result</strong> - Set up an {@link
|
||
android.app.Activity#onActivityResult(int, int, android.content.Intent) 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.</li>
|
||
</ol>
|
||
|
||
|
||
<h3 id="intent-image">Image capture intent</h3>
|
||
<p>Capturing images using a camera intent is quick way to enable your application to take pictures
|
||
with minimal coding. An image capture intent can include the following extra information:</p>
|
||
|
||
<ul>
|
||
<li>{@link android.provider.MediaStore#EXTRA_OUTPUT MediaStore.EXTRA_OUTPUT} - This setting
|
||
requires a {@link android.net.Uri} object specifying a path and file name where you'd like to
|
||
save the picture. This setting is optional but strongly recommended. If you do not specify this
|
||
value, the camera application saves the requested picture in the default location with a default
|
||
name, specified in the returned intent's {@link android.content.Intent#getData() Intent.getData()}
|
||
field.</li>
|
||
</ul>
|
||
|
||
<p>The following example demonstrates how to construct a image capture intent and execute it.
|
||
The {@code getOutputMediaFileUri()} method in this example refers to the sample code shown in <a
|
||
href= "#saving-media">Saving Media Files</a>.</p>
|
||
|
||
<pre>
|
||
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);
|
||
}
|
||
</pre>
|
||
|
||
<p>When the {@link android.app.Activity#startActivityForResult(android.content.Intent, int)
|
||
startActivityForResult()} method is executed, users see a camera application interface.
|
||
After the user finishes taking a picture (or cancels the operation), the user interface returns to
|
||
your application, and you must intercept the {@link
|
||
android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()}
|
||
method to receive the result of the intent and continue your application execution. For information
|
||
on how to receive the completed intent, see <a href="#intent-receive">Receiving camera intent
|
||
result</a>.</p>
|
||
|
||
|
||
<h3 id="intent-video">Video capture intent</h3>
|
||
<p>Capturing video using a camera intent is a quick way to enable your application to take videos
|
||
with minimal coding. A video capture intent can include the following extra information:</p>
|
||
|
||
<ul>
|
||
<li>{@link android.provider.MediaStore#EXTRA_OUTPUT MediaStore.EXTRA_OUTPUT} - This setting
|
||
requires a {@link android.net.Uri} specifying a path and file name where you'd 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, specified
|
||
in the returned intent's {@link android.content.Intent#getData() Intent.getData()} field.</li>
|
||
<li>{@link android.provider.MediaStore#EXTRA_VIDEO_QUALITY MediaStore.EXTRA_VIDEO_QUALITY} -
|
||
This value can be 0 for lowest quality and smallest file size or 1 for highest quality and
|
||
larger file size.</li>
|
||
<li>{@link android.provider.MediaStore#EXTRA_DURATION_LIMIT MediaStore.EXTRA_DURATION_LIMIT} -
|
||
Set this value to limit the length, in seconds, of the video being captured.</li>
|
||
<li>{@link android.provider.MediaStore#EXTRA_SIZE_LIMIT MediaStore.EXTRA_SIZE_LIMIT} -
|
||
Set this value to limit the file size, in bytes, of the video being captured.
|
||
</li>
|
||
</ul>
|
||
|
||
<p>The following example demonstrates how to construct a video capture intent and execute it.
|
||
The {@code getOutputMediaFileUri()} method in this example refers to the sample code shown in <a
|
||
href= "#saving-media">Saving Media Files</a>.</p>
|
||
|
||
<pre>
|
||
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);
|
||
}
|
||
</pre>
|
||
|
||
<p>When the {@link
|
||
android.app.Activity#startActivityForResult(android.content.Intent, int)
|
||
startActivityForResult()} method is executed, users see a modified 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 {@link
|
||
android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()}
|
||
method to receive the result of the intent and continue your application execution. For information
|
||
on how to receive the completed intent, see the next section.</p>
|
||
|
||
<h3 id="intent-receive">Receiving camera intent result</h3>
|
||
<p>Once you have constructed and executed an image or video camera intent, your application must be
|
||
configured to receive the result of the intent. This section shows you how to intercept the callback
|
||
from a camera intent so your application can do further processing of the captured image or
|
||
video.</p>
|
||
|
||
<p>In order to receive the result of an intent, you must override the {@link
|
||
android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()} in the
|
||
activity that started the intent. The following example demonstrates how to override {@link
|
||
android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()} to
|
||
capture the result of the <a href="#intent-image">image camera intent</a> or <a
|
||
href="#intent-video">video camera intent</a> examples shown in the previous sections.</p>
|
||
|
||
<pre>
|
||
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
|
||
}
|
||
}
|
||
}
|
||
</pre>
|
||
|
||
<p>Once your activity receives a successful result, the captured image or video is available in the
|
||
specified location for your application to access.</p>
|
||
|
||
|
||
|
||
<h2 id="custom-camera">Building a Camera App</h2>
|
||
<p>Some developers may require a camera user interface that is customized to the look of their
|
||
application or provides special features. Creating a customized camera activity requires more
|
||
code than <a href="#intents">using an intent</a>, but it can provide a more compelling experience
|
||
for your users.</p>
|
||
|
||
<p>The general steps for creating a custom camera interface for your application are as follows:</p>
|
||
|
||
<ul>
|
||
<li><strong>Detect and Access Camera</strong> - Create code to check for the existence of
|
||
cameras and request access.</li>
|
||
<li><strong>Create a Preview Class</strong> - Create a camera preview class that extends {@link
|
||
android.view.SurfaceView} and implements the {@link android.view.SurfaceHolder} interface. This
|
||
class previews the live images from the camera.</li>
|
||
<li><strong>Build a Preview Layout</strong> - Once you have the camera preview class, create a
|
||
view layout that incorporates the preview and the user interface controls you want.</li>
|
||
<li><strong>Setup Listeners for Capture</strong> - Connect listeners for your interface
|
||
controls to start image or video capture in response to user actions, such as pressing a
|
||
button.</li>
|
||
<li><strong>Capture and Save Files</strong> - Setup the code for capturing pictures or
|
||
videos and saving the output.</li>
|
||
<li><strong>Release the Camera</strong> - After using the camera, your application must
|
||
properly release it for use by other applications.</li>
|
||
</ul>
|
||
|
||
<p>Camera hardware is a shared resource that must be carefully managed so your application does
|
||
not collide with other applications that may also want to use it. The following sections discusses
|
||
how to detect camera hardware, how to request access to a camera, how to capture pictures or video
|
||
and how to release the camera when your application is done using it.</p>
|
||
|
||
<p class="caution"><strong>Caution:</strong> Remember to release the {@link android.hardware.Camera}
|
||
object by calling the {@link android.hardware.Camera#release() Camera.release()} when your
|
||
application is done using it! If your application does not properly release the camera, all
|
||
subsequent attempts to access the camera, including those by your own application, will fail and may
|
||
cause your or other applications to be shut down.</p>
|
||
|
||
|
||
<h3 id="detect-camera">Detecting camera hardware</h3>
|
||
<p>If your application does not specifically require a camera using a manifest declaration, you
|
||
should check to see if a camera is available at runtime. To perform this check, use the {@link
|
||
android.content.pm.PackageManager#hasSystemFeature(java.lang.String)
|
||
PackageManager.hasSystemFeature()} method, as shown in the example code below:</p>
|
||
|
||
<pre>
|
||
/** Check if this device has a camera */
|
||
private boolean checkCameraHardware(Context context) {
|
||
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
|
||
// this device has a camera
|
||
return true;
|
||
} else {
|
||
// no camera on this device
|
||
return false;
|
||
}
|
||
}
|
||
</pre>
|
||
|
||
<p>Android devices can have multiple cameras, for example a back-facing camera for photography and a
|
||
front-facing camera for video calls. Android 2.3 (API Level 9) and later allows you to check the
|
||
number of cameras available on a device using the {@link
|
||
android.hardware.Camera#getNumberOfCameras() Camera.getNumberOfCameras()} method.</p>
|
||
|
||
<h3 id="access-camera">Accessing cameras</h3>
|
||
<p>If you have determined that the device on which your application is running has a camera, you
|
||
must request to access it by getting an instance of {@link android.hardware.Camera} (unless you
|
||
are using an <a href="#intents">intent to access the camera</a>). </p>
|
||
|
||
<p>To access the primary camera, use the {@link android.hardware.Camera#open() Camera.open()} method
|
||
and be sure to catch any exceptions, as shown in the code below:</p>
|
||
|
||
<pre>
|
||
/** A safe way to get an instance of the Camera object. */
|
||
public static Camera getCameraInstance(){
|
||
Camera c = null;
|
||
try {
|
||
c = Camera.open(); // attempt to get a Camera instance
|
||
}
|
||
catch (Exception e){
|
||
// Camera is not available (in use or does not exist)
|
||
}
|
||
return c; // returns null if camera is unavailable
|
||
}
|
||
</pre>
|
||
|
||
<p class="caution"><strong>Caution:</strong> Always check for exceptions when using {@link
|
||
android.hardware.Camera#open() Camera.open()}. Failing to check for exceptions if the camera is in
|
||
use or does not exist will cause your application to be shut down by the system.</p>
|
||
|
||
<p>On devices running Android 2.3 (API Level 9) or higher, you can access specific cameras using
|
||
{@link android.hardware.Camera#open(int) Camera.open(int)}. The example code above will access
|
||
the first, back-facing camera on a device with more than one camera.</p>
|
||
|
||
<h3 id="check-camera-features">Checking camera features</h3>
|
||
<p>Once you obtain access to a camera, you can get further information about its capabilities using
|
||
the {@link android.hardware.Camera#getParameters() Camera.getParameters()} method and checking the
|
||
returned {@link android.hardware.Camera.Parameters} object for supported capabilities. When using
|
||
API Level 9 or higher, use the {@link android.hardware.Camera#getCameraInfo(int,
|
||
android.hardware.Camera.CameraInfo) Camera.getCameraInfo()} to determine if a camera is on the front
|
||
or back of the device, and the orientation of the image.</p>
|
||
|
||
|
||
|
||
<h3 id="camera-preview">Creating a preview class</h3>
|
||
<p>For users to effectively take pictures or video, they must be able to see what the device camera
|
||
sees. A camera preview class is a {@link android.view.SurfaceView} that can display the live image
|
||
data coming from a camera, so users can frame and capture a picture or video.</p>
|
||
|
||
<p>The following example code demonstrates how to create a basic camera preview class that can be
|
||
included in a {@link android.view.View} layout. This class implements {@link
|
||
android.view.SurfaceHolder.Callback SurfaceHolder.Callback} in order to capture the callback events
|
||
for creating and destroying the view, which are needed for assigning the camera preview input.</p>
|
||
|
||
<pre>
|
||
/** A basic Camera preview class */
|
||
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
|
||
private SurfaceHolder mHolder;
|
||
private Camera mCamera;
|
||
|
||
public CameraPreview(Context context, Camera camera) {
|
||
super(context);
|
||
mCamera = camera;
|
||
|
||
// Install a SurfaceHolder.Callback so we get notified when the
|
||
// underlying surface is created and destroyed.
|
||
mHolder = getHolder();
|
||
mHolder.addCallback(this);
|
||
// deprecated setting, but required on Android versions prior to 3.0
|
||
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
||
}
|
||
|
||
public void surfaceCreated(SurfaceHolder holder) {
|
||
// The Surface has been created, now tell the camera where to draw the preview.
|
||
try {
|
||
mCamera.setPreviewDisplay(holder);
|
||
mCamera.startPreview();
|
||
} catch (IOException e) {
|
||
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
|
||
}
|
||
}
|
||
|
||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||
// empty. Take care of releasing the Camera preview in your activity.
|
||
}
|
||
|
||
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
||
// If your preview can change or rotate, take care of those events here.
|
||
// Make sure to stop the preview before resizing or reformatting it.
|
||
|
||
if (mHolder.getSurface() == null){
|
||
// preview surface does not exist
|
||
return;
|
||
}
|
||
|
||
// stop preview before making changes
|
||
try {
|
||
mCamera.stopPreview();
|
||
} catch (Exception e){
|
||
// ignore: tried to stop a non-existent preview
|
||
}
|
||
|
||
// set preview size and make any resize, rotate or
|
||
// reformatting changes here
|
||
|
||
// start preview with new settings
|
||
try {
|
||
mCamera.setPreviewDisplay(mHolder);
|
||
mCamera.startPreview();
|
||
|
||
} catch (Exception e){
|
||
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
|
||
}
|
||
}
|
||
}
|
||
</pre>
|
||
|
||
<p>If you want to set a specific size for your camera preview, set this in the {@code
|
||
surfaceChanged()} method as noted in the comments above. When setting preview size, you
|
||
<em>must use</em> values from {@link android.hardware.Camera.Parameters#getSupportedPreviewSizes}.
|
||
<em>Do not</em> set arbitrary values in the {@link
|
||
android.hardware.Camera.Parameters#setPreviewSize setPreviewSize()} method.</p>
|
||
|
||
|
||
<h3 id="preview-layout">Placing preview in a layout</h3>
|
||
<p>A camera preview class, such as the example shown in the previous section, must be placed in the
|
||
layout of an activity along with other user interface controls for taking a picture or video. This
|
||
section shows you how to build a basic layout and activity for the preview.</p>
|
||
|
||
<p>The following layout code provides a very basic view that can be used to display a camera
|
||
preview. In this example, the {@link android.widget.FrameLayout} element is meant to be the
|
||
container for the camera preview class. This layout type is used so that additional picture
|
||
information or controls can be overlayed on the live camera preview images.</p>
|
||
|
||
<pre>
|
||
<?xml version="1.0" encoding="utf-8"?>
|
||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||
android:orientation="horizontal"
|
||
android:layout_width="fill_parent"
|
||
android:layout_height="fill_parent"
|
||
>
|
||
<FrameLayout
|
||
android:id="@+id/camera_preview"
|
||
android:layout_width="fill_parent"
|
||
android:layout_height="fill_parent"
|
||
android:layout_weight="1"
|
||
/>
|
||
|
||
<Button
|
||
android:id="@+id/button_capture"
|
||
android:text="Capture"
|
||
android:layout_width="wrap_content"
|
||
android:layout_height="wrap_content"
|
||
android:layout_gravity="center"
|
||
/>
|
||
</LinearLayout>
|
||
</pre>
|
||
|
||
<p>On most devices, the default orientation of the camera preview is landscape. This example layout
|
||
specifies a horizontal (landscape) layout and the code below fixes the orientation of the
|
||
application to landscape. For simplicity in rendering a camera preview, you should change your
|
||
application's preview activity orientation to landscape by adding the following to your
|
||
manifest.</p>
|
||
|
||
<pre>
|
||
<activity android:name=".CameraActivity"
|
||
android:label="@string/app_name"
|
||
|
||
android:screenOrientation="landscape">
|
||
<!-- configure this activity to use landscape orientation -->
|
||
|
||
<intent-filter>
|
||
<action android:name="android.intent.action.MAIN" />
|
||
<category android:name="android.intent.category.LAUNCHER" />
|
||
</intent-filter>
|
||
</activity>
|
||
</pre>
|
||
|
||
<p class="note"><strong>Note:</strong> A camera preview does not have to be in landscape mode.
|
||
Starting in Android 2.2 (API Level 8), you can use the {@link
|
||
android.hardware.Camera#setDisplayOrientation(int) setDisplayOrientation()} method to set the
|
||
rotation of the preview image. In order to change preview orientation as the user re-orients the
|
||
phone, within the {@link
|
||
android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder, int, int, int)
|
||
surfaceChanged()} method of your preview class, first stop the preview with {@link
|
||
android.hardware.Camera#stopPreview() Camera.stopPreview()} change the orientation and then
|
||
start the preview again with {@link android.hardware.Camera#startPreview()
|
||
Camera.startPreview()}.</p>
|
||
|
||
<p>In the activity for your camera view, add your preview class to the {@link
|
||
android.widget.FrameLayout} element shown in the example above. Your camera activity must also
|
||
ensure that it releases the camera when it is paused or shut down. The following example shows how
|
||
to modify a camera activity to attach the preview class shown in <a href="#camera-preview">Creating
|
||
a preview class</a>.</p>
|
||
|
||
<pre>
|
||
public class CameraActivity extends Activity {
|
||
|
||
private Camera mCamera;
|
||
private CameraPreview mPreview;
|
||
|
||
@Override
|
||
public void onCreate(Bundle savedInstanceState) {
|
||
super.onCreate(savedInstanceState);
|
||
setContentView(R.layout.main);
|
||
|
||
// Create an instance of Camera
|
||
mCamera = getCameraInstance();
|
||
|
||
// Create our Preview view and set it as the content of our activity.
|
||
mPreview = new CameraPreview(this, mCamera);
|
||
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
|
||
preview.addView(mPreview);
|
||
}
|
||
}
|
||
</pre>
|
||
|
||
<p class="note"><strong>Note:</strong> The {@code getCameraInstance()} method in the example above
|
||
refers to the example method shown in <a href="#access-camera">Accessing cameras</a>.</p>
|
||
|
||
|
||
<h3 id="capture-picture">Capturing pictures</h3>
|
||
<p>Once you have built a preview class and a view layout in which to display it, you are ready to
|
||
start capturing images with your application. In your application code, you must set up listeners
|
||
for your user interface controls to respond to a user action by taking a picture.</p>
|
||
|
||
<p>In order to retrieve a picture, use the {@link
|
||
android.hardware.Camera#takePicture(android.hardware.Camera.ShutterCallback,
|
||
android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback)
|
||
Camera.takePicture()} method. This method takes three parameters which receive data from the camera.
|
||
In order to receive data in a JPEG format, you must implement an {@link
|
||
android.hardware.Camera.PictureCallback} interface to receive the image data and
|
||
write it to a file. The following code shows a basic implementation of the {@link
|
||
android.hardware.Camera.PictureCallback} interface to save an image received from the camera.</p>
|
||
|
||
<pre>
|
||
private PictureCallback mPicture = new PictureCallback() {
|
||
|
||
@Override
|
||
public void onPictureTaken(byte[] data, Camera camera) {
|
||
|
||
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
|
||
if (pictureFile == null){
|
||
Log.d(TAG, "Error creating media file, check storage permissions: " +
|
||
e.getMessage());
|
||
return;
|
||
}
|
||
|
||
try {
|
||
FileOutputStream fos = new FileOutputStream(pictureFile);
|
||
fos.write(data);
|
||
fos.close();
|
||
} catch (FileNotFoundException e) {
|
||
Log.d(TAG, "File not found: " + e.getMessage());
|
||
} catch (IOException e) {
|
||
Log.d(TAG, "Error accessing file: " + e.getMessage());
|
||
}
|
||
}
|
||
};
|
||
</pre>
|
||
|
||
<p>Trigger capturing an image by calling the {@link
|
||
android.hardware.Camera#takePicture(android.hardware.Camera.ShutterCallback,
|
||
android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback)
|
||
Camera.takePicture()} method. The following example code shows how to call this method from a
|
||
button {@link android.view.View.OnClickListener}.</p>
|
||
|
||
<pre>
|
||
// Add a listener to the Capture button
|
||
Button captureButton = (Button) findViewById(id.button_capture);
|
||
captureButton.setOnClickListener(
|
||
new View.OnClickListener() {
|
||
@Override
|
||
public void onClick(View v) {
|
||
// get an image from the camera
|
||
mCamera.takePicture(null, null, mPicture);
|
||
}
|
||
}
|
||
);
|
||
</pre>
|
||
|
||
<p class="note"><strong>Note:</strong> The {@code mPicture} member in the following example refers
|
||
to the example code above.</p>
|
||
|
||
<p class="caution"><strong>Caution:</strong> Remember to release the {@link android.hardware.Camera}
|
||
object by calling the {@link android.hardware.Camera#release() Camera.release()} when your
|
||
application is done using it! For information about how to release the camera, see <a
|
||
href="#release-camera">Releasing the camera</a>.</p>
|
||
|
||
|
||
<h3 id="capture-video">Capturing videos</h3>
|
||
|
||
<p>Video capture using the Android framework requires careful management of the {@link
|
||
android.hardware.Camera} object and coordination with the {@link android.media.MediaRecorder}
|
||
class. When recording video with {@link android.hardware.Camera}, you must manage the {@link
|
||
android.hardware.Camera#lock() Camera.lock()} and {@link android.hardware.Camera#unlock()
|
||
Camera.unlock()} calls to allow {@link android.media.MediaRecorder} access to the camera hardware,
|
||
in addition to the {@link android.hardware.Camera#open() Camera.open()} and {@link
|
||
android.hardware.Camera#release() Camera.release()} calls.</p>
|
||
|
||
<p class="note"><strong>Note:</strong> Starting with Android 4.0 (API level 14), the {@link
|
||
android.hardware.Camera#lock() Camera.lock()} and {@link android.hardware.Camera#unlock()
|
||
Camera.unlock()} calls are managed for you automatically.</p>
|
||
|
||
<p>Unlike taking pictures with a device camera, capturing video requires a very particular call
|
||
order. You must follow a specific order of execution to successfully prepare for and capture video
|
||
with your application, as detailed below.</p>
|
||
|
||
<ol>
|
||
<li><strong>Open Camera</strong> - Use the {@link android.hardware.Camera#open() Camera.open()}
|
||
to get an instance of the camera object.</li>
|
||
<li><strong>Connect Preview</strong> - Prepare a live camera image preview by connecting a {@link
|
||
android.view.SurfaceView} to the camera using {@link
|
||
android.hardware.Camera#setPreviewDisplay(android.view.SurfaceHolder) Camera.setPreviewDisplay()}.
|
||
</li>
|
||
<li><strong>Start Preview</strong> - Call {@link android.hardware.Camera#startPreview()
|
||
Camera.startPreview()} to begin displaying the live camera images.</li>
|
||
<li><strong>Start Recording Video</strong> - The following steps must be completed <em>in
|
||
order</em> to successfully record video:
|
||
<ol style="list-style-type: lower-alpha;">
|
||
<li><strong>Unlock the Camera</strong> - Unlock the camera for use by {@link
|
||
android.media.MediaRecorder} by calling {@link android.hardware.Camera#unlock()
|
||
Camera.unlock()}.</li>
|
||
<li><strong>Configure MediaRecorder</strong> - Call in the following {@link
|
||
android.media.MediaRecorder} methods <em>in this order</em>. For more information, see the {@link
|
||
android.media.MediaRecorder} reference documentation.
|
||
<ol>
|
||
<li>{@link android.media.MediaRecorder#setCamera(android.hardware.Camera)
|
||
setCamera()} - Set the camera to be used for video capture, use your application's current instance
|
||
of {@link android.hardware.Camera}.</li>
|
||
<li>{@link android.media.MediaRecorder#setAudioSource(int) setAudioSource()} - Set the
|
||
audio source, use {@link android.media.MediaRecorder.AudioSource#CAMCORDER
|
||
MediaRecorder.AudioSource.CAMCORDER}. </li>
|
||
<li>{@link android.media.MediaRecorder#setVideoSource(int) setVideoSource()} - Set
|
||
the video source, use {@link android.media.MediaRecorder.VideoSource#CAMERA
|
||
MediaRecorder.VideoSource.CAMERA}.</li>
|
||
<li>Set the video output format and encoding. For Android 2.2 (API Level 8) and
|
||
higher, use the {@link android.media.MediaRecorder#setProfile(android.media.CamcorderProfile)
|
||
MediaRecorder.setProfile} method, and get a profile instance using {@link
|
||
android.media.CamcorderProfile#get(int) CamcorderProfile.get()}. For versions of Android prior to
|
||
2.2, you must set the video output format and encoding parameters:
|
||
<ol style="list-style-type: lower-roman;">
|
||
<li>{@link android.media.MediaRecorder#setOutputFormat(int) setOutputFormat()} - Set
|
||
the output format, specify the default setting or {@link
|
||
android.media.MediaRecorder.OutputFormat#MPEG_4 MediaRecorder.OutputFormat.MPEG_4}.</li>
|
||
<li>{@link android.media.MediaRecorder#setAudioEncoder(int) setAudioEncoder()} - Set
|
||
the sound encoding type, specify the default setting or {@link
|
||
android.media.MediaRecorder.AudioEncoder#AMR_NB MediaRecorder.AudioEncoder.AMR_NB}.</li>
|
||
<li>{@link android.media.MediaRecorder#setVideoEncoder(int) setVideoEncoder()} - Set
|
||
the video encoding type, specify the default setting or {@link
|
||
android.media.MediaRecorder.VideoEncoder#MPEG_4_SP MediaRecorder.VideoEncoder.MPEG_4_SP}.</li>
|
||
</ol>
|
||
</li>
|
||
<li>{@link android.media.MediaRecorder#setOutputFile(java.lang.String) setOutputFile()} -
|
||
Set the output file, use {@code getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()} from the example
|
||
method in the <a href="#saving-media">Saving Media Files</a> section.</li>
|
||
<li>{@link android.media.MediaRecorder#setPreviewDisplay(android.view.Surface)
|
||
setPreviewDisplay()} - Specify the {@link android.view.SurfaceView} preview layout element for
|
||
your application. Use the same object you specified for <strong>Connect Preview</strong>.</li>
|
||
</ol>
|
||
<p class="caution"><strong>Caution:</strong> You must call these {@link
|
||
android.media.MediaRecorder} configuration methods <em>in this order</em>, otherwise your
|
||
application will encounter errors and the recording will fail.</p>
|
||
</li>
|
||
<li><strong>Prepare MediaRecorder</strong> - Prepare the {@link android.media.MediaRecorder}
|
||
with provided configuration settings by calling {@link android.media.MediaRecorder#prepare()
|
||
MediaRecorder.prepare()}.</li>
|
||
<li><strong>Start MediaRecorder</strong> - Start recording video by calling {@link
|
||
android.media.MediaRecorder#start() MediaRecorder.start()}.</li>
|
||
</ol>
|
||
</li>
|
||
<li><strong>Stop Recording Video</strong> - Call the following methods <em>in order</em>, to
|
||
successfully complete a video recording:
|
||
<ol style="list-style-type: lower-alpha;">
|
||
<li><strong>Stop MediaRecorder</strong> - Stop recording video by calling {@link
|
||
android.media.MediaRecorder#stop() MediaRecorder.stop()}.</li>
|
||
<li><strong>Reset MediaRecorder</strong> - Optionally, remove the configuration settings from
|
||
the recorder by calling {@link android.media.MediaRecorder#reset() MediaRecorder.reset()}.</li>
|
||
<li><strong>Release MediaRecorder</strong> - Release the {@link android.media.MediaRecorder}
|
||
by calling {@link android.media.MediaRecorder#release() MediaRecorder.release()}.</li>
|
||
<li><strong>Lock the Camera</strong> - Lock the camera so that future {@link
|
||
android.media.MediaRecorder} sessions can use it by calling {@link android.hardware.Camera#lock()
|
||
Camera.lock()}. Starting with Android 4.0 (API level 14), this call is not required unless the
|
||
{@link android.media.MediaRecorder#prepare() MediaRecorder.prepare()} call fails.</li>
|
||
</ol>
|
||
</li>
|
||
<li><strong>Stop the Preview</strong> - When your activity has finished using the camera, stop the
|
||
preview using {@link android.hardware.Camera#stopPreview() Camera.stopPreview()}.</li>
|
||
<li><strong>Release Camera</strong> - Release the camera so that other applications can use
|
||
it by calling {@link android.hardware.Camera#release() Camera.release()}.</li>
|
||
</ol>
|
||
|
||
<p class="note"><strong>Note:</strong> It is possible to use {@link android.media.MediaRecorder}
|
||
without creating a camera preview first and skip the first few steps of this process. However,
|
||
since users typically prefer to see a preview before starting a recording, that process is not
|
||
discussed here.</p>
|
||
|
||
<p class="note"><strong>Tip:</strong> If your application is typically used for recording video, set
|
||
{@link android.hardware.Camera.Parameters#setRecordingHint} to {@code true} prior to starting your
|
||
preview. This setting can help reduce the time it takes to start recording.</p>
|
||
|
||
<h4 id="configuring-mediarecorder">Configuring MediaRecorder</h4>
|
||
<p>When using the {@link android.media.MediaRecorder} class to record video, you must perform
|
||
configuration steps in a <em>specific order</em> and then call the {@link
|
||
android.media.MediaRecorder#prepare() MediaRecorder.prepare()} method to check and implement the
|
||
configuration. The following example code demonstrates how to properly configure and prepare the
|
||
{@link android.media.MediaRecorder} class for video recording.</p>
|
||
|
||
<pre>
|
||
private boolean prepareVideoRecorder(){
|
||
|
||
mCamera = getCameraInstance();
|
||
mMediaRecorder = new MediaRecorder();
|
||
|
||
// Step 1: Unlock and set camera to MediaRecorder
|
||
mCamera.unlock();
|
||
mMediaRecorder.setCamera(mCamera);
|
||
|
||
// Step 2: Set sources
|
||
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
|
||
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
|
||
|
||
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
|
||
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
|
||
|
||
// Step 4: Set output file
|
||
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
|
||
|
||
// Step 5: Set the preview output
|
||
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
|
||
|
||
// Step 6: Prepare configured MediaRecorder
|
||
try {
|
||
mMediaRecorder.prepare();
|
||
} catch (IllegalStateException e) {
|
||
Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
|
||
releaseMediaRecorder();
|
||
return false;
|
||
} catch (IOException e) {
|
||
Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
|
||
releaseMediaRecorder();
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
</pre>
|
||
|
||
<p>Prior to Android 2.2 (API Level 8), you must set the output format and encoding formats
|
||
parameters directly, instead of using {@link android.media.CamcorderProfile}. This approach is
|
||
demonstrated in the following code:</p>
|
||
|
||
<pre>
|
||
// Step 3: Set output format and encoding (for versions prior to API Level 8)
|
||
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
|
||
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
|
||
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
|
||
</pre>
|
||
|
||
<p>The following video recording parameters for {@link android.media.MediaRecorder} are given
|
||
default settings, however, you may want to adjust these settings for your application:</p>
|
||
|
||
<ul>
|
||
<li>{@link android.media.MediaRecorder#setVideoEncodingBitRate(int)
|
||
setVideoEncodingBitRate()}</li>
|
||
<li>{@link android.media.MediaRecorder#setVideoSize(int, int) setVideoSize()}</li>
|
||
<li>{@link android.media.MediaRecorder#setVideoFrameRate(int) setVideoFrameRate()}</li>
|
||
<li>{@link android.media.MediaRecorder#setAudioEncodingBitRate(int)
|
||
setAudioEncodingBitRate()}</li> <li>{@link android.media.MediaRecorder#setAudioChannels(int)
|
||
setAudioChannels()}</li>
|
||
<li>{@link android.media.MediaRecorder#setAudioSamplingRate(int) setAudioSamplingRate()}</li>
|
||
</ul>
|
||
|
||
<h4 id="start-stop-mediarecorder">Starting and stopping MediaRecorder</h4>
|
||
<p>When starting and stopping video recording using the {@link android.media.MediaRecorder} class,
|
||
you must follow a specific order, as listed below.</p>
|
||
|
||
<ol>
|
||
<li>Unlock the camera with {@link android.hardware.Camera#unlock() Camera.unlock()}</li>
|
||
<li>Configure {@link android.media.MediaRecorder} as shown in the code example above</li>
|
||
<li>Start recording using {@link android.media.MediaRecorder#start()
|
||
MediaRecorder.start()}</li>
|
||
<li>Record the video</li>
|
||
<li>Stop recording using {@link
|
||
android.media.MediaRecorder#stop() MediaRecorder.stop()}</li>
|
||
<li>Release the media recorder with {@link android.media.MediaRecorder#release()
|
||
MediaRecorder.release()}</li>
|
||
<li>Lock the camera using {@link android.hardware.Camera#lock() Camera.lock()}</li>
|
||
</ol>
|
||
|
||
<p>The following example code demonstrates how to wire up a button to properly start and stop
|
||
video recording using the camera and the {@link android.media.MediaRecorder} class.</p>
|
||
|
||
<p class="note"><strong>Note:</strong> When completing a video recording, do not release the camera
|
||
or else your preview will be stopped.</p>
|
||
|
||
<pre>
|
||
private boolean isRecording = false;
|
||
|
||
// Add a listener to the Capture button
|
||
Button captureButton = (Button) findViewById(id.button_capture);
|
||
captureButton.setOnClickListener(
|
||
new View.OnClickListener() {
|
||
@Override
|
||
public void onClick(View v) {
|
||
if (isRecording) {
|
||
// stop recording and release camera
|
||
mMediaRecorder.stop(); // stop the recording
|
||
releaseMediaRecorder(); // release the MediaRecorder object
|
||
mCamera.lock(); // take camera access back from MediaRecorder
|
||
|
||
// inform the user that recording has stopped
|
||
setCaptureButtonText("Capture");
|
||
isRecording = false;
|
||
} else {
|
||
// initialize video camera
|
||
if (prepareVideoRecorder()) {
|
||
// Camera is available and unlocked, MediaRecorder is prepared,
|
||
// now you can start recording
|
||
mMediaRecorder.start();
|
||
|
||
// inform the user that recording has started
|
||
setCaptureButtonText("Stop");
|
||
isRecording = true;
|
||
} else {
|
||
// prepare didn't work, release the camera
|
||
releaseMediaRecorder();
|
||
// inform user
|
||
}
|
||
}
|
||
}
|
||
}
|
||
);
|
||
</pre>
|
||
|
||
<p class="note"><strong>Note:</strong> In the above example, the {@code prepareVideoRecorder()}
|
||
method refers to the example code shown in <a
|
||
href="#configuring-mediarecorder">Configuring MediaRecorder</a>. This method takes care of locking
|
||
the camera, configuring and preparing the {@link android.media.MediaRecorder} instance.</p>
|
||
|
||
|
||
<h3 id="release-camera">Releasing the camera</h3>
|
||
<p>Cameras are a resource that is shared by applications on a device. Your application can make
|
||
use of the camera after getting an instance of {@link android.hardware.Camera}, and you must be
|
||
particularly careful to release the camera object when your application stops using it, and as
|
||
soon as your application is paused ({@link android.app.Activity#onPause() Activity.onPause()}). If
|
||
your application does not properly release the camera, all subsequent attempts to access the camera,
|
||
including those by your own application, will fail and may cause your or other applications to be
|
||
shut down.</p>
|
||
|
||
<p>To release an instance of the {@link android.hardware.Camera} object, use the {@link
|
||
android.hardware.Camera#release() Camera.release()} method, as shown in the example code below.</p>
|
||
|
||
<pre>
|
||
public class CameraActivity extends Activity {
|
||
private Camera mCamera;
|
||
private SurfaceView mPreview;
|
||
private MediaRecorder mMediaRecorder;
|
||
|
||
...
|
||
|
||
@Override
|
||
protected void onPause() {
|
||
super.onPause();
|
||
releaseMediaRecorder(); // if you are using MediaRecorder, release it first
|
||
releaseCamera(); // release the camera immediately on pause event
|
||
}
|
||
|
||
private void releaseMediaRecorder(){
|
||
if (mMediaRecorder != null) {
|
||
mMediaRecorder.reset(); // clear recorder configuration
|
||
mMediaRecorder.release(); // release the recorder object
|
||
mMediaRecorder = null;
|
||
mCamera.lock(); // lock camera for later use
|
||
}
|
||
}
|
||
|
||
private void releaseCamera(){
|
||
if (mCamera != null){
|
||
mCamera.release(); // release the camera for other applications
|
||
mCamera = null;
|
||
}
|
||
}
|
||
}
|
||
</pre>
|
||
|
||
<p class="caution"><strong>Caution:</strong> If your application does not properly release the
|
||
camera, all subsequent attempts to access the camera, including those by your own application, will
|
||
fail and may cause your or other applications to be shut down.</p>
|
||
|
||
|
||
<h2 id="saving-media">Saving Media Files</h2>
|
||
<p>Media files created by users such as pictures and videos should be saved to a device's external
|
||
storage directory (SD Card) to conserve system space and to allow users to access these files
|
||
without their device. There are many possible directory locations to save media files on a device,
|
||
however there are only two standard locations you should consider as a developer:</p>
|
||
|
||
<ul>
|
||
<li><strong>{@link android.os.Environment#getExternalStoragePublicDirectory(java.lang.String)
|
||
Environment.getExternalStoragePublicDirectory}({@link android.os.Environment#DIRECTORY_PICTURES
|
||
Environment.DIRECTORY_PICTURES})</strong> - This method returns the standard, shared and recommended
|
||
location for saving pictures and videos. This directory is shared (public), so other applications
|
||
can easily discover, read, change and delete files saved in this location. If your application is
|
||
uninstalled by the user, media files saved to this location will not be removed. To avoid
|
||
interfering with users existing pictures and videos, you should create a sub-directory for your
|
||
application's media files within this directory, as shown in the code sample below. This method is
|
||
available in Android 2.2 (API Level 8), for equivalent calls in earlier API versions, see <a
|
||
href="{@docRoot}guide/topics/data/data-storage.html#SavingSharedFiles">Saving Shared Files</a>.</li>
|
||
<li><strong>{@link android.content.Context#getExternalFilesDir(java.lang.String)
|
||
Context.getExternalFilesDir}({@link android.os.Environment#DIRECTORY_PICTURES
|
||
Environment.DIRECTORY_PICTURES})</strong> - This method returns a standard location for saving
|
||
pictures and videos which are associated with your application. If your application is uninstalled,
|
||
any files saved in this location are removed. Security is not enforced for files in this
|
||
location and other applications may read, change and delete them.</li>
|
||
</ul>
|
||
|
||
<p>The following example code demonstrates how to create a {@link java.io.File} or {@link
|
||
android.net.Uri} location for a media file that can be used when invoking a device's camera with
|
||
an {@link android.content.Intent} or as part of a <a href="#custom-camera">Building a Camera
|
||
App</a>.</p>
|
||
|
||
<pre>
|
||
public static final int MEDIA_TYPE_IMAGE = 1;
|
||
public static final int MEDIA_TYPE_VIDEO = 2;
|
||
|
||
/** Create a file Uri for saving an image or video */
|
||
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
|
||
// using Environment.getExternalStorageState() before doing this.
|
||
|
||
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
|
||
Environment.DIRECTORY_PICTURES), "MyCameraApp");
|
||
// 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("MyCameraApp", "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;
|
||
}
|
||
</pre>
|
||
|
||
<p class="note"><strong>Note:</strong> {@link
|
||
android.os.Environment#getExternalStoragePublicDirectory(java.lang.String)
|
||
Environment.getExternalStoragePublicDirectory()} is available in Android 2.2 (API Level 8) or
|
||
higher. If you are targeting devices with earlier versions of Android, use {@link
|
||
android.os.Environment#getExternalStorageDirectory() Environment.getExternalStorageDirectory()}
|
||
instead. For more information, see <a
|
||
href="{@docRoot}guide/topics/data/data-storage.html#SavingSharedFiles">Saving Shared Files</a>.</p>
|
||
|
||
<p>For more information about saving files on an Android device, see <a
|
||
href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a>.</p>
|
||
|
||
|
||
<h2 id="camera-features">Camera Features</h2>
|
||
<p>Android supports a wide array of camera features you can control with your camera application,
|
||
such as picture format, flash mode, focus settings, and many more. This section lists the common
|
||
camera features, and briefly discusses how to use them. Most camera features can be accessed and set
|
||
using the through {@link android.hardware.Camera.Parameters} object. However, there are several
|
||
important features that require more than simple settings in {@link
|
||
android.hardware.Camera.Parameters}. These features are covered in the following sections:<p>
|
||
|
||
<ul>
|
||
<li><a href="#metering-focus-areas">Metering and focus areas</a></li>
|
||
<li><a href="#face-detection">Face detection</a></li>
|
||
<li><a href="#time-lapse-video">Time lapse video</a></li>
|
||
</ul>
|
||
|
||
<p>For general information about how to use features that are controlled through {@link
|
||
android.hardware.Camera.Parameters}, review the <a href="#using-features">Using camera
|
||
features</a> section. For more detailed information about how to use features controlled through the
|
||
camera parameters object, follow the links in the feature list below to the API reference
|
||
documentation.</p>
|
||
|
||
<p class="table-caption" id="table1">
|
||
<strong>Table 1.</strong> Common camera features sorted by the Android API Level in which they
|
||
were introduced.</p>
|
||
<table>
|
||
<tr>
|
||
<th>Feature</th> <th>API Level</th> <th>Description</th>
|
||
</tr>
|
||
<tr>
|
||
<td><a href="#face-detection">Face Detection</a></td>
|
||
<td>14</td>
|
||
<td>Identify human faces within a picture and use them for focus, metering and white
|
||
balance</td>
|
||
</tr>
|
||
<tr>
|
||
<td><a href="#metering-focus-areas">Metering Areas</a></td>
|
||
<td>14</td>
|
||
<td>Specify one or more areas within an image for calculating white balance</td>
|
||
</tr>
|
||
<tr>
|
||
<td><a href="#metering-focus-areas">Focus Areas</a></td>
|
||
<td>14</td>
|
||
<td>Set one or more areas within an image to use for focus</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#setAutoWhiteBalanceLock White Balance Lock}</td>
|
||
<td>14</td>
|
||
<td>Stop or start automatic white balance adjustments</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#setAutoExposureLock Exposure Lock}</td>
|
||
<td>14</td>
|
||
<td>Stop or start automatic exposure adjustments</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera#takePicture Video Snapshot}</td>
|
||
<td>14</td>
|
||
<td>Take a picture while shooting video (frame grab)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><a href="#time-lapse-video">Time Lapse Video</a></td>
|
||
<td>11</td>
|
||
<td>Record frames with set delays to record a time lapse video</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera#open(int) Multiple Cameras}</td>
|
||
<td>9</td>
|
||
<td>Support for more than one camera on a device, including front-facing and back-facing
|
||
cameras</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#getFocusDistances Focus Distance}</td>
|
||
<td>9</td>
|
||
<td>Reports distances between the camera and objects that appear to be in focus</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#setZoom Zoom}</td>
|
||
<td>8</td>
|
||
<td>Set image magnification</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#setExposureCompensation Exposure
|
||
Compensation}</td>
|
||
<td>8</td>
|
||
<td>Increase or decrease the light exposure level</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#setGpsLatitude GPS Data}</td>
|
||
<td>5</td>
|
||
<td>Include or omit geographic location data with the image</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#setWhiteBalance White Balance}</td>
|
||
<td>5</td>
|
||
<td>Set the white balance mode, which affects color values in the captured image</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#setFocusMode Focus Mode}</td>
|
||
<td>5</td>
|
||
<td>Set how the camera focuses on a subject such as automatic, fixed, macro or infinity</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#setSceneMode Scene Mode}</td>
|
||
<td>5</td>
|
||
<td>Apply a preset mode for specific types of photography situations such as night, beach, snow
|
||
or candlelight scenes</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#setJpegQuality JPEG Quality}</td>
|
||
<td>5</td>
|
||
<td>Set the compression level for a JPEG image, which increases or decreases image output file
|
||
quality and size</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#setFlashMode Flash Mode}</td>
|
||
<td>5</td>
|
||
<td>Turn flash on, off, or use automatic setting</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#setColorEffect Color Effects}</td>
|
||
<td>5</td>
|
||
<td>Apply a color effect to the captured image such as black and white, sepia tone or negative.
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#setAntibanding Anti-Banding}</td>
|
||
<td>5</td>
|
||
<td>Reduces the effect of banding in color gradients due to JPEG compression</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#setPictureFormat Picture Format}</td>
|
||
<td>1</td>
|
||
<td>Specify the file format for the picture</td>
|
||
</tr>
|
||
<tr>
|
||
<td>{@link android.hardware.Camera.Parameters#setPictureSize Picture Size}</td>
|
||
<td>1</td>
|
||
<td>Specify the pixel dimensions of the saved picture</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<p class="note"><strong>Note:</strong> These features are not supported on all devices due to
|
||
hardware differences and software implementation. For information on checking the availability
|
||
of features on the device where your application is running, see <a href="#check-feature">Checking
|
||
feature availability</a>.</p>
|
||
|
||
|
||
<h3 id="check-feature">Checking feature availability</h3>
|
||
<p>The first thing to understand when setting out to use camera features on Android devices is that
|
||
not all camera features are supported on all devices. In addition, devices that support a particular
|
||
feature may support them to different levels or with different options. Therefore, part of your
|
||
decision process as you develop a camera application is to decide what camera features you want to
|
||
support and to what level. After making that decision, you should plan on including code in your
|
||
camera application that checks to see if device hardware supports those features and fails
|
||
gracefully if a feature is not available.</p>
|
||
|
||
<p>You can check the availabilty of camera features by getting an instance of a camera’s parameters
|
||
object, and checking the relevant methods. The following code sample shows you how to obtain a
|
||
{@link android.hardware.Camera.Parameters} object and check if the camera supports the autofocus
|
||
feature:</p>
|
||
|
||
<pre>
|
||
// get Camera parameters
|
||
Camera.Parameters params = mCamera.getParameters();
|
||
|
||
List<String> focusModes = params.getSupportedFocusModes();
|
||
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
|
||
// Autofocus mode is supported
|
||
}
|
||
</pre>
|
||
|
||
<p>You can use the technique shown above for most camera features. The
|
||
{@link android.hardware.Camera.Parameters} object provides a {@code getSupported...()}, {@code
|
||
is...Supported()} or {@code getMax...()} method to determine if (and to what extent) a feature is
|
||
supported.</p>
|
||
|
||
<p>If your application requires certain camera features in order to function properly, you can
|
||
require them through additions to your application manifest. When you declare the use of specific
|
||
camera features, such as flash and auto-focus, Google Play restricts your application from
|
||
being installed on devices which do not support these features. For a list of camera features that
|
||
can be declared in your app manifest, see the manifest
|
||
<a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#hw-features"> Features
|
||
Reference</a>.</p>
|
||
|
||
<h3 id="using-features">Using camera features</h3>
|
||
<p>Most camera features are activated and controlled using a {@link
|
||
android.hardware.Camera.Parameters} object. You obtain this object by first getting an instance of
|
||
the {@link android.hardware.Camera} object, calling the {@link
|
||
android.hardware.Camera#getParameters getParameters()} method, changing the returned parameter
|
||
object and then setting it back into the camera object, as demonstrated in the following example
|
||
code:</p>
|
||
|
||
<pre>
|
||
// get Camera parameters
|
||
Camera.Parameters params = mCamera.getParameters();
|
||
// set the focus mode
|
||
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
|
||
// set Camera parameters
|
||
mCamera.setParameters(params);
|
||
</pre>
|
||
|
||
<p>This technique works for nearly all camera features, and most parameters can be changed at any
|
||
time after you have obtained an instance of the {@link android.hardware.Camera} object. Changes to
|
||
parameters are typically visible to the user immediately in the application’s camera preview.
|
||
On the software side, parameter changes may take several frames to actually take effect as the
|
||
camera hardware processes the new instructions and then sends updated image data.</p>
|
||
|
||
<p class="caution"><strong>Important:</strong> Some camera features cannot be changed at will. In
|
||
particular, changing the size or orientation of the camera preview requires that you first stop the
|
||
preview, change the preview size, and then restart the preview. Starting with Android 4.0 (API
|
||
Level 14) preview orientation can be changed without restarting the preview.</p>
|
||
|
||
<p>Other camera features require more code in order to implement, including:</p>
|
||
<ul>
|
||
<li>Metering and focus areas</li>
|
||
<li>Face detection</li>
|
||
<li>Time lapse video</li>
|
||
</ul>
|
||
<p>A quick outline of how to implement these features is provided in the following sections.</p>
|
||
|
||
|
||
<h3 id="metering-focus-areas">Metering and focus areas</h3>
|
||
<p>In some photographic scenarios, automatic focusing and light metering may not produce the
|
||
desired results. Starting with Android 4.0 (API Level 14), your camera application can provide
|
||
additional controls to allow your app or users to specify areas in an image to use for determining
|
||
focus or light level settings and pass these values to the camera hardware for use in capturing
|
||
images or video.</p>
|
||
|
||
<p>Areas for metering and focus work very similarly to other camera features, in that you control
|
||
them through methods in the {@link android.hardware.Camera.Parameters} object. The following code
|
||
demonstrates setting two light metering areas for an instance of
|
||
{@link android.hardware.Camera}:</p>
|
||
|
||
<pre>
|
||
// Create an instance of Camera
|
||
mCamera = getCameraInstance();
|
||
|
||
// set Camera parameters
|
||
Camera.Parameters params = mCamera.getParameters();
|
||
|
||
if (params.getMaxNumMeteringAreas() > 0){ // check that metering areas are supported
|
||
List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
|
||
|
||
Rect areaRect1 = new Rect(-100, -100, 100, 100); // specify an area in center of image
|
||
meteringAreas.add(new Camera.Area(areaRect1, 600)); // set weight to 60%
|
||
Rect areaRect2 = new Rect(800, -1000, 1000, -800); // specify an area in upper right of image
|
||
meteringAreas.add(new Camera.Area(areaRect2, 400)); // set weight to 40%
|
||
params.setMeteringAreas(meteringAreas);
|
||
}
|
||
|
||
mCamera.setParameters(params);
|
||
</pre>
|
||
|
||
<p>The {@link android.hardware.Camera.Area} object contains two data parameters: A {@link
|
||
android.graphics.Rect} object for specifying an area within the camera’s field of view and a weight
|
||
value, which tells the camera what level of importance this area should be given in light metering
|
||
or focus calculations.</p>
|
||
|
||
<p>The {@link android.graphics.Rect} field in a {@link android.hardware.Camera.Area} object
|
||
describes a rectangular shape mapped on a 2000 x 2000 unit grid. The coordinates -1000, -1000
|
||
represent the top, left corner of the camera image, and coordinates 1000, 1000 represent the
|
||
bottom, right corner of the camera image, as shown in the illustration below.</p>
|
||
|
||
<img src='images/camera-area-coordinates.png' />
|
||
<p class="img-caption">
|
||
<strong>Figure 1.</strong> The red lines illustrate the coordinate system for specifying a
|
||
{@link android.hardware.Camera.Area} within a camera preview. The blue box shows the location and
|
||
shape of an camera area with the {@link android.graphics.Rect} values 333,333,667,667.
|
||
</p>
|
||
|
||
<p>The bounds of this coordinate system always correspond to the outer edge of the image visible in
|
||
the camera preview and do not shrink or expand with the zoom level. Similarly, rotation of the image
|
||
preview using {@link android.hardware.Camera#setDisplayOrientation Camera.setDisplayOrientation()}
|
||
does not remap the coordinate system.</p>
|
||
|
||
|
||
<h3 id="face-detection">Face detection</h3>
|
||
<p>For pictures that include people, faces are usually the most important part of the picture, and
|
||
should be used for determining both focus and white balance when capturing an image. The Android 4.0
|
||
(API Level 14) framework provides APIs for identifying faces and calculating picture settings using
|
||
face recognition technology.</p>
|
||
|
||
<p class="note"><strong>Note:</strong> While the face detection feature is running,
|
||
{@link android.hardware.Camera.Parameters#setWhiteBalance},
|
||
{@link android.hardware.Camera.Parameters#setFocusAreas} and
|
||
{@link android.hardware.Camera.Parameters#setMeteringAreas} have no effect.</p>
|
||
|
||
<p>Using the face detection feature in your camera application requires a few general steps:</p>
|
||
<ul>
|
||
<li>Check that face detection is supported on the device</li>
|
||
<li>Create a face detection listener</li>
|
||
<li>Add the face detection listener to your camera object</li>
|
||
<li>Start face detection after preview (and after <em>every</em> preview restart)</li>
|
||
</ul>
|
||
|
||
<p>The face detection feature is not supported on all devices. You can check that this feature is
|
||
supported by calling {@link android.hardware.Camera.Parameters#getMaxNumDetectedFaces}. An
|
||
example of this check is shown in the {@code startFaceDetection()} sample method below.</p>
|
||
|
||
<p>In order to be notified and respond to the detection of a face, your camera application must set
|
||
a listener for face detection events. In order to do this, you must create a listener class that
|
||
implements the {@link android.hardware.Camera.FaceDetectionListener} interface as shown in the
|
||
example code below.</p>
|
||
|
||
<pre>
|
||
class MyFaceDetectionListener implements Camera.FaceDetectionListener {
|
||
|
||
@Override
|
||
public void onFaceDetection(Face[] faces, Camera camera) {
|
||
if (faces.length > 0){
|
||
Log.d("FaceDetection", "face detected: "+ faces.length +
|
||
" Face 1 Location X: " + faces[0].rect.centerX() +
|
||
"Y: " + faces[0].rect.centerY() );
|
||
}
|
||
}
|
||
}
|
||
</pre>
|
||
|
||
<p>After creating this class, you then set it into your application’s
|
||
{@link android.hardware.Camera} object, as shown in the example code below:</p>
|
||
|
||
<pre>
|
||
mCamera.setFaceDetectionListener(new MyFaceDetectionListener());
|
||
</pre>
|
||
|
||
<p>Your application must start the face detection function each time you start (or restart) the
|
||
camera preview. Create a method for starting face detection so you can call it as needed, as shown
|
||
in the example code below.</p>
|
||
|
||
<pre>
|
||
public void startFaceDetection(){
|
||
// Try starting Face Detection
|
||
Camera.Parameters params = mCamera.getParameters();
|
||
|
||
// start face detection only *after* preview has started
|
||
if (params.getMaxNumDetectedFaces() > 0){
|
||
// camera supports face detection, so can start it:
|
||
mCamera.startFaceDetection();
|
||
}
|
||
}
|
||
</pre>
|
||
|
||
<p>You must start face detection <em>each time</em> you start (or restart) the camera preview. If
|
||
you use the preview class shown in <a href="#camera-preview">Creating a preview class</a>, add your
|
||
{@link android.hardware.Camera#startFaceDetection startFaceDetection()} method to both the
|
||
{@link android.view.SurfaceHolder.Callback#surfaceCreated surfaceCreated()} and {@link
|
||
android.view.SurfaceHolder.Callback#surfaceChanged surfaceChanged()} methods in your preview class,
|
||
as shown in the sample code below.</p>
|
||
|
||
<pre>
|
||
public void surfaceCreated(SurfaceHolder holder) {
|
||
try {
|
||
mCamera.setPreviewDisplay(holder);
|
||
mCamera.startPreview();
|
||
|
||
startFaceDetection(); // start face detection feature
|
||
|
||
} catch (IOException e) {
|
||
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
|
||
}
|
||
}
|
||
|
||
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
||
|
||
if (mHolder.getSurface() == null){
|
||
// preview surface does not exist
|
||
Log.d(TAG, "mHolder.getSurface() == null");
|
||
return;
|
||
}
|
||
|
||
try {
|
||
mCamera.stopPreview();
|
||
|
||
} catch (Exception e){
|
||
// ignore: tried to stop a non-existent preview
|
||
Log.d(TAG, "Error stopping camera preview: " + e.getMessage());
|
||
}
|
||
|
||
try {
|
||
mCamera.setPreviewDisplay(mHolder);
|
||
mCamera.startPreview();
|
||
|
||
startFaceDetection(); // re-start face detection feature
|
||
|
||
} catch (Exception e){
|
||
// ignore: tried to stop a non-existent preview
|
||
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
|
||
}
|
||
}
|
||
</pre>
|
||
|
||
<p class="note"><strong>Note:</strong> Remember to call this method <em>after</em> calling
|
||
{@link android.hardware.Camera#startPreview startPreview()}. Do not attempt to start face detection
|
||
in the {@link android.app.Activity#onCreate onCreate()} method of your camera app’s main activity,
|
||
as the preview is not available by this point in your application's the execution.</p>
|
||
|
||
|
||
<h3 id="time-lapse-video">Time lapse video</h3>
|
||
<p>Time lapse video allows users to create video clips that combine pictures taken a few seconds or
|
||
minutes apart. This feature uses {@link android.media.MediaRecorder} to record the images for a time
|
||
lapse sequence. </p>
|
||
|
||
<p>To record a time lapse video with {@link android.media.MediaRecorder}, you must configure the
|
||
recorder object as if you are recording a normal video, setting the captured frames per second to a
|
||
low number and using one of the time lapse quality settings, as shown in the code example below.</p>
|
||
|
||
<pre>
|
||
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
|
||
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH));
|
||
...
|
||
// Step 5.5: Set the video capture rate to a low number
|
||
mMediaRecorder.setCaptureRate(0.1); // capture a frame every 10 seconds
|
||
</pre>
|
||
|
||
<p>These settings must be done as part of a larger configuration procedure for {@link
|
||
android.media.MediaRecorder}. For a full configuration code example, see <a
|
||
href="#configuring-mediarecorder">Configuring MediaRecorder</a>. Once the configuration is complete,
|
||
you start the video recording as if you were recording a normal video clip. For more information
|
||
about configuring and running {@link android.media.MediaRecorder}, see <a
|
||
href="#capture-video">Capturing videos</a>.</p>
|