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 </ol> 33 <h2>Key Classes</h2> 34 <ol> 35 <li>{@link android.hardware.Camera}</li> 36 <li>{@link android.view.SurfaceView}</li> 37 <li>{@link android.media.MediaRecorder}</li> 38 <li>{@link android.content.Intent}</li> 39 </ol> 40 <h2>See also</h2> 41 <ol> 42 <li><a href="{@docRoot}reference/android/hardware/Camera.html">Camera</a></li> 43 <li><a href="{@docRoot}reference/android/media/MediaRecorder.html">MediaRecorder</a></li> 44 <li><a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a></li> 45 </ol> 46 </div> 47</div> 48 49 50<p>The Android framework includes support for various cameras and camera features available on 51devices, allowing you to capture pictures and videos in your applications. This document discusses a 52quick, simple approach to image and video capture and outlines an advanced approach for creating 53custom camera experiences for your users.</p> 54 55<h2 id="considerations">Considerations</h2> 56<p>Before enabling your application to use cameras on Android devices, you should consider a few 57questions about how your app intends to use this hardware feature.</p> 58 59<ul> 60 <li><strong>Camera Requirement</strong> - Is the use of a camera so important to your 61application that you do not want your application installed on a device that does not have a 62camera? If so, you should declare the <a href="#manifest">camera requirement in your 63manifest</a>.</li> 64 65 <li><strong>Quick Picture or Customized Camera</strong> - How will your application use the 66camera? Are you just interested in snapping a quick picture or video clip, or will your application 67provide a new way to use cameras? For a getting a quick snap or clip, consider 68<a href="#intents">Using Existing Camera Apps</a>. For developing a customized camera feature, check 69out the <a href="#custom-camera">Building a Camera App</a> section.</li> 70 71 <li><strong>Storage</strong> - Are the images or videos your application generates intended to be 72only visible to your application or shared so that other applications such as Gallery or other 73media and social apps can use them? Do you want the pictures and videos to be available even if your 74application is uninstalled? Check out the <a href="#saving-media">Saving Media Files</a> section to 75see how to implement these options.</li> 76</ul> 77 78 79 80<h2 id="basics">The Basics</h2> 81<p>The Android framework supports capturing images and video through the 82{@link android.hardware.Camera} API or camera {@link android.content.Intent}. Here are the relevant 83classes:</p> 84 85<dl> 86 <dt>{@link android.hardware.Camera}</dt> 87 <dd>This class is the primary API for controlling device cameras. This class is used to take 88pictures or videos when you are building a camera application.</a>.</dd> 89 90 <dt>{@link android.view.SurfaceView}</dt> 91 <dd>This class is used to present a live camera preview to the user.</dd> 92 93 <dt>{@link android.media.MediaRecorder}</dt> 94 <dd>This class is used to record video from the camera.</dd> 95 96 <dt>{@link android.content.Intent}</dt> 97 <dd>An intent action type of {@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE 98MediaStore.ACTION_IMAGE_CAPTURE} or {@link android.provider.MediaStore#ACTION_VIDEO_CAPTURE 99MediaStore.ACTION_VIDEO_CAPTURE} can be used to capture images or videos without directly 100using the {@link android.hardware.Camera} object.</dd> 101</dl> 102 103 104<h2 id="manifest">Manifest Declarations</h2> 105<p>Before starting development on your application with the Camera API, you should make sure 106your manifest has the appropriate declarations to allow use of camera hardware and other 107related features.</p> 108 109<ul> 110 <li><strong>Camera Permission</strong> - Your application must request permission to use a device 111camera. 112<pre> 113<uses-permission android:name="android.permission.CAMERA" /> 114</pre> 115 <p class="note"><strong>Note:</strong> If you are using the camera <a href="#intents">via an 116intent</a>, your application does not need to request this permission.</p> 117 </li> 118 <li><strong>Camera Features</strong> - Your application must also declare use of camera features, 119for example: 120<pre> 121<uses-feature android:name="android.hardware.camera" /> 122</pre> 123 <p>For a list of camera features, see the manifest <a 124href="{@docRoot}guide/topics/manifest/uses-feature-element.html#features-reference">Features 125Reference</a>.</p> 126 <p>Adding camera features to your manifest causes Android Market to prevent your application from 127being installed to devices that do not include a camera or do not support the camera features you 128specify. For more information about using feature-based filtering with Android Market, see <a 129href="{@docRoot}guide/topics/manifest/uses-feature-element.html#market-feature-filtering">Android 130Market and Feature-Based Filtering</a>.</p> 131 <p>If your application <em>can use</em> a camera or camera feature for proper operation, but does 132not <em>require</em> it, you should specify this in the manifest by including the {@code 133android:required} attribute, and setting it to {@code false}:</p> 134<pre> 135<uses-feature android:name="android.hardware.camera" android:required="false" /> 136</pre> 137 138 </li> 139 <li><strong>Storage Permission</strong> - If your application saves images or videos to the 140device's external storage (SD Card), you must also specify this in the manifest. 141<pre> 142<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 143</pre> 144 </li> 145 <li><strong>Audio Recording Permission</strong> - For recording audio with video capture, your 146application must request the audio capture permission. 147<pre> 148<uses-permission android:name="android.permission.RECORD_AUDIO" /> 149</pre> 150 </li> 151</ul> 152 153 154<h2 id="intents">Using Existing Camera Apps</h2> 155<p>A quick way to enable taking pictures or videos in your application without a lot of extra code 156is to use an {@link android.content.Intent} to invoke an existing Android camera application. A 157camera intent makes a request to capture a picture or video clip through an existing camera app and 158then returns control back to your application. This section shows you how to capture an image or 159video using this technique.</p> 160 161<p>The procedure for invoking a camera intent follows these general steps:</p> 162 163<ol> 164 <li><strong>Compose a Camera Intent</strong> - Create an {@link android.content.Intent} that 165requests an image or video, using one of these intent types: 166 <ul> 167 <li>{@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE MediaStore.ACTION_IMAGE_CAPTURE} - 168Intent action type for requesting an image from an existing camera application.</li> 169 <li>{@link android.provider.MediaStore#ACTION_VIDEO_CAPTURE MediaStore.ACTION_VIDEO_CAPTURE} - 170Intent action type for requesting a video from an existing camera application. </li> 171 </ul> 172 </li> 173 <li><strong>Start the Camera Intent</strong> - Use the {@link 174android.app.Activity#startActivityForResult(android.content.Intent, int) startActivityForResult()} 175method to execute the camera intent. After you start the intent, the Camera application user 176interface appears on the device screen and the user can take a picture or video.</li> 177 <li><strong>Receive the Intent Result</strong> - Set up an {@link 178android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()} method 179in your application to receive the callback and data from the camera intent. When the user 180finishes taking a picture or video (or cancels the operation), the system calls this method.</li> 181</ol> 182 183 184<h3 id="intent-image">Image capture intent</h3> 185<p>Capturing images using a camera intent is quick way to enable your application to take pictures 186with minimal coding. An image capture intent can include the following extra information:</p> 187 188<ul> 189 <li>{@link android.provider.MediaStore#EXTRA_OUTPUT MediaStore.EXTRA_OUTPUT} - This setting 190requires a {@link android.net.Uri} object specifying a path and file name where you'd like to 191save the picture. This setting is optional but strongly recommended. If you do not specify this 192value, the camera application saves the requested picture in the default location with a default 193name, specified in the returned intent's {@link android.content.Intent#getData() Intent.getData()} 194field.</li> 195</ul> 196 197<p>The following example demonstrates how to construct a image capture intent and execute it. 198The {@code getOutputMediaFileUri()} method in this example refers to the sample code shown in <a 199href= "#saving-media">Saving Media Files</a>.</p> 200 201<pre> 202private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100; 203private Uri fileUri; 204 205@Override 206public void onCreate(Bundle savedInstanceState) { 207 super.onCreate(savedInstanceState); 208 setContentView(R.layout.main); 209 210 // create Intent to take a picture and return control to the calling application 211 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 212 213 fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image 214 intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name 215 216 // start the image capture Intent 217 startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); 218} 219</pre> 220 221<p>When the {@link android.app.Activity#startActivityForResult(android.content.Intent, int) 222startActivityForResult()} method is executed, users see a camera application interface. 223After the user finishes taking a picture (or cancels the operation), the user interface returns to 224your application, and you must intercept the {@link 225android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()} 226method to receive the result of the intent and continue your application execution. For information 227on how to receive the completed intent, see <a href="#intent-receive">Receiving Camera Intent 228Result</a>.</p> 229 230 231<h3 id="intent-video">Video capture intent</h3> 232<p>Capturing video using a camera intent is a quick way to enable your application to take videos 233with minimal coding. A video capture intent can include the following extra information:</p> 234 235<ul> 236 <li>{@link android.provider.MediaStore#EXTRA_OUTPUT MediaStore.EXTRA_OUTPUT} - This setting 237requires a {@link android.net.Uri} specifying a path and file name where you'd like to save the 238video. This setting is optional but strongly recommended. If you do not specify this value, the 239Camera application saves the requested video in the default location with a default name, specified 240in the returned intent's {@link android.content.Intent#getData() Intent.getData()} field.</li> 241 <li>{@link android.provider.MediaStore#EXTRA_VIDEO_QUALITY MediaStore.EXTRA_VIDEO_QUALITY} - 242This value can be 0 for lowest quality and smallest file size or 1 for highest quality and 243larger file size.</li> 244 <li>{@link android.provider.MediaStore#EXTRA_DURATION_LIMIT MediaStore.EXTRA_DURATION_LIMIT} - 245Set this value to limit the length, in seconds, of the video being captured.</li> 246 <li>{@link android.provider.MediaStore#EXTRA_SIZE_LIMIT MediaStore.EXTRA_SIZE_LIMIT} - 247Set this value to limit the file size, in bytes, of the video being captured. 248</li> 249</ul> 250 251<p>The following example demonstrates how to construct a video capture intent and execute it. 252The {@code getOutputMediaFileUri()} method in this example refers to the sample code shown in <a 253href= "#saving-media">Saving Media Files</a>.</p> 254 255<pre> 256private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200; 257private Uri fileUri; 258 259@Override 260public void onCreate(Bundle savedInstanceState) { 261 super.onCreate(savedInstanceState); 262 setContentView(R.layout.main); 263 264 //create new Intent 265 Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); 266 267 fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO); // create a file to save the video 268 intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name 269 270 intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high 271 272 // start the Video Capture Intent 273 startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE); 274} 275</pre> 276 277<p>When the {@link 278android.app.Activity#startActivityForResult(android.content.Intent, int) 279startActivityForResult()} method is executed, users see a modified camera application interface. 280After the user finishes taking a video (or cancels the operation), the user interface 281returns to your application, and you must intercept the {@link 282android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()} 283method to receive the result of the intent and continue your application execution. For information 284on how to receive the completed intent, see the next section.</p> 285 286<h3 id="intent-receive">Receiving camera intent result</h3> 287<p>Once you have constructed and executed an image or video camera intent, your application must be 288configured to receive the result of the intent. This section shows you how to intercept the callback 289from a camera intent so your application can do further processing of the captured image or 290video.</p> 291 292<p>In order to receive the result of an intent, you must override the {@link 293android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()} in the 294activity that started the intent. The following example demonstrates how to override {@link 295android.app.Activity#onActivityResult(int, int, android.content.Intent) onActivityResult()} to 296capture the result of the <a href="#intent-image">image camera intent</a> or <a 297href="#intent-video">video camera intent</a> examples shown in the previous sections.</p> 298 299<pre> 300private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100; 301private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200; 302 303@Override 304protected void onActivityResult(int requestCode, int resultCode, Intent data) { 305 if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) { 306 if (resultCode == RESULT_OK) { 307 // Image captured and saved to fileUri specified in the Intent 308 Toast.makeText(this, "Image saved to:\n" + 309 data.getData(), Toast.LENGTH_LONG).show(); 310 } else if (resultCode == RESULT_CANCELED) { 311 // User cancelled the image capture 312 } else { 313 // Image capture failed, advise user 314 } 315 } 316 317 if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) { 318 if (resultCode == RESULT_OK) { 319 // Video captured and saved to fileUri specified in the Intent 320 Toast.makeText(this, "Video saved to:\n" + 321 data.getData(), Toast.LENGTH_LONG).show(); 322 } else if (resultCode == RESULT_CANCELED) { 323 // User cancelled the video capture 324 } else { 325 // Video capture failed, advise user 326 } 327 } 328} 329</pre> 330 331<p>Once your activity receives a successful result, the captured image or video is available in the 332specified location for your application to access.</p> 333 334 335 336<h2 id="custom-camera">Building a Camera App</h2> 337<p>Some developers may require a camera user interface that is customized to the look of their 338application or provides special features. Creating a customized camera activity requires more 339code than <a href="#intents">using an intent</a>, but it can provide a more compelling experience 340for your users.</p> 341 342<p>The general steps for creating a custom camera interface for your application are as follows:</p> 343 344<ul> 345 <li><strong>Detect and Access Camera</strong> - Create code to check for the existence of 346cameras and request access.</li> 347 <li><strong>Create a Preview Class</strong> - Create a camera preview class that extends {@link 348android.view.SurfaceView} and implements the {@link android.view.SurfaceHolder} interface. This 349class previews the live images from the camera.</li> 350 <li><strong>Build a Preview Layout</strong> - Once you have the camera preview class, create a 351view layout that incorporates the preview and the user interface controls you want.</li> 352 <li><strong>Setup Listeners for Capture</strong> - Connect listeners for your interface 353controls to start image or video capture in response to user actions, such as pressing a 354button.</li> 355 <li><strong>Capture and Save Files</strong> - Setup the code for capturing pictures or 356videos and saving the output.</li> 357 <li><strong>Release the Camera</strong> - After using the camera, your application must 358properly release it for use by other applications.</li> 359</ul> 360 361<p>Camera hardware is a shared resource that must be carefully managed so your application does 362not collide with other applications that may also want to use it. The following sections discusses 363how to detect camera hardware, how to request access to a camera and how to release it when your 364application is done using it.</p> 365 366<p class="caution"><strong>Caution:</strong> Remember to release the {@link android.hardware.Camera} 367object by calling the {@link android.hardware.Camera#release() Camera.release()} when your 368application is done using it! If your application does not properly release the camera, all 369subsequent attempts to access the camera, including those by your own application, will fail and may 370cause your or other applications to be shut down.</p> 371 372 373<h3 id="detect-camera">Detecting camera hardware</h3> 374<p>If your application does not specifically require a camera using a manifest declaration, you 375should check to see if a camera is available at runtime. To perform this check, use the {@link 376android.content.pm.PackageManager#hasSystemFeature(java.lang.String) 377PackageManager.hasSystemFeature()} method, as shown in the example code below:</p> 378 379<pre> 380/** Check if this device has a camera */ 381private boolean checkCameraHardware(Context context) { 382 if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){ 383 // this device has a camera 384 return true; 385 } else { 386 // no camera on this device 387 return false; 388 } 389} 390</pre> 391 392<p>Android devices can have multiple cameras, for example a back-facing camera for photography and a 393front-facing camera for video calls. Android 2.3 (API Level 9) and later allows you to check the 394number of cameras available on a device using the {@link 395android.hardware.Camera#getNumberOfCameras() Camera.getNumberOfCameras()} method.</p> 396 397<h3 id="access-camera">Accessing cameras</h3> 398<p>If you have determined that the device on which your application is running has a camera, you 399must request to access it by getting an instance of {@link android.hardware.Camera} (unless you 400are using an <a href="#intents">intent to access the camera</a>). </p> 401 402<p>To access the primary camera, use the {@link android.hardware.Camera#open() Camera.open()} method 403and be sure to catch any exceptions, as shown in the code below:</p> 404 405<pre> 406/** A safe way to get an instance of the Camera object. */ 407public static Camera getCameraInstance(){ 408 Camera c = null; 409 try { 410 c = Camera.open(); // attempt to get a Camera instance 411 } 412 catch (Exception e){ 413 // Camera is not available (in use or does not exist) 414 } 415 return c; // returns null if camera is unavailable 416} 417</pre> 418 419<p class="caution"><strong>Caution:</strong> Always check for exceptions when using {@link 420android.hardware.Camera#open() Camera.open()}. Failing to check for exceptions if the camera is in 421use or does not exist will cause your application to be shut down by the system.</p> 422 423<p>On devices running Android 2.3 (API Level 9) or higher, you can access specific cameras using 424{@link android.hardware.Camera#open(int) Camera.open(int)}. The example code above will access 425the first, back-facing camera on a device with more than one camera.</p> 426 427<h3 id="check-camera-features">Checking camera features</h3> 428<p>Once you obtain access to a camera, you can get further information about its capabilties using 429the {@link android.hardware.Camera#getParameters() Camera.getParameters()} method and checking the 430returned {@link android.hardware.Camera.Parameters} object for supported capabilities. When using 431API Level 9 or higher, use the {@link android.hardware.Camera#getCameraInfo(int, 432android.hardware.Camera.CameraInfo) Camera.getCameraInfo()} to determine if a camera is on the front 433or back of the device, and the orientation of the image.</p> 434 435 436 437<h3 id="camera-preview">Creating a preview class</h3> 438<p>For users to effectively take pictures or video, they must be able to see what the device camera 439sees. A camera preview class is a {@link android.view.SurfaceView} that can display the live image 440data coming from a camera, so users can frame and capture a picture or video.</p> 441 442<p>The following example code demonstrates how to create a basic camera preview class that can be 443included in a {@link android.view.View} layout. This class implements {@link 444android.view.SurfaceHolder.Callback SurfaceHolder.Callback} in order to capture the callback events 445for creating and destroying the view, which are needed for assigning the camera preview input.</p> 446 447<pre> 448/** A basic Camera preview class */ 449public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 450 private SurfaceHolder mHolder; 451 private Camera mCamera; 452 453 public CameraPreview(Context context, Camera camera) { 454 super(context); 455 mCamera = camera; 456 457 // Install a SurfaceHolder.Callback so we get notified when the 458 // underlying surface is created and destroyed. 459 mHolder = getHolder(); 460 mHolder.addCallback(this); 461 // deprecated setting, but required on Android versions prior to 3.0 462 mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 463 } 464 465 public void surfaceCreated(SurfaceHolder holder) { 466 // The Surface has been created, now tell the camera where to draw the preview. 467 try { 468 mCamera.setPreviewDisplay(holder); 469 mCamera.startPreview(); 470 } catch (IOException e) { 471 Log.d(TAG, "Error setting camera preview: " + e.getMessage()); 472 } 473 } 474 475 public void surfaceDestroyed(SurfaceHolder holder) { 476 // empty. Take care of releasing the Camera preview in your activity. 477 } 478 479 public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 480 // If your preview can change or rotate, take care of those events here. 481 // Make sure to stop the preview before resizing or reformatting it. 482 483 if (mHolder.getSurface() == null){ 484 // preview surface does not exist 485 return; 486 } 487 488 // stop preview before making changes 489 try { 490 mCamera.stopPreview(); 491 } catch (Exception e){ 492 // ignore: tried to stop a non-existent preview 493 } 494 495 // make any resize, rotate or reformatting changes here 496 497 // start preview with new settings 498 try { 499 mCamera.setPreviewDisplay(mHolder); 500 mCamera.startPreview(); 501 502 } catch (Exception e){ 503 Log.d(TAG, "Error starting camera preview: " + e.getMessage()); 504 } 505 } 506} 507</pre> 508 509 510<h3 id="preview-layout">Placing preview in a layout</h3> 511<p>A camera preview class, such as the example shown in the previous section, must be placed in the 512layout of an activity along with other user interface controls for taking a picture or video. This 513section shows you how to build a basic layout and activity for the preview.</p> 514 515<p>The following layout code provides a very basic view that can be used to display a camera 516preview. In this example, the {@link android.widget.FrameLayout} element is meant to be the 517container for the camera preview class. This layout type is used so that additional picture 518information or controls can be overlayed on the live camera preview images.</p> 519 520<pre> 521<?xml version="1.0" encoding="utf-8"?> 522<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 523 android:orientation="horizontal" 524 android:layout_width="fill_parent" 525 android:layout_height="fill_parent" 526 > 527 <FrameLayout 528 android:id="@+id/camera_preview" 529 android:layout_width="fill_parent" 530 android:layout_height="fill_parent" 531 android:layout_weight="1" 532 /> 533 534 <Button 535 android:id="@+id/button_capture" 536 android:text="Capture" 537 android:layout_width="wrap_content" 538 android:layout_height="wrap_content" 539 android:layout_gravity="center" 540 /> 541</LinearLayout> 542</pre> 543 544<p>On most devices, the default orientation of the camera preview is landscape. This example layout 545specifies a horizontal (landscape) layout and the code below fixes the orientation of the 546application to landscape. For simplicity in rendering a camera preview, you should change your 547application's preview activity orientation to landscape by adding the following to your 548manifest.</p> 549 550<pre> 551<activity android:name=".CameraActivity" 552 android:label="@string/app_name" 553 554 android:screenOrientation="landscape"> 555 <!-- configure this activity to use landscape orientation --> 556 557 <intent-filter> 558 <action android:name="android.intent.action.MAIN" /> 559 <category android:name="android.intent.category.LAUNCHER" /> 560 </intent-filter> 561</activity> 562</pre> 563 564<p class="note"><strong>Note:</strong> A camera preview does not have to be in landscape mode. 565Starting in Android 2.2 (API Level 8), you can use the {@link 566android.hardware.Camera#setDisplayOrientation(int) setDisplayOrientation()} method to set the 567rotation of the preview image. In order to change preview orientation as the user re-orients the 568phone, within the {@link 569android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder, int, int, int) 570surfaceChanged()} method of your preview class, first stop the preview with {@link 571android.hardware.Camera#stopPreview() Camera.stopPreview()} change the orientation and then 572start the preview again with {@link android.hardware.Camera#startPreview() 573Camera.startPreview()}.</p> 574 575<p>In the activity for your camera view, add your preview class to the {@link 576android.widget.FrameLayout} element shown in the example above. Your camera activity must also 577ensure that it releases the camera when it is paused or shut down. The following example shows how 578to modify a camera activity to attach the preview class shown in <a href="#camera-preview">Creating 579a preview class</a>.</p> 580 581<pre> 582public class CameraActivity extends Activity { 583 584 private Camera mCamera; 585 private CameraPreview mPreview; 586 587 @Override 588 public void onCreate(Bundle savedInstanceState) { 589 super.onCreate(savedInstanceState); 590 setContentView(R.layout.main); 591 592 // Create an instance of Camera 593 mCamera = getCameraInstance(); 594 595 // Create our Preview view and set it as the content of our activity. 596 mPreview = new CameraPreview(this, mCamera); 597 FrameLayout preview = (FrameLayout) findViewById(id.camera_preview); 598 preview.addView(mPreview); 599 } 600} 601</pre> 602 603<p class="note"><strong>Note:</strong> The {@code getCameraInstance()} method in the example above 604refers to the example method shown in <a href="#access-camera">Accessing cameras</a>.</p> 605 606 607<h3 id="capture-picture">Capturing pictures</h3> 608<p>Once you have built a preview class and a view layout in which to display it, you are ready to 609start capturing images with your application. In your application code, you must set up listeners 610for your user interface controls to respond to a user action by taking a picture.</p> 611 612<p>In order to retrieve a picture, use the {@link 613android.hardware.Camera#takePicture(android.hardware.Camera.ShutterCallback, 614android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback) 615Camera.takePicture()} method. This method takes three parameters which receive data from the camera. 616In order to receive data in a JPEG format, you must implement an {@link 617android.hardware.Camera.PictureCallback} interface to receive the image data and 618write it to a file. The following code shows a basic implementation of the {@link 619android.hardware.Camera.PictureCallback} interface to save an image received from the camera.</p> 620 621<pre> 622private PictureCallback mPicture = new PictureCallback() { 623 624 @Override 625 public void onPictureTaken(byte[] data, Camera camera) { 626 627 File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE); 628 if (pictureFile == null){ 629 Log.d(TAG, "Error creating media file, check storage permissions: " + 630 e.getMessage()); 631 return; 632 } 633 634 try { 635 FileOutputStream fos = new FileOutputStream(pictureFile); 636 fos.write(data); 637 fos.close(); 638 } catch (FileNotFoundException e) { 639 Log.d(TAG, "File not found: " + e.getMessage()); 640 } catch (IOException e) { 641 Log.d(TAG, "Error accessing file: " + e.getMessage()); 642 } 643 } 644}; 645</pre> 646 647<p>Trigger capturing an image by calling the {@link 648android.hardware.Camera#takePicture(android.hardware.Camera.ShutterCallback, 649android.hardware.Camera.PictureCallback, android.hardware.Camera.PictureCallback) 650Camera.takePicture()} method. The following example code shows how to call this method from a 651button {@link android.view.View.OnClickListener}.</p> 652 653<pre> 654// Add a listener to the Capture button 655Button captureButton = (Button) findViewById(id.button_capture); 656 captureButton.setOnClickListener( 657 new View.OnClickListener() { 658 @Override 659 public void onClick(View v) { 660 // get an image from the camera 661 mCamera.takePicture(null, null, mPicture); 662 } 663 } 664); 665</pre> 666 667<p class="note"><strong>Note:</strong> The {@code mPicture} member in the following example refers 668to the example code above.</p> 669 670<p class="caution"><strong>Caution:</strong> Remember to release the {@link android.hardware.Camera} 671object by calling the {@link android.hardware.Camera#release() Camera.release()} when your 672application is done using it! For information about how to release the camera, see <a 673href="#release-camera">Releasing the camera</a>.</p> 674 675 676<h3 id="capture-video">Capturing videos</h3> 677 678<p>Video capture using the Android framework requires careful management of the {@link 679android.hardware.Camera} object and coordination with the {@link android.media.MediaRecorder} 680class. When recording video with {@link android.hardware.Camera}, you must manage the {@link 681android.hardware.Camera#lock() Camera.lock()} and {@link android.hardware.Camera#unlock() 682Camera.unlock()} calls to allow {@link android.media.MediaRecorder} access to the camera hardware, 683in addition to the {@link android.hardware.Camera#open() Camera.open()} and {@link 684android.hardware.Camera#release() Camera.release()} calls.</p> 685 686<p class="note"><strong>Note:</strong> Starting with Android 4.0 (API level 14), the {@link 687android.hardware.Camera#lock() Camera.lock()} and {@link android.hardware.Camera#unlock() 688Camera.unlock()} calls are managed for you automatically.</p> 689 690<p>Unlike taking pictures with a device camera, capturing video requires a very particular call 691order. You must follow a specific order of execution to successfully prepare for and capture video 692with your application, as detailed below.</p> 693 694<ol> 695 <li><strong>Open Camera</strong> - Use the {@link android.hardware.Camera#open() Camera.open()} 696to get an instance of the camera object.</li> 697 <li><strong>Connect Preview</strong> - Prepare a live camera image preview by connecting a {@link 698android.view.SurfaceView} to the camera using {@link 699android.hardware.Camera#setPreviewDisplay(android.view.SurfaceHolder) Camera.setPreviewDisplay()}. 700 </li> 701 <li><strong>Start Preview</strong> - Call {@link android.hardware.Camera#startPreview() 702Camera.startPreview()} to begin displaying the live camera images.</li> 703 <li><strong>Start Recording Video</strong> - The following steps must be completed <em>in 704order</em> to successfully record video: 705 <ol style="list-style-type: lower-alpha;"> 706 <li><strong>Unlock the Camera</strong> - Unlock the camera for use by {@link 707android.media.MediaRecorder} by calling {@link android.hardware.Camera#unlock() 708Camera.unlock()}.</li> 709 <li><strong>Configure MediaRecorder</strong> - Call in the following {@link 710android.media.MediaRecorder} methods <em>in this order</em>. For more information, see the {@link 711android.media.MediaRecorder} reference documentation. 712 <ol> 713 <li>{@link android.media.MediaRecorder#setCamera(android.hardware.Camera) 714setCamera()} - Set the camera to be used for video capture, use your application's current instance 715of {@link android.hardware.Camera}.</li> 716 <li>{@link android.media.MediaRecorder#setAudioSource(int) setAudioSource()} - Set the 717audio source, use {@link android.media.MediaRecorder.AudioSource#CAMCORDER 718MediaRecorder.AudioSource.CAMCORDER}. </li> 719 <li>{@link android.media.MediaRecorder#setVideoSource(int) setVideoSource()} - Set 720the video source, use {@link android.media.MediaRecorder.VideoSource#CAMERA 721MediaRecorder.VideoSource.CAMERA}.</li> 722 <li>Set the video output format and encoding. For Android 2.2 (API Level 8) and 723higher, use the {@link android.media.MediaRecorder#setProfile(android.media.CamcorderProfile) 724MediaRecorder.setProfile} method, and get a profile instance using {@link 725android.media.CamcorderProfile#get(int) CamcorderProfile.get()}. For versions of Android prior to 7262.2, you must set the video output format and encoding parameters: 727 <ol style="list-style-type: lower-roman;"> 728 <li>{@link android.media.MediaRecorder#setOutputFormat(int) setOutputFormat()} - Set 729the output format, specify the default setting or {@link 730android.media.MediaRecorder.OutputFormat#MPEG_4 MediaRecorder.OutputFormat.MPEG_4}.</li> 731 <li>{@link android.media.MediaRecorder#setAudioEncoder(int) setAudioEncoder()} - Set 732the sound encoding type, specify the default setting or {@link 733android.media.MediaRecorder.AudioEncoder#AMR_NB MediaRecorder.AudioEncoder.AMR_NB}.</li> 734 <li>{@link android.media.MediaRecorder#setVideoEncoder(int) setVideoEncoder()} - Set 735the video encoding type, specify the default setting or {@link 736android.media.MediaRecorder.VideoEncoder#MPEG_4_SP MediaRecorder.VideoEncoder.MPEG_4_SP}.</li> 737 </ol> 738 </li> 739 <li>{@link android.media.MediaRecorder#setOutputFile(java.lang.String) setOutputFile()} - 740Set the output file, use {@code getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()} from the example 741method in the <a href="#saving-media">Saving Media Files</a> section.</li> 742 <li>{@link android.media.MediaRecorder#setPreviewDisplay(android.view.Surface) 743setPreviewDisplay()} - Specify the {@link android.view.SurfaceView} preview layout element for 744your application. Use the same object you specified for <strong>Connect Preview</strong>.</li> 745 </ol> 746 <p class="caution"><strong>Caution:</strong> You must call these {@link 747android.media.MediaRecorder} configuration methods <em>in this order</em>, otherwise your 748application will encounter errors and the recording will fail.</p> 749 </li> 750 <li><strong>Prepare MediaRecorder</strong> - Prepare the {@link android.media.MediaRecorder} 751with provided configuration settings by calling {@link android.media.MediaRecorder#prepare() 752MediaRecorder.prepare()}.</li> 753 <li><strong>Start MediaRecorder</strong> - Start recording video by calling {@link 754android.media.MediaRecorder#start() MediaRecorder.start()}.</li> 755 </ol> 756 </li> 757 <li><strong>Stop Recording Video</strong> - Call the following methods <em>in order</em>, to 758successfully complete a video recording: 759 <ol style="list-style-type: lower-alpha;"> 760 <li><strong>Stop MediaRecorder</strong> - Stop recording video by calling {@link 761android.media.MediaRecorder#stop() MediaRecorder.stop()}.</li> 762 <li><strong>Reset MediaRecorder</strong> - Optionally, remove the configuration settings from 763the recorder by calling {@link android.media.MediaRecorder#reset() MediaRecorder.reset()}.</li> 764 <li><strong>Release MediaRecorder</strong> - Release the {@link android.media.MediaRecorder} 765by calling {@link android.media.MediaRecorder#release() MediaRecorder.release()}.</li> 766 <li><strong>Lock the Camera</strong> - Lock the camera so that future {@link 767android.media.MediaRecorder} sessions can use it by calling {@link android.hardware.Camera#lock() 768Camera.lock()}. Starting with Android 4.0 (API level 14), this call is not required unless the 769{@link android.media.MediaRecorder#prepare() MediaRecorder.prepare()} call fails.</li> 770 </ol> 771 </li> 772 <li><strong>Stop the Preview</strong> - When your activity has finished using the camera, stop the 773preview using {@link android.hardware.Camera#stopPreview() Camera.stopPreview()}.</li> 774 <li><strong>Release Camera</strong> - Release the camera so that other applications can use 775it by calling {@link android.hardware.Camera#release() Camera.release()}.</li> 776</ol> 777 778<p class="note"><strong>Note:</strong> It is possible to use {@link android.media.MediaRecorder} 779without creating a camera preview first and skip the first few steps of this process. However, 780since users typically prefer to see a preview before starting a recording, that process is not 781discussed here.</p> 782 783<h4 id="configuring-mediarecorder">Configuring MediaRecorder</h4> 784<p>When using the {@link android.media.MediaRecorder} class to record video, you must perform 785configuration steps in a <em>specific order</em> and then call the {@link 786android.media.MediaRecorder#prepare() MediaRecorder.prepare()} method to check and implement the 787configuration. The following example code demonstrates how to properly configure and prepare the 788{@link android.media.MediaRecorder} class for video recording.</p> 789 790<pre> 791private boolean prepareVideoRecorder(){ 792 793 mCamera = getCameraInstance(); 794 mMediaRecorder = new MediaRecorder(); 795 796 // Step 1: Unlock and set camera to MediaRecorder 797 mCamera.unlock(); 798 mMediaRecorder.setCamera(mCamera); 799 800 // Step 2: Set sources 801 mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); 802 mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 803 804 // Step 3: Set a CamcorderProfile (requires API Level 8 or higher) 805 mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); 806 807 // Step 4: Set output file 808 mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()); 809 810 // Step 5: Set the preview output 811 mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface()); 812 813 // Step 6: Prepare configured MediaRecorder 814 try { 815 mMediaRecorder.prepare(); 816 } catch (IllegalStateException e) { 817 Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage()); 818 releaseMediaRecorder(); 819 return false; 820 } catch (IOException e) { 821 Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage()); 822 releaseMediaRecorder(); 823 return false; 824 } 825 return true; 826} 827</pre> 828 829<p>Prior to Android 2.2 (API Level 8), you must set the output format and encoding formats 830parameters directly, instead of using {@link android.media.CamcorderProfile}. This approach is 831demonstrated in the following code:</p> 832 833<pre> 834 // Step 3: Set output format and encoding (for versions prior to API Level 8) 835 mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); 836 mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); 837 mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT); 838</pre> 839 840<p>The following video recording parameters for {@link android.media.MediaRecorder} are given 841default settings, however, you may want to adjust these settings for your application:</p> 842 843<ul> 844 <li>{@link android.media.MediaRecorder#setVideoEncodingBitRate(int) 845setVideoEncodingBitRate()}</li> 846 <li>{@link android.media.MediaRecorder#setVideoSize(int, int) setVideoSize()}</li> 847 <li>{@link android.media.MediaRecorder#setVideoFrameRate(int) setVideoFrameRate()}</li> 848 <li>{@link android.media.MediaRecorder#setAudioEncodingBitRate(int) 849setAudioEncodingBitRate()}</li> <li>{@link android.media.MediaRecorder#setAudioChannels(int) 850setAudioChannels()}</li> 851 <li>{@link android.media.MediaRecorder#setAudioSamplingRate(int) setAudioSamplingRate()}</li> 852</ul> 853 854<h4 id="start-stop-mediarecorder">Starting and Stopping MediaRecorder</h4> 855<p>When starting and stopping video recording using the {@link android.media.MediaRecorder} class, 856you must follow a specific order, as listed below.</p> 857 858<ol> 859 <li>Unlock the camera with {@link android.hardware.Camera#unlock() Camera.unlock()}</li> 860 <li>Configure {@link android.media.MediaRecorder} as shown in the code example above</li> 861 <li>Start recording using {@link android.media.MediaRecorder#start() 862MediaRecorder.start()}</li> 863 <li>Record the video</li> 864 <li>Stop recording using {@link 865android.media.MediaRecorder#stop() MediaRecorder.stop()}</li> 866 <li>Release the media recorder with {@link android.media.MediaRecorder#release() 867MediaRecorder.release()}</li> 868 <li>Lock the camera using {@link android.hardware.Camera#lock() Camera.lock()}</li> 869</ol> 870 871<p>The following example code demonstrates how to wire up a button to properly start and stop 872video recording using the camera and the {@link android.media.MediaRecorder} class.</p> 873 874<p class="note"><strong>Note:</strong> When completing a video recording, do not release the camera 875or else your preview will be stopped.</p> 876 877<pre> 878private boolean isRecording = false; 879 880// Add a listener to the Capture button 881Button captureButton = (Button) findViewById(id.button_capture); 882captureButton.setOnClickListener( 883 new View.OnClickListener() { 884 @Override 885 public void onClick(View v) { 886 if (isRecording) { 887 // stop recording and release camera 888 mMediaRecorder.stop(); // stop the recording 889 releaseMediaRecorder(); // release the MediaRecorder object 890 mCamera.lock(); // take camera access back from MediaRecorder 891 892 // inform the user that recording has stopped 893 setCaptureButtonText("Capture"); 894 isRecording = false; 895 } else { 896 // initialize video camera 897 if (prepareVideoRecorder()) { 898 // Camera is available and unlocked, MediaRecorder is prepared, 899 // now you can start recording 900 mMediaRecorder.start(); 901 902 // inform the user that recording has started 903 setCaptureButtonText("Stop"); 904 isRecording = true; 905 } else { 906 // prepare didn't work, release the camera 907 releaseMediaRecorder(); 908 // inform user 909 } 910 } 911 } 912 } 913); 914</pre> 915 916<p class="note"><strong>Note:</strong> In the above example, the {@code prepareVideoRecorder()} 917method refers to the example code shown in <a 918href="#configuring-mediarecorder">Configuring MediaRecorder</a>. This method takes care of locking 919the camera, configuring and preparing the {@link android.media.MediaRecorder} instance.</p> 920 921 922<h3 id="release-camera">Releasing the camera</h3> 923<p>Cameras are a resource that is shared by applications on a device. Your application can make 924use of the camera after getting an instance of {@link android.hardware.Camera}, and you must be 925particularly careful to release the camera object when your application stops using it, and as 926soon as your application is paused ({@link android.app.Activity#onPause() Activity.onPause()}). If 927your application does not properly release the camera, all subsequent attempts to access the camera, 928including those by your own application, will fail and may cause your or other applications to be 929shut down.</p> 930 931<p>To release an instance of the {@link android.hardware.Camera} object, use the {@link 932android.hardware.Camera#release() Camera.release()} method, as shown in the example code below.</p> 933 934<pre> 935public class CameraActivity extends Activity { 936 private Camera mCamera; 937 private SurfaceView mPreview; 938 private MediaRecorder mMediaRecorder; 939 940 ... 941 942 @Override 943 protected void onPause() { 944 super.onPause(); 945 releaseMediaRecorder(); // if you are using MediaRecorder, release it first 946 releaseCamera(); // release the camera immediately on pause event 947 } 948 949 private void releaseMediaRecorder(){ 950 if (mMediaRecorder != null) { 951 mMediaRecorder.reset(); // clear recorder configuration 952 mMediaRecorder.release(); // release the recorder object 953 mMediaRecorder = null; 954 mCamera.lock(); // lock camera for later use 955 } 956 } 957 958 private void releaseCamera(){ 959 if (mCamera != null){ 960 mCamera.release(); // release the camera for other applications 961 mCamera = null; 962 } 963 } 964} 965</pre> 966 967<p class="caution"><strong>Caution:</strong> If your application does not properly release the 968camera, all subsequent attempts to access the camera, including those by your own application, will 969fail and may cause your or other applications to be shut down.</p> 970 971 972<h2 id="saving-media">Saving Media Files</h2> 973<p>Media files created by users such as pictures and videos should be saved to a device's external 974storage directory (SD Card) to conserve system space and to allow users to access these files 975without their device. There are many possible directory locations to save media files on a device, 976however there are only two standard locations you should consider as a developer:</p> 977 978<ul> 979 <li><strong>{@link android.os.Environment#getExternalStoragePublicDirectory(java.lang.String) 980Environment.getExternalStoragePublicDirectory}({@link android.os.Environment#DIRECTORY_PICTURES 981Environment.DIRECTORY_PICTURES})</strong> - This method returns the standard, shared and recommended 982location for saving pictures and videos. This directory is shared (public), so other applications 983can easily discover, read, change and delete files saved in this location. If your application is 984uninstalled by the user, media files saved to this location will not be removed. To avoid 985interfering with users existing pictures and videos, you should create a sub-directory for your 986application's media files within this directory, as shown in the code sample below. This method is 987available in Android 2.2 (API Level 8), for equivalent calls in earlier API versions, see <a 988href="{@docRoot}guide/topics/data/data-storage.html#SavingSharedFiles">Saving Shared Files</a>.</li> 989 <li><strong>{@link android.content.Context#getExternalFilesDir(java.lang.String) 990Context.getExternalFilesDir}({@link android.os.Environment#DIRECTORY_PICTURES 991Environment.DIRECTORY_PICTURES})</strong> - This method returns a standard location for saving 992pictures and videos which are associated with your application. If your application is uninstalled, 993any files saved in this location are removed. Security is not enforced for files in this 994location and other applications may read, change and delete them.</li> 995</ul> 996 997<p>The following example code demonstrates how to create a {@link java.io.File} or {@link 998android.net.Uri} location for a media file that can be used when invoking a device's camera with 999an {@link android.content.Intent} or as part of a <a href="#custom-camera">Building a Camera 1000App</a>.</p> 1001 1002<pre> 1003public static final int MEDIA_TYPE_IMAGE = 1; 1004public static final int MEDIA_TYPE_VIDEO = 2; 1005 1006/** Create a file Uri for saving an image or video */ 1007private static Uri getOutputMediaFileUri(int type){ 1008 return Uri.fromFile(getOutputMediaFile(type)); 1009} 1010 1011/** Create a File for saving an image or video */ 1012private static Uri getOutputMediaFile(int type){ 1013 // To be safe, you should check that the SDCard is mounted 1014 // using Environment.getExternalStorageState() before doing this. 1015 1016 File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( 1017 Environment.DIRECTORY_PICTURES), "MyCameraApp"); 1018 // This location works best if you want the created images to be shared 1019 // between applications and persist after your app has been uninstalled. 1020 1021 // Create the storage directory if it does not exist 1022 if (! mediaStorageDir.exists()){ 1023 if (! mediaStorageDir.mkdirs()){ 1024 Log.d("MyCameraApp", "failed to create directory"); 1025 return null; 1026 } 1027 } 1028 1029 // Create a media file name 1030 String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 1031 File mediaFile; 1032 if (type == MEDIA_TYPE_IMAGE){ 1033 mediaFile = new File(mediaStorageDir.getPath() + File.separator + 1034 "IMG_"+ timeStamp + ".jpg"); 1035 } else if(type == MEDIA_TYPE_VIDEO) { 1036 mediaFile = new File(mediaStorageDir.getPath() + File.separator + 1037 "VID_"+ timeStamp + ".mp4"); 1038 } else { 1039 return null; 1040 } 1041 1042 return mediaFile; 1043} 1044</pre> 1045 1046<p class="note"><strong>Note:</strong> {@link 1047android.os.Environment#getExternalStoragePublicDirectory(java.lang.String) 1048Environment.getExternalStoragePublicDirectory()} is available in Android 2.2 (API Level 8) or 1049higher. If you are targeting devices with earlier versions of Android, use {@link 1050android.os.Environment#getExternalStorageDirectory() Environment.getExternalStorageDirectory()} 1051instead. For more information, see <a 1052href="{@docRoot}guide/topics/data/data-storage.html#SavingSharedFiles">Saving Shared Files</a>.</p> 1053 1054<p>For more information about saving files on an Android device, see <a 1055href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a>.</p>