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