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