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