• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Camera
2page.tags=photo,video,picture,mediarecorder
3@jd:body
4
5<div id="qv-wrapper">
6  <div id="qv">
7  <h2>In this document</h2>
8  <ol>
9    <li><a href="#considerations">Considerations</a></li>
10    <li><a href="#basics">The Basics</a>
11    <li><a href="#manifest">Manifest Declarations</a></li>
12    <li><a href="#intents">Using Existing Camera Apps</a>
13      <ol>
14        <li><a href="#intent-image">Image capture intent</a></li>
15        <li><a href="#intent-video">Video capture intent</a></li>
16        <li><a href="#intent-receive">Receiving camera intent result</a></li>
17      </ol>
18    <li><a href="#custom-camera">Building a Camera App</a>
19      <ol>
20        <li><a href="#detect-camera">Detecting camera hardware</a></li>
21        <li><a href="#access-camera">Accessing cameras</a></li>
22        <li><a href="#check-camera-features">Checking camera features</a></li>
23        <li><a href="#camera-preview">Creating a preview class</a></li>
24        <li><a href="#preview-layout">Placing preview in a layout</a></li>
25        <li><a href="#capture-picture">Capturing pictures</a></li>
26        <li><a href="#capture-video">Capturing videos</a></li>
27        <li><a href="#release-camera">Releasing the camera</a></li>
28      </ol>
29    </li>
30    <li><a href="#saving-media">Saving Media Files</a></li>
31    <li><a href="#camera-features">Camera Features</a>
32      <ol>
33        <li><a href="#check-feature">Checking feature availability</a></li>
34        <li><a href="#using-features">Using camera features</a></li>
35        <li><a href="#metering-focus-areas">Metering and focus areas</a></li>
36        <li><a href="#face-detection">Face detection</a></li>
37        <li><a href="#time-lapse-video">Time lapse video</a></li>
38      </ol>
39    </li>
40  </ol>
41  <h2>Key Classes</h2>
42  <ol>
43    <li>{@link android.hardware.Camera}</li>
44    <li>{@link android.view.SurfaceView}</li>
45    <li>{@link android.media.MediaRecorder}</li>
46    <li>{@link android.content.Intent}</li>
47  </ol>
48  <h2>See also</h2>
49  <ol>
50    <li><a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a></li>
51    <li><a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a></li>
52  </ol>
53  </div>
54</div>
55
56
57<p>The Android framework includes support for various cameras and camera features available on
58devices, allowing you to capture pictures and videos in your applications. This document discusses a
59quick, simple approach to image and video capture and outlines an advanced approach for creating
60custom camera experiences for your users.</p>
61
62<h2 id="considerations">Considerations</h2>
63<p>Before enabling your application to use cameras on Android devices, you should consider a few
64questions about how your app intends to use this hardware feature.</p>
65
66<ul>
67  <li><strong>Camera Requirement</strong> - Is the use of a camera so important to your
68application that you do not want your application installed on a device that does not have a
69camera? If so, you should declare the <a href="#manifest">camera requirement in your
70manifest</a>.</li>
71
72  <li><strong>Quick Picture or Customized Camera</strong> - How will your application use the
73camera? Are you just interested in snapping a quick picture or video clip, or will your application
74provide a new way to use cameras? For a getting a quick snap or clip, consider
75<a href="#intents">Using Existing Camera Apps</a>. For developing a customized camera feature, check
76out the <a href="#custom-camera">Building a Camera App</a> section.</li>
77
78  <li><strong>Storage</strong> - Are the images or videos your application generates intended to be
79only visible to your application or shared so that other applications such as Gallery or other
80media and social apps can use them? Do you want the pictures and videos to be available even if your
81application is uninstalled? Check out the <a href="#saving-media">Saving Media Files</a> section to
82see how to implement these options.</li>
83</ul>
84
85
86
87<h2 id="basics">The Basics</h2>
88<p>The Android framework supports capturing images and video through the
89{@link android.hardware.camera2} API or camera {@link android.content.Intent}. Here are the relevant
90classes:</p>
91
92<dl>
93  <dt>{@link android.hardware.camera2}</dt>
94  <dd>This package is the primary API for controlling device cameras. It can be used to take
95pictures or videos when you are building a camera application.</dd>
96
97  <dt>{@link android.hardware.Camera}</dt>
98  <dd>This class is the older deprecated API for controlling device cameras.</dd>
99
100  <dt>{@link android.view.SurfaceView}</dt>
101  <dd>This class is used to present a live camera preview to the user.</dd>
102
103  <dt>{@link android.media.MediaRecorder}</dt>
104  <dd>This class is used to record video from the camera.</dd>
105
106  <dt>{@link android.content.Intent}</dt>
107  <dd>An intent action type of {@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE
108MediaStore.ACTION_IMAGE_CAPTURE} or {@link android.provider.MediaStore#ACTION_VIDEO_CAPTURE
109MediaStore.ACTION_VIDEO_CAPTURE} can be used to capture images or videos without directly
110using the {@link android.hardware.Camera} object.</dd>
111</dl>
112
113
114<h2 id="manifest">Manifest Declarations</h2>
115<p>Before starting development on your application with the Camera API, you should make sure
116your manifest has the appropriate declarations to allow use of camera hardware and other
117related features.</p>
118
119<ul>
120  <li><strong>Camera Permission</strong> - Your application must request permission to use a device
121camera.
122<pre>
123&lt;uses-permission android:name=&quot;android.permission.CAMERA&quot; /&gt;
124</pre>
125  <p class="note"><strong>Note:</strong> If you are using the camera <a href="#intents">via an
126intent</a>, your application does not need to request this permission.</p>
127  </li>
128  <li><strong>Camera Features</strong> - Your application must also declare use of camera features,
129for example:
130<pre>
131&lt;uses-feature android:name=&quot;android.hardware.camera&quot; /&gt;
132</pre>
133  <p>For a list of camera features, see the manifest
134<a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#hw-features">Features
135Reference</a>.</p>
136  <p>Adding camera features to your manifest causes Google Play to prevent your application from
137being installed to devices that do not include a camera or do not support the camera features you
138specify. For more information about using feature-based filtering with Google Play, see <a
139href="{@docRoot}guide/topics/manifest/uses-feature-element.html#market-feature-filtering">Google
140Play and Feature-Based Filtering</a>.</p>
141  <p>If your application <em>can use</em> a camera or camera feature for proper operation, but does
142not <em>require</em> it, you should specify this in the manifest by including the {@code
143android:required} attribute, and setting it to {@code false}:</p>
144<pre>
145&lt;uses-feature android:name="android.hardware.camera" android:required="false" /&gt;
146</pre>
147
148  </li>
149  <li><strong>Storage Permission</strong> - If your application saves images or videos to the
150device's external storage (SD Card), you must also specify this in the manifest.
151<pre>
152&lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot; /&gt;
153</pre>
154  </li>
155  <li><strong>Audio Recording Permission</strong> - For recording audio with video capture, your
156application must request the audio capture permission.
157<pre>
158&lt;uses-permission android:name="android.permission.RECORD_AUDIO" /&gt;
159</pre>
160  </li>
161  <li><strong>Location Permission</strong> - If your application tags images with GPS location
162information, you must request location permission:
163<pre>
164&lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /&gt;
165</pre>
166<p>For more information about getting user location, see
167<a href="{@docRoot}guide/topics/location/strategies.html">Location Strategies</a>.</p>
168  </li>
169</ul>
170
171
172<h2 id="intents">Using Existing Camera Apps</h2>
173<p>A quick way to enable taking pictures or videos in your application without a lot of extra code
174is to use an {@link android.content.Intent} to invoke an existing Android camera application. A
175camera intent makes a request to capture a picture or video clip through an existing camera app and
176then returns control back to your application. This section shows you how to capture an image or
177video using this technique.</p>
178
179<p>The procedure for invoking a camera intent follows these general steps:</p>
180
181<ol>
182  <li><strong>Compose a Camera Intent</strong> - Create an {@link android.content.Intent} that
183requests an image or video, using one of these intent types:
184    <ul>
185      <li>{@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE MediaStore.ACTION_IMAGE_CAPTURE} -
186Intent action type for requesting an image from an existing camera application.</li>
187      <li>{@link android.provider.MediaStore#ACTION_VIDEO_CAPTURE MediaStore.ACTION_VIDEO_CAPTURE} -
188Intent action type for requesting a video from an existing camera application. </li>
189    </ul>
190  </li>
191  <li><strong>Start the Camera Intent</strong> - Use the {@link
192android.app.Activity#startActivityForResult(android.content.Intent, int) startActivityForResult()}
193method to execute the camera intent. After you start the intent, the Camera application user
194interface appears on the device screen and the user can take a picture or video.</li>
195  <li><strong>Receive the Intent Result</strong> - Set up an {@link
196android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()} method
197in your application to receive the callback and data from the camera intent. When the user
198finishes taking a picture or video (or cancels the operation), the system calls this method.</li>
199</ol>
200
201
202<h3 id="intent-image">Image capture intent</h3>
203<p>Capturing images using a camera intent is quick way to enable your application to take pictures
204with minimal coding. An image capture intent can include the following extra information:</p>
205
206<ul>
207  <li>{@link android.provider.MediaStore#EXTRA_OUTPUT MediaStore.EXTRA_OUTPUT} - This setting
208requires a {@link android.net.Uri} object specifying a path and file name where you'd like to
209save the picture. This setting is optional but strongly recommended. If you do not specify this
210value, the camera application saves the requested picture in the default location with a default
211name, specified in the returned intent's {@link android.content.Intent#getData() Intent.getData()}
212field.</li>
213</ul>
214
215<p>The following example demonstrates how to construct a image capture intent and execute it.
216The {@code getOutputMediaFileUri()} method in this example refers to the sample code shown in <a
217href= "#saving-media">Saving Media Files</a>.</p>
218
219<pre>
220private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
221private Uri fileUri;
222
223&#64;Override
224public void onCreate(Bundle savedInstanceState) {
225    super.onCreate(savedInstanceState);
226    setContentView(R.layout.main);
227
228    // create Intent to take a picture and return control to the calling application
229    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
230
231    fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
232    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
233
234    // start the image capture Intent
235    startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
236}
237</pre>
238
239<p>When the {@link android.app.Activity#startActivityForResult(android.content.Intent, int)
240startActivityForResult()} method is executed, users see a camera application interface.
241After the user finishes taking a picture (or cancels the operation), the user interface returns to
242your application, and you must intercept the {@link
243android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()}
244method to receive the result of the intent and continue your application execution. For information
245on how to receive the completed intent, see <a href="#intent-receive">Receiving camera intent
246result</a>.</p>
247
248
249<h3 id="intent-video">Video capture intent</h3>
250<p>Capturing video using a camera intent is a quick way to enable your application to take videos
251with minimal coding. A video capture intent can include the following extra information:</p>
252
253<ul>
254  <li>{@link android.provider.MediaStore#EXTRA_OUTPUT MediaStore.EXTRA_OUTPUT} - This setting
255requires a {@link android.net.Uri} specifying a path and file name where you'd like to save the
256video. This setting is optional but strongly recommended. If you do not specify this value, the
257Camera application saves the requested video in the default location with a default name, specified
258in the returned intent's {@link android.content.Intent#getData() Intent.getData()} field.</li>
259  <li>{@link android.provider.MediaStore#EXTRA_VIDEO_QUALITY MediaStore.EXTRA_VIDEO_QUALITY} -
260This value can be 0 for lowest quality and smallest file size or 1 for highest quality and
261larger file size.</li>
262  <li>{@link android.provider.MediaStore#EXTRA_DURATION_LIMIT MediaStore.EXTRA_DURATION_LIMIT} -
263Set this value to limit the length, in seconds, of the video being captured.</li>
264  <li>{@link android.provider.MediaStore#EXTRA_SIZE_LIMIT MediaStore.EXTRA_SIZE_LIMIT} -
265Set this value to limit the file size, in bytes, of the video being captured.
266</li>
267</ul>
268
269<p>The following example demonstrates how to construct a video capture intent and execute it.
270The {@code getOutputMediaFileUri()} method in this example refers to the sample code shown in <a
271href= "#saving-media">Saving Media Files</a>.</p>
272
273<pre>
274private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
275private Uri fileUri;
276
277&#64;Override
278public void onCreate(Bundle savedInstanceState) {
279    super.onCreate(savedInstanceState);
280    setContentView(R.layout.main);
281
282    //create new Intent
283    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
284
285    fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);  // create a file to save the video
286    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);  // set the image file name
287
288    intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high
289
290    // start the Video Capture Intent
291    startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
292}
293</pre>
294
295<p>When the {@link
296android.app.Activity#startActivityForResult(android.content.Intent, int)
297startActivityForResult()} method is executed, users see a modified camera application interface.
298After the user finishes taking a video (or cancels the operation), the user interface
299returns to your application, and you must intercept the {@link
300android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()}
301method to receive the result of the intent and continue your application execution. For information
302on how to receive the completed intent, see the next section.</p>
303
304<h3 id="intent-receive">Receiving camera intent result</h3>
305<p>Once you have constructed and executed an image or video camera intent, your application must be
306configured to receive the result of the intent. This section shows you how to intercept the callback
307from a camera intent so your application can do further processing of the captured image or
308video.</p>
309
310<p>In order to receive the result of an intent, you must override the {@link
311android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()} in the
312activity that started the intent. The following example demonstrates how to override {@link
313android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()} to
314capture the result of the <a href="#intent-image">image camera intent</a> or <a
315href="#intent-video">video camera intent</a> examples shown in the previous sections.</p>
316
317<pre>
318private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
319private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
320
321&#64;Override
322protected void onActivityResult(int requestCode, int resultCode, Intent data) {
323    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
324        if (resultCode == RESULT_OK) {
325            // Image captured and saved to fileUri specified in the Intent
326            Toast.makeText(this, "Image saved to:\n" +
327                     data.getData(), Toast.LENGTH_LONG).show();
328        } else if (resultCode == RESULT_CANCELED) {
329            // User cancelled the image capture
330        } else {
331            // Image capture failed, advise user
332        }
333    }
334
335    if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
336        if (resultCode == RESULT_OK) {
337            // Video captured and saved to fileUri specified in the Intent
338            Toast.makeText(this, "Video saved to:\n" +
339                     data.getData(), Toast.LENGTH_LONG).show();
340        } else if (resultCode == RESULT_CANCELED) {
341            // User cancelled the video capture
342        } else {
343            // Video capture failed, advise user
344        }
345    }
346}
347</pre>
348
349<p>Once your activity receives a successful result, the captured image or video is available in the
350specified location for your application to access.</p>
351
352
353
354<h2 id="custom-camera">Building a Camera App</h2>
355<p>Some developers may require a camera user interface that is customized to the look of their
356application or provides special features. Creating a customized camera activity requires more
357code than <a href="#intents">using an intent</a>, but it can provide a more compelling experience
358for your users.</p>
359
360<p><strong> Note: The following guide is for the older, deprecated {@link android.hardware.Camera}
361API. For new or advanced camera applications, the newer {@link android.hardware.camera2} API is
362recommended.</strong></p>
363
364<p>The general steps for creating a custom camera interface for your application are as follows:</p>
365
366<ul>
367   <li><strong>Detect and Access Camera</strong> - Create code to check for the existence of
368cameras and request access.</li>
369   <li><strong>Create a Preview Class</strong> - Create a camera preview class that extends {@link
370android.view.SurfaceView} and implements the {@link android.view.SurfaceHolder} interface. This
371class previews the live images from the camera.</li>
372   <li><strong>Build a Preview Layout</strong> - Once you have the camera preview class, create a
373view layout that incorporates the preview and the user interface controls you want.</li>
374   <li><strong>Setup Listeners for Capture</strong> - Connect listeners for your interface
375controls to start image or video capture in response to user actions, such as pressing a
376button.</li>
377   <li><strong>Capture and Save Files</strong> - Setup the code for capturing pictures or
378videos and saving the output.</li>
379   <li><strong>Release the Camera</strong> - After using the camera, your application must
380properly release it for use by other applications.</li>
381</ul>
382
383<p>Camera hardware is a shared resource that must be carefully managed so your application does
384not collide with other applications that may also want to use it. The following sections discusses
385how to detect camera hardware, how to request access to a camera, how to capture pictures or video
386and how to release the camera when your application is done using it.</p>
387
388<p class="caution"><strong>Caution:</strong> Remember to release the {@link android.hardware.Camera}
389object by calling the {@link android.hardware.Camera#release() Camera.release()} when your
390application is done using it! If your application does not properly release the camera, all
391subsequent attempts to access the camera, including those by your own application, will fail and may
392cause your or other applications to be shut down.</p>
393
394
395<h3 id="detect-camera">Detecting camera hardware</h3>
396<p>If your application does not specifically require a camera using a manifest declaration, you
397should check to see if a camera is available at runtime. To perform this check, use the {@link
398android.content.pm.PackageManager#hasSystemFeature(java.lang.String)
399PackageManager.hasSystemFeature()} method, as shown in the example code below:</p>
400
401<pre>
402/** Check if this device has a camera */
403private boolean checkCameraHardware(Context context) {
404    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
405        // this device has a camera
406        return true;
407    } else {
408        // no camera on this device
409        return false;
410    }
411}
412</pre>
413
414<p>Android devices can have multiple cameras, for example a back-facing camera for photography and a
415front-facing camera for video calls. Android 2.3 (API Level 9) and later allows you to check the
416number of cameras available on a device using the {@link
417android.hardware.Camera#getNumberOfCameras() Camera.getNumberOfCameras()} method.</p>
418
419<h3 id="access-camera">Accessing cameras</h3>
420<p>If you have determined that the device on which your application is running has a camera, you
421must request to access it by getting an instance of {@link android.hardware.Camera} (unless you
422are using an <a href="#intents">intent to access the camera</a>). </p>
423
424<p>To access the primary camera, use the {@link android.hardware.Camera#open() Camera.open()} method
425and be sure to catch any exceptions, as shown in the code below:</p>
426
427<pre>
428/** A safe way to get an instance of the Camera object. */
429public static Camera getCameraInstance(){
430    Camera c = null;
431    try {
432        c = Camera.open(); // attempt to get a Camera instance
433    }
434    catch (Exception e){
435        // Camera is not available (in use or does not exist)
436    }
437    return c; // returns null if camera is unavailable
438}
439</pre>
440
441<p class="caution"><strong>Caution:</strong> Always check for exceptions when using {@link
442android.hardware.Camera#open() Camera.open()}. Failing to check for exceptions if the camera is in
443use or does not exist will cause your application to be shut down by the system.</p>
444
445<p>On devices running Android 2.3 (API Level 9) or higher, you can access specific cameras using
446{@link android.hardware.Camera#open(int) Camera.open(int)}. The example code above will access
447the first, back-facing camera on a device with more than one camera.</p>
448
449<h3 id="check-camera-features">Checking camera features</h3>
450<p>Once you obtain access to a camera, you can get further information about its capabilities using
451the {@link android.hardware.Camera#getParameters() Camera.getParameters()} method and checking the
452returned {@link android.hardware.Camera.Parameters} object for supported capabilities. When using
453API Level 9 or higher, use the {@link android.hardware.Camera#getCameraInfo(int,
454android.hardware.Camera.CameraInfo) Camera.getCameraInfo()} to determine if a camera is on the front
455or back of the device, and the orientation of the image.</p>
456
457
458
459<h3 id="camera-preview">Creating a preview class</h3>
460<p>For users to effectively take pictures or video, they must be able to see what the device camera
461sees. A camera preview class is a {@link android.view.SurfaceView} that can display the live image
462data coming from a camera, so users can frame and capture a picture or video.</p>
463
464<p>The following example code demonstrates how to create a basic camera preview class that can be
465included in a {@link android.view.View} layout. This class implements {@link
466android.view.SurfaceHolder.Callback SurfaceHolder.Callback} in order to capture the callback events
467for creating and destroying the view, which are needed for assigning the camera preview input.</p>
468
469<pre>
470/** A basic Camera preview class */
471public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
472    private SurfaceHolder mHolder;
473    private Camera mCamera;
474
475    public CameraPreview(Context context, Camera camera) {
476        super(context);
477        mCamera = camera;
478
479        // Install a SurfaceHolder.Callback so we get notified when the
480        // underlying surface is created and destroyed.
481        mHolder = getHolder();
482        mHolder.addCallback(this);
483        // deprecated setting, but required on Android versions prior to 3.0
484        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
485    }
486
487    public void surfaceCreated(SurfaceHolder holder) {
488        // The Surface has been created, now tell the camera where to draw the preview.
489        try {
490            mCamera.setPreviewDisplay(holder);
491            mCamera.startPreview();
492        } catch (IOException e) {
493            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
494        }
495    }
496
497    public void surfaceDestroyed(SurfaceHolder holder) {
498        // empty. Take care of releasing the Camera preview in your activity.
499    }
500
501    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
502        // If your preview can change or rotate, take care of those events here.
503        // Make sure to stop the preview before resizing or reformatting it.
504
505        if (mHolder.getSurface() == null){
506          // preview surface does not exist
507          return;
508        }
509
510        // stop preview before making changes
511        try {
512            mCamera.stopPreview();
513        } catch (Exception e){
514          // ignore: tried to stop a non-existent preview
515        }
516
517        // set preview size and make any resize, rotate or
518        // reformatting changes here
519
520        // start preview with new settings
521        try {
522            mCamera.setPreviewDisplay(mHolder);
523            mCamera.startPreview();
524
525        } catch (Exception e){
526            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
527        }
528    }
529}
530</pre>
531
532<p>If you want to set a specific size for your camera preview, set this in the {@code
533surfaceChanged()} method as noted in the comments above. When setting preview size, you
534<em>must use</em> values from {@link android.hardware.Camera.Parameters#getSupportedPreviewSizes}.
535<em>Do not</em> set arbitrary values in the {@link
536android.hardware.Camera.Parameters#setPreviewSize setPreviewSize()} method.</p>
537
538
539<h3 id="preview-layout">Placing preview in a layout</h3>
540<p>A camera preview class, such as the example shown in the previous section, must be placed in the
541layout of an activity along with other user interface controls for taking a picture or video. This
542section shows you how to build a basic layout and activity for the preview.</p>
543
544<p>The following layout code provides a very basic view that can be used to display a camera
545preview. In this example, the {@link android.widget.FrameLayout} element is meant to be the
546container for the camera preview class. This layout type is used so that additional picture
547information or controls can be overlayed on the live camera preview images.</p>
548
549<pre>
550&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
551&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
552    android:orientation=&quot;horizontal&quot;
553    android:layout_width=&quot;fill_parent&quot;
554    android:layout_height=&quot;fill_parent&quot;
555    &gt;
556  &lt;FrameLayout
557    android:id=&quot;@+id/camera_preview&quot;
558    android:layout_width=&quot;fill_parent&quot;
559    android:layout_height=&quot;fill_parent&quot;
560    android:layout_weight=&quot;1&quot;
561    /&gt;
562
563  &lt;Button
564    android:id=&quot;@+id/button_capture&quot;
565    android:text=&quot;Capture&quot;
566    android:layout_width=&quot;wrap_content&quot;
567    android:layout_height=&quot;wrap_content&quot;
568    android:layout_gravity=&quot;center&quot;
569    /&gt;
570&lt;/LinearLayout&gt;
571</pre>
572
573<p>On most devices, the default orientation of the camera preview is landscape. This example layout
574specifies a horizontal (landscape) layout and the code below fixes the orientation of the
575application to landscape. For simplicity in rendering a camera preview, you should change your
576application's preview activity orientation to landscape by adding the following to your
577manifest.</p>
578
579<pre>
580&lt;activity android:name=&quot;.CameraActivity&quot;
581          android:label=&quot;@string/app_name&quot;
582
583          android:screenOrientation=&quot;landscape&quot;&gt;
584          &lt;!-- configure this activity to use landscape orientation --&gt;
585
586          &lt;intent-filter&gt;
587        &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
588        &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
589    &lt;/intent-filter&gt;
590&lt;/activity&gt;
591</pre>
592
593<p class="note"><strong>Note:</strong> A camera preview does not have to be in landscape mode.
594Starting in Android 2.2 (API Level 8), you can use the {@link
595android.hardware.Camera#setDisplayOrientation(int) setDisplayOrientation()} method to set the
596rotation of the preview image. In order to change preview orientation as the user re-orients the
597phone, within the {@link
598android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder, int, int, int)
599surfaceChanged()} method of your preview class, first stop the preview with {@link
600android.hardware.Camera#stopPreview() Camera.stopPreview()} change the orientation and then
601start the preview again with {@link android.hardware.Camera#startPreview()
602Camera.startPreview()}.</p>
603
604<p>In the activity for your camera view, add your preview class to the {@link
605android.widget.FrameLayout} element shown in the example above. Your camera activity must also
606ensure that it releases the camera when it is paused or shut down. The following example shows how
607to modify a camera activity to attach the preview class shown in <a href="#camera-preview">Creating
608a preview class</a>.</p>
609
610<pre>
611public class CameraActivity extends Activity {
612
613    private Camera mCamera;
614    private CameraPreview mPreview;
615
616    &#64;Override
617    public void onCreate(Bundle savedInstanceState) {
618        super.onCreate(savedInstanceState);
619        setContentView(R.layout.main);
620
621        // Create an instance of Camera
622        mCamera = getCameraInstance();
623
624        // Create our Preview view and set it as the content of our activity.
625        mPreview = new CameraPreview(this, mCamera);
626        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
627        preview.addView(mPreview);
628    }
629}
630</pre>
631
632<p class="note"><strong>Note:</strong> The {@code getCameraInstance()} method in the example above
633refers to the example method shown in <a href="#access-camera">Accessing cameras</a>.</p>
634
635
636<h3 id="capture-picture">Capturing pictures</h3>
637<p>Once you have built a preview class and a view layout in which to display it, you are ready to
638start capturing images with your application. In your application code, you must set up listeners
639for your user interface controls to respond to a user action by taking a picture.</p>
640
641<p>In order to retrieve a picture, use the {@link
642android.hardware.Camera#takePicture(android.hardware.Camera.ShutterCallback,
643android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback)
644Camera.takePicture()} method. This method takes three parameters which receive data from the camera.
645In order to receive data in a JPEG format, you must implement an {@link
646android.hardware.Camera.PictureCallback} interface to receive the image data and
647write it to a file. The following code shows a basic implementation of the {@link
648android.hardware.Camera.PictureCallback} interface to save an image received from the camera.</p>
649
650<pre>
651private PictureCallback mPicture = new PictureCallback() {
652
653    &#64;Override
654    public void onPictureTaken(byte[] data, Camera camera) {
655
656        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
657        if (pictureFile == null){
658            Log.d(TAG, "Error creating media file, check storage permissions: " +
659                e.getMessage());
660            return;
661        }
662
663        try {
664            FileOutputStream fos = new FileOutputStream(pictureFile);
665            fos.write(data);
666            fos.close();
667        } catch (FileNotFoundException e) {
668            Log.d(TAG, "File not found: " + e.getMessage());
669        } catch (IOException e) {
670            Log.d(TAG, "Error accessing file: " + e.getMessage());
671        }
672    }
673};
674</pre>
675
676<p>Trigger capturing an image by calling the {@link
677android.hardware.Camera#takePicture(android.hardware.Camera.ShutterCallback,
678android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback)
679Camera.takePicture()} method. The following example code shows how to call this method from a
680button {@link android.view.View.OnClickListener}.</p>
681
682<pre>
683// Add a listener to the Capture button
684Button captureButton = (Button) findViewById(id.button_capture);
685captureButton.setOnClickListener(
686    new View.OnClickListener() {
687        &#64;Override
688        public void onClick(View v) {
689            // get an image from the camera
690            mCamera.takePicture(null, null, mPicture);
691        }
692    }
693);
694</pre>
695
696<p class="note"><strong>Note:</strong> The {@code mPicture} member in the following example refers
697to the example code above.</p>
698
699<p class="caution"><strong>Caution:</strong> Remember to release the {@link android.hardware.Camera}
700object by calling the {@link android.hardware.Camera#release() Camera.release()} when your
701application is done using it! For information about how to release the camera, see <a
702href="#release-camera">Releasing the camera</a>.</p>
703
704
705<h3 id="capture-video">Capturing videos</h3>
706
707<p>Video capture using the Android framework requires careful management of the {@link
708android.hardware.Camera} object and coordination with the {@link android.media.MediaRecorder}
709class. When recording video with {@link android.hardware.Camera}, you must manage the {@link
710android.hardware.Camera#lock() Camera.lock()} and {@link android.hardware.Camera#unlock()
711Camera.unlock()} calls to allow {@link android.media.MediaRecorder} access to the camera hardware,
712in addition to the {@link android.hardware.Camera#open() Camera.open()} and {@link
713android.hardware.Camera#release() Camera.release()} calls.</p>
714
715<p class="note"><strong>Note:</strong> Starting with Android 4.0 (API level 14), the {@link
716android.hardware.Camera#lock() Camera.lock()} and {@link android.hardware.Camera#unlock()
717Camera.unlock()} calls are managed for you automatically.</p>
718
719<p>Unlike taking pictures with a device camera, capturing video requires a very particular call
720order. You must follow a specific order of execution to successfully prepare for and capture video
721with your application, as detailed below.</p>
722
723<ol>
724  <li><strong>Open Camera</strong> - Use the {@link android.hardware.Camera#open() Camera.open()}
725to get an instance of the camera object.</li>
726  <li><strong>Connect Preview</strong> - Prepare a live camera image preview by connecting a {@link
727android.view.SurfaceView} to the camera using {@link
728android.hardware.Camera#setPreviewDisplay(android.view.SurfaceHolder) Camera.setPreviewDisplay()}.
729  </li>
730  <li><strong>Start Preview</strong> - Call {@link android.hardware.Camera#startPreview()
731Camera.startPreview()} to begin displaying the live camera images.</li>
732  <li><strong>Start Recording Video</strong> - The following steps must be completed <em>in
733order</em> to successfully record video:
734    <ol style="list-style-type: lower-alpha;">
735      <li><strong>Unlock the Camera</strong> - Unlock the camera for use by {@link
736android.media.MediaRecorder} by calling {@link android.hardware.Camera#unlock()
737Camera.unlock()}.</li>
738      <li><strong>Configure MediaRecorder</strong> - Call in the following {@link
739android.media.MediaRecorder} methods <em>in this order</em>. For more information, see the {@link
740android.media.MediaRecorder} reference documentation.
741        <ol>
742          <li>{@link android.media.MediaRecorder#setCamera(android.hardware.Camera)
743setCamera()} - Set the camera to be used for video capture, use your application's current instance
744of {@link android.hardware.Camera}.</li>
745          <li>{@link android.media.MediaRecorder#setAudioSource(int) setAudioSource()} - Set the
746audio source, use {@link android.media.MediaRecorder.AudioSource#CAMCORDER
747MediaRecorder.AudioSource.CAMCORDER}. </li>
748          <li>{@link android.media.MediaRecorder#setVideoSource(int) setVideoSource()} - Set
749the video source, use {@link android.media.MediaRecorder.VideoSource#CAMERA
750MediaRecorder.VideoSource.CAMERA}.</li>
751          <li>Set the video output format and encoding. For Android 2.2 (API Level 8) and
752higher, use the {@link android.media.MediaRecorder#setProfile(android.media.CamcorderProfile)
753MediaRecorder.setProfile} method, and get a profile instance using {@link
754android.media.CamcorderProfile#get(int) CamcorderProfile.get()}. For versions of Android prior to
7552.2, you must set the video output format and encoding parameters:
756          <ol style="list-style-type: lower-roman;">
757            <li>{@link android.media.MediaRecorder#setOutputFormat(int) setOutputFormat()} - Set
758the output format, specify the default setting or {@link
759android.media.MediaRecorder.OutputFormat#MPEG_4 MediaRecorder.OutputFormat.MPEG_4}.</li>
760            <li>{@link android.media.MediaRecorder#setAudioEncoder(int) setAudioEncoder()} - Set
761the sound encoding type, specify the default setting or {@link
762android.media.MediaRecorder.AudioEncoder#AMR_NB MediaRecorder.AudioEncoder.AMR_NB}.</li>
763            <li>{@link android.media.MediaRecorder#setVideoEncoder(int) setVideoEncoder()} - Set
764the video encoding type, specify the default setting or {@link
765android.media.MediaRecorder.VideoEncoder#MPEG_4_SP MediaRecorder.VideoEncoder.MPEG_4_SP}.</li>
766          </ol>
767          </li>
768          <li>{@link android.media.MediaRecorder#setOutputFile(java.lang.String) setOutputFile()} -
769Set the output file, use {@code getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()} from the example
770method in the <a href="#saving-media">Saving Media Files</a> section.</li>
771          <li>{@link android.media.MediaRecorder#setPreviewDisplay(android.view.Surface)
772setPreviewDisplay()} - Specify the {@link android.view.SurfaceView} preview layout element for
773your application. Use the same object you specified for <strong>Connect Preview</strong>.</li>
774        </ol>
775        <p class="caution"><strong>Caution:</strong> You must call these {@link
776android.media.MediaRecorder} configuration methods <em>in this order</em>, otherwise your
777application will encounter errors and the recording will fail.</p>
778      </li>
779      <li><strong>Prepare MediaRecorder</strong> - Prepare the {@link android.media.MediaRecorder}
780with provided configuration settings by calling {@link android.media.MediaRecorder#prepare()
781MediaRecorder.prepare()}.</li>
782      <li><strong>Start MediaRecorder</strong> - Start recording video by calling {@link
783android.media.MediaRecorder#start() MediaRecorder.start()}.</li>
784    </ol>
785  </li>
786  <li><strong>Stop Recording Video</strong> - Call the following methods <em>in order</em>, to
787successfully complete a video recording:
788    <ol style="list-style-type: lower-alpha;">
789      <li><strong>Stop MediaRecorder</strong> - Stop recording video by calling {@link
790android.media.MediaRecorder#stop() MediaRecorder.stop()}.</li>
791      <li><strong>Reset MediaRecorder</strong> - Optionally, remove the configuration settings from
792the recorder by calling {@link android.media.MediaRecorder#reset() MediaRecorder.reset()}.</li>
793      <li><strong>Release MediaRecorder</strong> - Release the {@link android.media.MediaRecorder}
794by calling {@link android.media.MediaRecorder#release() MediaRecorder.release()}.</li>
795      <li><strong>Lock the Camera</strong> - Lock the camera so that future {@link
796android.media.MediaRecorder} sessions can use it by calling {@link android.hardware.Camera#lock()
797Camera.lock()}. Starting with Android 4.0 (API level 14), this call is not required unless the
798{@link android.media.MediaRecorder#prepare() MediaRecorder.prepare()} call fails.</li>
799    </ol>
800  </li>
801  <li><strong>Stop the Preview</strong> - When your activity has finished using the camera, stop the
802preview using {@link android.hardware.Camera#stopPreview() Camera.stopPreview()}.</li>
803  <li><strong>Release Camera</strong> - Release the camera so that other applications can use
804it by calling {@link android.hardware.Camera#release() Camera.release()}.</li>
805</ol>
806
807<p class="note"><strong>Note:</strong> It is possible to use {@link android.media.MediaRecorder}
808without creating a camera preview first and skip the first few steps of this process. However,
809since users typically prefer to see a preview before starting a recording, that process is not
810discussed here.</p>
811
812<p class="note"><strong>Tip:</strong> If your application is typically used for recording video, set
813{@link android.hardware.Camera.Parameters#setRecordingHint} to {@code true} prior to starting your
814preview. This setting can help reduce the time it takes to start recording.</p>
815
816<h4 id="configuring-mediarecorder">Configuring MediaRecorder</h4>
817<p>When using the {@link android.media.MediaRecorder} class to record video, you must perform
818configuration steps in a <em>specific order</em> and then call the {@link
819android.media.MediaRecorder#prepare() MediaRecorder.prepare()} method to check and implement the
820configuration. The following example code demonstrates how to properly configure and prepare the
821{@link android.media.MediaRecorder} class for video recording.</p>
822
823<pre>
824private boolean prepareVideoRecorder(){
825
826    mCamera = getCameraInstance();
827    mMediaRecorder = new MediaRecorder();
828
829    // Step 1: Unlock and set camera to MediaRecorder
830    mCamera.unlock();
831    mMediaRecorder.setCamera(mCamera);
832
833    // Step 2: Set sources
834    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
835    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
836
837    // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
838    mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
839
840    // Step 4: Set output file
841    mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
842
843    // Step 5: Set the preview output
844    mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
845
846    // Step 6: Prepare configured MediaRecorder
847    try {
848        mMediaRecorder.prepare();
849    } catch (IllegalStateException e) {
850        Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
851        releaseMediaRecorder();
852        return false;
853    } catch (IOException e) {
854        Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
855        releaseMediaRecorder();
856        return false;
857    }
858    return true;
859}
860</pre>
861
862<p>Prior to Android 2.2 (API Level 8), you must set the output format and encoding formats
863parameters directly, instead of using {@link android.media.CamcorderProfile}. This approach is
864demonstrated in the following code:</p>
865
866<pre>
867    // Step 3: Set output format and encoding (for versions prior to API Level 8)
868    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
869    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
870    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
871</pre>
872
873<p>The following video recording parameters for {@link android.media.MediaRecorder} are given
874default settings, however, you may want to adjust these settings for your application:</p>
875
876<ul>
877  <li>{@link android.media.MediaRecorder#setVideoEncodingBitRate(int)
878setVideoEncodingBitRate()}</li>
879  <li>{@link android.media.MediaRecorder#setVideoSize(int, int) setVideoSize()}</li>
880  <li>{@link android.media.MediaRecorder#setVideoFrameRate(int) setVideoFrameRate()}</li>
881  <li>{@link android.media.MediaRecorder#setAudioEncodingBitRate(int)
882setAudioEncodingBitRate()}</li>  <li>{@link android.media.MediaRecorder#setAudioChannels(int)
883setAudioChannels()}</li>
884  <li>{@link android.media.MediaRecorder#setAudioSamplingRate(int) setAudioSamplingRate()}</li>
885</ul>
886
887<h4 id="start-stop-mediarecorder">Starting and stopping MediaRecorder</h4>
888<p>When starting and stopping video recording using the {@link android.media.MediaRecorder} class,
889you must follow a specific order, as listed below.</p>
890
891<ol>
892  <li>Unlock the camera with {@link android.hardware.Camera#unlock() Camera.unlock()}</li>
893  <li>Configure {@link android.media.MediaRecorder} as shown in the code example above</li>
894  <li>Start recording using {@link android.media.MediaRecorder#start()
895MediaRecorder.start()}</li>
896  <li>Record the video</li>
897  <li>Stop recording using {@link
898android.media.MediaRecorder#stop() MediaRecorder.stop()}</li>
899  <li>Release the media recorder with {@link android.media.MediaRecorder#release()
900MediaRecorder.release()}</li>
901  <li>Lock the camera using {@link android.hardware.Camera#lock() Camera.lock()}</li>
902</ol>
903
904<p>The following example code demonstrates how to wire up a button to properly start and stop
905video recording using the camera and the {@link android.media.MediaRecorder} class.</p>
906
907<p class="note"><strong>Note:</strong> When completing a video recording, do not release the camera
908or else your preview will be stopped.</p>
909
910<pre>
911private boolean isRecording = false;
912
913// Add a listener to the Capture button
914Button captureButton = (Button) findViewById(id.button_capture);
915captureButton.setOnClickListener(
916    new View.OnClickListener() {
917        &#64;Override
918        public void onClick(View v) {
919            if (isRecording) {
920                // stop recording and release camera
921                mMediaRecorder.stop();  // stop the recording
922                releaseMediaRecorder(); // release the MediaRecorder object
923                mCamera.lock();         // take camera access back from MediaRecorder
924
925                // inform the user that recording has stopped
926                setCaptureButtonText("Capture");
927                isRecording = false;
928            } else {
929                // initialize video camera
930                if (prepareVideoRecorder()) {
931                    // Camera is available and unlocked, MediaRecorder is prepared,
932                    // now you can start recording
933                    mMediaRecorder.start();
934
935                    // inform the user that recording has started
936                    setCaptureButtonText("Stop");
937                    isRecording = true;
938                } else {
939                    // prepare didn't work, release the camera
940                    releaseMediaRecorder();
941                    // inform user
942                }
943            }
944        }
945    }
946);
947</pre>
948
949<p class="note"><strong>Note:</strong> In the above example, the {@code prepareVideoRecorder()}
950method refers to the example code shown in <a
951href="#configuring-mediarecorder">Configuring MediaRecorder</a>. This method takes care of locking
952the camera, configuring and preparing the {@link android.media.MediaRecorder} instance.</p>
953
954
955<h3 id="release-camera">Releasing the camera</h3>
956<p>Cameras are a resource that is shared by applications on a device. Your application can make
957use of the camera after getting an instance of {@link android.hardware.Camera}, and you must be
958particularly careful to release the camera object when your application stops using it, and as
959soon as your application is paused ({@link android.app.Activity#onPause() Activity.onPause()}). If
960your application does not properly release the camera, all subsequent attempts to access the camera,
961including those by your own application, will fail and may cause your or other applications to be
962shut down.</p>
963
964<p>To release an instance of the {@link android.hardware.Camera} object, use the {@link
965android.hardware.Camera#release() Camera.release()} method, as shown in the example code below.</p>
966
967<pre>
968public class CameraActivity extends Activity {
969    private Camera mCamera;
970    private SurfaceView mPreview;
971    private MediaRecorder mMediaRecorder;
972
973    ...
974
975    &#64;Override
976    protected void onPause() {
977        super.onPause();
978        releaseMediaRecorder();       // if you are using MediaRecorder, release it first
979        releaseCamera();              // release the camera immediately on pause event
980    }
981
982    private void releaseMediaRecorder(){
983        if (mMediaRecorder != null) {
984            mMediaRecorder.reset();   // clear recorder configuration
985            mMediaRecorder.release(); // release the recorder object
986            mMediaRecorder = null;
987            mCamera.lock();           // lock camera for later use
988        }
989    }
990
991    private void releaseCamera(){
992        if (mCamera != null){
993            mCamera.release();        // release the camera for other applications
994            mCamera = null;
995        }
996    }
997}
998</pre>
999
1000<p class="caution"><strong>Caution:</strong> If your application does not properly release the
1001camera, all subsequent attempts to access the camera, including those by your own application, will
1002fail and may cause your or other applications to be shut down.</p>
1003
1004
1005<h2 id="saving-media">Saving Media Files</h2>
1006<p>Media files created by users such as pictures and videos should be saved to a device's external
1007storage directory (SD Card) to conserve system space and to allow users to access these files
1008without their device. There are many possible directory locations to save media files on a device,
1009however there are only two standard locations you should consider as a developer:</p>
1010
1011<ul>
1012  <li><strong>{@link android.os.Environment#getExternalStoragePublicDirectory(java.lang.String)
1013Environment.getExternalStoragePublicDirectory}({@link android.os.Environment#DIRECTORY_PICTURES
1014Environment.DIRECTORY_PICTURES})</strong> - This method returns the standard, shared and recommended
1015location for saving pictures and videos. This directory is shared (public), so other applications
1016can easily discover, read, change and delete files saved in this location. If your application is
1017uninstalled by the user, media files saved to this location will not be removed. To avoid
1018interfering with users existing pictures and videos, you should create a sub-directory for your
1019application's media files within this directory, as shown in the code sample below. This method is
1020available in Android 2.2 (API Level 8), for equivalent calls in earlier API versions, see <a
1021href="{@docRoot}guide/topics/data/data-storage.html#SavingSharedFiles">Saving Shared Files</a>.</li>
1022  <li><strong>{@link android.content.Context#getExternalFilesDir(java.lang.String)
1023Context.getExternalFilesDir}({@link android.os.Environment#DIRECTORY_PICTURES
1024Environment.DIRECTORY_PICTURES})</strong> - This method returns a standard location for saving
1025pictures and videos which are associated with your application. If your application is uninstalled,
1026any files saved in this location are removed. Security is not enforced for files in this
1027location and other applications may read, change and delete them.</li>
1028</ul>
1029
1030<p>The following example code demonstrates how to create a {@link java.io.File} or {@link
1031android.net.Uri} location for a media file that can be used when invoking a device's camera with
1032an {@link android.content.Intent} or as part of a <a href="#custom-camera">Building a Camera
1033App</a>.</p>
1034
1035<pre>
1036public static final int MEDIA_TYPE_IMAGE = 1;
1037public static final int MEDIA_TYPE_VIDEO = 2;
1038
1039/** Create a file Uri for saving an image or video */
1040private static Uri getOutputMediaFileUri(int type){
1041      return Uri.fromFile(getOutputMediaFile(type));
1042}
1043
1044/** Create a File for saving an image or video */
1045private static File getOutputMediaFile(int type){
1046    // To be safe, you should check that the SDCard is mounted
1047    // using Environment.getExternalStorageState() before doing this.
1048
1049    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
1050              Environment.DIRECTORY_PICTURES), "MyCameraApp");
1051    // This location works best if you want the created images to be shared
1052    // between applications and persist after your app has been uninstalled.
1053
1054    // Create the storage directory if it does not exist
1055    if (! mediaStorageDir.exists()){
1056        if (! mediaStorageDir.mkdirs()){
1057            Log.d("MyCameraApp", "failed to create directory");
1058            return null;
1059        }
1060    }
1061
1062    // Create a media file name
1063    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
1064    File mediaFile;
1065    if (type == MEDIA_TYPE_IMAGE){
1066        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
1067        "IMG_"+ timeStamp + ".jpg");
1068    } else if(type == MEDIA_TYPE_VIDEO) {
1069        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
1070        "VID_"+ timeStamp + ".mp4");
1071    } else {
1072        return null;
1073    }
1074
1075    return mediaFile;
1076}
1077</pre>
1078
1079<p class="note"><strong>Note:</strong> {@link
1080android.os.Environment#getExternalStoragePublicDirectory(java.lang.String)
1081Environment.getExternalStoragePublicDirectory()} is available in Android 2.2 (API Level 8) or
1082higher. If you are targeting devices with earlier versions of Android, use {@link
1083android.os.Environment#getExternalStorageDirectory() Environment.getExternalStorageDirectory()}
1084instead. For more information, see <a
1085href="{@docRoot}guide/topics/data/data-storage.html#SavingSharedFiles">Saving Shared Files</a>.</p>
1086
1087<p>For more information about saving files on an Android device, see <a
1088href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a>.</p>
1089
1090
1091<h2 id="camera-features">Camera Features</h2>
1092<p>Android supports a wide array of camera features you can control with your camera application,
1093such as picture format, flash mode, focus settings, and many more. This section lists the common
1094camera features, and briefly discusses how to use them. Most camera features can be accessed and set
1095using the through {@link android.hardware.Camera.Parameters} object. However, there are several
1096important features that require more than simple settings in {@link
1097android.hardware.Camera.Parameters}. These features are covered in the following sections:<p>
1098
1099<ul>
1100  <li><a href="#metering-focus-areas">Metering and focus areas</a></li>
1101  <li><a href="#face-detection">Face detection</a></li>
1102  <li><a href="#time-lapse-video">Time lapse video</a></li>
1103</ul>
1104
1105<p>For general information about how to use features that are controlled through {@link
1106android.hardware.Camera.Parameters}, review the <a href="#using-features">Using camera
1107features</a> section. For more detailed information about how to use features controlled through the
1108camera parameters object, follow the links in the feature list below to the API reference
1109documentation.</p>
1110
1111<p class="table-caption" id="table1">
1112  <strong>Table 1.</strong> Common camera features sorted by the Android API Level in which they
1113were introduced.</p>
1114<table>
1115  <tr>
1116    <th>Feature</th>  <th>API Level</th>  <th>Description</th>
1117  </tr>
1118  <tr>
1119    <td><a href="#face-detection">Face Detection</a></td>
1120    <td>14</td>
1121    <td>Identify human faces within a picture and use them for focus, metering and white
1122balance</td>
1123  </tr>
1124  <tr>
1125    <td><a href="#metering-focus-areas">Metering Areas</a></td>
1126    <td>14</td>
1127    <td>Specify one or more areas within an image for calculating white balance</td>
1128  </tr>
1129  <tr>
1130    <td><a href="#metering-focus-areas">Focus Areas</a></td>
1131    <td>14</td>
1132    <td>Set one or more areas within an image to use for focus</td>
1133  </tr>
1134  <tr>
1135    <td>{@link android.hardware.Camera.Parameters#setAutoWhiteBalanceLock White Balance Lock}</td>
1136    <td>14</td>
1137    <td>Stop or start automatic white balance adjustments</td>
1138  </tr>
1139  <tr>
1140    <td>{@link android.hardware.Camera.Parameters#setAutoExposureLock Exposure Lock}</td>
1141    <td>14</td>
1142    <td>Stop or start automatic exposure adjustments</td>
1143  </tr>
1144  <tr>
1145    <td>{@link android.hardware.Camera#takePicture Video Snapshot}</td>
1146    <td>14</td>
1147    <td>Take a picture while shooting video (frame grab)</td>
1148  </tr>
1149  <tr>
1150    <td><a href="#time-lapse-video">Time Lapse Video</a></td>
1151    <td>11</td>
1152    <td>Record frames with set delays to record a time lapse video</td>
1153  </tr>
1154  <tr>
1155    <td>{@link android.hardware.Camera#open(int) Multiple Cameras}</td>
1156    <td>9</td>
1157    <td>Support for more than one camera on a device, including front-facing and back-facing
1158cameras</td>
1159  </tr>
1160  <tr>
1161    <td>{@link android.hardware.Camera.Parameters#getFocusDistances Focus Distance}</td>
1162    <td>9</td>
1163    <td>Reports distances between the camera and objects that appear to be in focus</td>
1164  </tr>
1165  <tr>
1166    <td>{@link android.hardware.Camera.Parameters#setZoom Zoom}</td>
1167    <td>8</td>
1168    <td>Set image magnification</td>
1169  </tr>
1170  <tr>
1171    <td>{@link android.hardware.Camera.Parameters#setExposureCompensation Exposure
1172Compensation}</td>
1173    <td>8</td>
1174    <td>Increase or decrease the light exposure level</td>
1175  </tr>
1176  <tr>
1177    <td>{@link android.hardware.Camera.Parameters#setGpsLatitude GPS Data}</td>
1178    <td>5</td>
1179    <td>Include or omit geographic location data with the image</td>
1180  </tr>
1181  <tr>
1182    <td>{@link android.hardware.Camera.Parameters#setWhiteBalance White Balance}</td>
1183    <td>5</td>
1184    <td>Set the white balance mode, which affects color values in the captured image</td>
1185  </tr>
1186  <tr>
1187    <td>{@link android.hardware.Camera.Parameters#setFocusMode Focus Mode}</td>
1188    <td>5</td>
1189    <td>Set how the camera focuses on a subject such as automatic, fixed, macro or infinity</td>
1190  </tr>
1191  <tr>
1192    <td>{@link android.hardware.Camera.Parameters#setSceneMode Scene Mode}</td>
1193    <td>5</td>
1194    <td>Apply a preset mode for specific types of photography situations such as night, beach, snow
1195or candlelight scenes</td>
1196  </tr>
1197  <tr>
1198    <td>{@link android.hardware.Camera.Parameters#setJpegQuality JPEG Quality}</td>
1199    <td>5</td>
1200    <td>Set the compression level for a JPEG image, which increases or decreases image output file
1201quality and size</td>
1202  </tr>
1203  <tr>
1204    <td>{@link android.hardware.Camera.Parameters#setFlashMode Flash Mode}</td>
1205    <td>5</td>
1206    <td>Turn flash on, off, or use automatic setting</td>
1207  </tr>
1208  <tr>
1209    <td>{@link android.hardware.Camera.Parameters#setColorEffect Color Effects}</td>
1210    <td>5</td>
1211    <td>Apply a color effect to the captured image such as black and white, sepia tone or negative.
1212</td>
1213  </tr>
1214  <tr>
1215    <td>{@link android.hardware.Camera.Parameters#setAntibanding Anti-Banding}</td>
1216    <td>5</td>
1217    <td>Reduces the effect of banding in color gradients due to JPEG compression</td>
1218  </tr>
1219  <tr>
1220    <td>{@link android.hardware.Camera.Parameters#setPictureFormat Picture Format}</td>
1221    <td>1</td>
1222    <td>Specify the file format for the picture</td>
1223  </tr>
1224  <tr>
1225    <td>{@link android.hardware.Camera.Parameters#setPictureSize Picture Size}</td>
1226    <td>1</td>
1227    <td>Specify the pixel dimensions of the saved picture</td>
1228  </tr>
1229</table>
1230
1231<p class="note"><strong>Note:</strong> These features are not supported on all devices due to
1232hardware differences and software implementation. For information on checking the availability
1233of features on the device where your application is running, see <a href="#check-feature">Checking
1234feature availability</a>.</p>
1235
1236
1237<h3 id="check-feature">Checking feature availability</h3>
1238<p>The first thing to understand when setting out to use camera features on Android devices is that
1239not all camera features are supported on all devices. In addition, devices that support a particular
1240feature may support them to different levels or with different options. Therefore, part of your
1241decision process as you develop a camera application is to decide what camera features you want to
1242support and to what level. After making that decision, you should plan on including code in your
1243camera application that checks to see if device hardware supports those features and fails
1244gracefully if a feature is not available.</p>
1245
1246<p>You can check the availabilty of camera features by getting an instance of a camera’s parameters
1247object, and checking the relevant methods. The following code sample shows you how to obtain a
1248{@link android.hardware.Camera.Parameters} object and check if the camera supports the autofocus
1249feature:</p>
1250
1251<pre>
1252// get Camera parameters
1253Camera.Parameters params = mCamera.getParameters();
1254
1255List&lt;String&gt; focusModes = params.getSupportedFocusModes();
1256if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
1257  // Autofocus mode is supported
1258}
1259</pre>
1260
1261<p>You can use the technique shown above for most camera features. The
1262{@link android.hardware.Camera.Parameters} object provides a {@code getSupported...()}, {@code
1263is...Supported()} or {@code getMax...()} method to determine if (and to what extent) a feature is
1264supported.</p>
1265
1266<p>If your application requires certain camera features in order to function properly, you can
1267require them through additions to your application manifest. When you declare the use of specific
1268camera features, such as flash and auto-focus, Google Play restricts your application from
1269being installed on devices which do not support these features. For a list of camera features that
1270can be declared in your app manifest, see the manifest
1271<a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#hw-features"> Features
1272Reference</a>.</p>
1273
1274<h3 id="using-features">Using camera features</h3>
1275<p>Most camera features are activated and controlled using a {@link
1276android.hardware.Camera.Parameters} object. You obtain this object by first getting an instance of
1277the {@link android.hardware.Camera} object, calling the {@link
1278android.hardware.Camera#getParameters getParameters()} method, changing the returned parameter
1279object and then setting it back into the camera object, as demonstrated in the following example
1280code:</p>
1281
1282<pre>
1283// get Camera parameters
1284Camera.Parameters params = mCamera.getParameters();
1285// set the focus mode
1286params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
1287// set Camera parameters
1288mCamera.setParameters(params);
1289</pre>
1290
1291<p>This technique works for nearly all camera features, and most parameters can be changed at any
1292time after you have obtained an instance of the {@link android.hardware.Camera} object. Changes to
1293parameters are typically visible to the user immediately in the application’s camera preview.
1294On the software side, parameter changes may take several frames to actually take effect as the
1295camera hardware processes the new instructions and then sends updated image data.</p>
1296
1297<p class="caution"><strong>Important:</strong> Some camera features cannot be changed at will. In
1298particular, changing the size or orientation of the camera preview requires that you first stop the
1299preview, change the preview size, and then restart the preview. Starting with Android 4.0 (API
1300Level 14) preview orientation can be changed without restarting the preview.</p>
1301
1302<p>Other camera features require more code in order to implement, including:</p>
1303<ul>
1304  <li>Metering and focus areas</li>
1305  <li>Face detection</li>
1306  <li>Time lapse video</li>
1307</ul>
1308<p>A quick outline of how to implement these features is provided in the following sections.</p>
1309
1310
1311<h3 id="metering-focus-areas">Metering and focus areas</h3>
1312<p>In some photographic scenarios, automatic focusing and light metering may not produce the
1313desired results. Starting with Android 4.0 (API Level 14), your camera application can provide
1314additional controls to allow your app or users to specify areas in an image to use for determining
1315focus or light level settings and pass these values to the camera hardware for use in capturing
1316images or video.</p>
1317
1318<p>Areas for metering and focus work very similarly to other camera features, in that you control
1319them through methods in the {@link android.hardware.Camera.Parameters} object. The following code
1320demonstrates setting two light metering areas for an instance of
1321{@link android.hardware.Camera}:</p>
1322
1323<pre>
1324// Create an instance of Camera
1325mCamera = getCameraInstance();
1326
1327// set Camera parameters
1328Camera.Parameters params = mCamera.getParameters();
1329
1330if (params.getMaxNumMeteringAreas() > 0){ // check that metering areas are supported
1331    List&lt;Camera.Area&gt; meteringAreas = new ArrayList&lt;Camera.Area&gt;();
1332
1333    Rect areaRect1 = new Rect(-100, -100, 100, 100);    // specify an area in center of image
1334    meteringAreas.add(new Camera.Area(areaRect1, 600)); // set weight to 60%
1335    Rect areaRect2 = new Rect(800, -1000, 1000, -800);  // specify an area in upper right of image
1336    meteringAreas.add(new Camera.Area(areaRect2, 400)); // set weight to 40%
1337    params.setMeteringAreas(meteringAreas);
1338}
1339
1340mCamera.setParameters(params);
1341</pre>
1342
1343<p>The {@link android.hardware.Camera.Area} object contains two data parameters: A {@link
1344android.graphics.Rect} object for specifying an area within the camera’s field of view and a weight
1345value, which tells the camera what level of importance this area should be given in light metering
1346or focus calculations.</p>
1347
1348<p>The {@link android.graphics.Rect} field in a {@link android.hardware.Camera.Area} object
1349describes a rectangular shape mapped on a 2000 x 2000 unit grid. The coordinates -1000, -1000
1350represent the top, left corner of the camera image, and coordinates 1000, 1000 represent the
1351bottom, right corner of the camera image, as shown in the illustration below.</p>
1352
1353<img src='images/camera-area-coordinates.png' />
1354<p class="img-caption">
1355  <strong>Figure 1.</strong> The red lines illustrate the coordinate system for specifying a
1356{@link android.hardware.Camera.Area} within a camera preview. The blue box shows the location and
1357shape of an camera area with the {@link android.graphics.Rect} values 333,333,667,667.
1358</p>
1359
1360<p>The bounds of this coordinate system always correspond to the outer edge of the image visible in
1361the camera preview and do not shrink or expand with the zoom level. Similarly, rotation of the image
1362preview using {@link android.hardware.Camera#setDisplayOrientation Camera.setDisplayOrientation()}
1363does not remap the coordinate system.</p>
1364
1365
1366<h3 id="face-detection">Face detection</h3>
1367<p>For pictures that include people, faces are usually the most important part of the picture, and
1368should be used for determining both focus and white balance when capturing an image. The Android 4.0
1369(API Level 14) framework provides APIs for identifying faces and calculating picture settings using
1370face recognition technology.</p>
1371
1372<p class="note"><strong>Note:</strong> While the face detection feature is running,
1373{@link android.hardware.Camera.Parameters#setWhiteBalance},
1374{@link android.hardware.Camera.Parameters#setFocusAreas} and
1375{@link android.hardware.Camera.Parameters#setMeteringAreas} have no effect.</p>
1376
1377<p>Using the face detection feature in your camera application requires a few general steps:</p>
1378<ul>
1379  <li>Check that face detection is supported on the device</li>
1380  <li>Create a face detection listener</li>
1381  <li>Add the face detection listener to your camera object</li>
1382  <li>Start face detection after preview (and after <em>every</em> preview restart)</li>
1383</ul>
1384
1385<p>The face detection feature is not supported on all devices. You can check that this feature is
1386supported by calling {@link android.hardware.Camera.Parameters#getMaxNumDetectedFaces}. An
1387example of this check is shown in the {@code startFaceDetection()} sample method below.</p>
1388
1389<p>In order to be notified and respond to the detection of a face, your camera application must set
1390a listener for face detection events. In order to do this, you must create a listener class that
1391implements the {@link android.hardware.Camera.FaceDetectionListener} interface as shown in the
1392example code below.</p>
1393
1394<pre>
1395class MyFaceDetectionListener implements Camera.FaceDetectionListener {
1396
1397    &#064;Override
1398    public void onFaceDetection(Face[] faces, Camera camera) {
1399        if (faces.length > 0){
1400            Log.d("FaceDetection", "face detected: "+ faces.length +
1401                    " Face 1 Location X: " + faces[0].rect.centerX() +
1402                    "Y: " + faces[0].rect.centerY() );
1403        }
1404    }
1405}
1406</pre>
1407
1408<p>After creating this class, you then set it into your application’s
1409{@link android.hardware.Camera} object, as shown in the example code below:</p>
1410
1411<pre>
1412mCamera.setFaceDetectionListener(new MyFaceDetectionListener());
1413</pre>
1414
1415<p>Your application must start the face detection function each time you start (or restart) the
1416camera preview. Create a method for starting face detection so you can call it as needed, as shown
1417in the example code below.</p>
1418
1419<pre>
1420public void startFaceDetection(){
1421    // Try starting Face Detection
1422    Camera.Parameters params = mCamera.getParameters();
1423
1424    // start face detection only *after* preview has started
1425    if (params.getMaxNumDetectedFaces() > 0){
1426        // camera supports face detection, so can start it:
1427        mCamera.startFaceDetection();
1428    }
1429}
1430</pre>
1431
1432<p>You must start face detection <em>each time</em> you start (or restart) the camera preview. If
1433you use the preview class shown in <a href="#camera-preview">Creating a preview class</a>, add your
1434{@link android.hardware.Camera#startFaceDetection startFaceDetection()} method to both the
1435{@link android.view.SurfaceHolder.Callback#surfaceCreated surfaceCreated()} and {@link
1436android.view.SurfaceHolder.Callback#surfaceChanged surfaceChanged()} methods in your preview class,
1437as shown in the sample code below.</p>
1438
1439<pre>
1440public void surfaceCreated(SurfaceHolder holder) {
1441    try {
1442        mCamera.setPreviewDisplay(holder);
1443        mCamera.startPreview();
1444
1445        startFaceDetection(); // start face detection feature
1446
1447    } catch (IOException e) {
1448        Log.d(TAG, "Error setting camera preview: " + e.getMessage());
1449    }
1450}
1451
1452public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
1453
1454    if (mHolder.getSurface() == null){
1455        // preview surface does not exist
1456        Log.d(TAG, "mHolder.getSurface() == null");
1457        return;
1458    }
1459
1460    try {
1461        mCamera.stopPreview();
1462
1463    } catch (Exception e){
1464        // ignore: tried to stop a non-existent preview
1465        Log.d(TAG, "Error stopping camera preview: " + e.getMessage());
1466    }
1467
1468    try {
1469        mCamera.setPreviewDisplay(mHolder);
1470        mCamera.startPreview();
1471
1472        startFaceDetection(); // re-start face detection feature
1473
1474    } catch (Exception e){
1475        // ignore: tried to stop a non-existent preview
1476        Log.d(TAG, "Error starting camera preview: " + e.getMessage());
1477    }
1478}
1479</pre>
1480
1481<p class="note"><strong>Note:</strong> Remember to call this method <em>after</em> calling
1482{@link android.hardware.Camera#startPreview startPreview()}. Do not attempt to start face detection
1483in the {@link android.app.Activity#onCreate onCreate()} method of your camera app’s main activity,
1484as the preview is not available by this point in your application's the execution.</p>
1485
1486
1487<h3 id="time-lapse-video">Time lapse video</h3>
1488<p>Time lapse video allows users to create video clips that combine pictures taken a few seconds or
1489minutes apart. This feature uses {@link android.media.MediaRecorder} to record the images for a time
1490lapse sequence. </p>
1491
1492<p>To record a time lapse video with {@link android.media.MediaRecorder}, you must configure the
1493recorder object as if you are recording a normal video, setting the captured frames per second to a
1494low number and using one of the time lapse quality settings, as shown in the code example below.</p>
1495
1496<pre>
1497// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
1498mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH));
1499...
1500// Step 5.5: Set the video capture rate to a low number
1501mMediaRecorder.setCaptureRate(0.1); // capture a frame every 10 seconds
1502</pre>
1503
1504<p>These settings must be done as part of a larger configuration procedure for {@link
1505android.media.MediaRecorder}. For  a full configuration code example, see <a
1506href="#configuring-mediarecorder">Configuring MediaRecorder</a>. Once the configuration is complete,
1507you start the video recording as if you were recording a normal video clip. For more information
1508about configuring and running {@link android.media.MediaRecorder}, see <a
1509href="#capture-video">Capturing videos</a>.</p>
1510