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