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