Camera.java revision 9b6a8ab8221f2df20c32711b0f1e4f301165fac2
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.hardware; 18 19import java.lang.ref.WeakReference; 20import java.util.ArrayList; 21import java.util.HashMap; 22import java.util.List; 23import java.util.StringTokenizer; 24import java.io.IOException; 25 26import android.util.Log; 27import android.view.Surface; 28import android.view.SurfaceHolder; 29import android.graphics.PixelFormat; 30import android.os.Handler; 31import android.os.Looper; 32import android.os.Message; 33 34/** 35 * The Camera class is used to connect/disconnect with the camera service, 36 * set capture settings, start/stop preview, snap a picture, and retrieve 37 * frames for encoding for video. 38 * <p>There is no default constructor for this class. Use {@link #open()} to 39 * get a Camera object.</p> 40 */ 41public class Camera { 42 private static final String TAG = "Camera"; 43 44 // These match the enums in frameworks/base/include/ui/Camera.h 45 private static final int CAMERA_MSG_ERROR = 0x001; 46 private static final int CAMERA_MSG_SHUTTER = 0x002; 47 private static final int CAMERA_MSG_FOCUS = 0x004; 48 private static final int CAMERA_MSG_ZOOM = 0x008; 49 private static final int CAMERA_MSG_PREVIEW_FRAME = 0x010; 50 private static final int CAMERA_MSG_VIDEO_FRAME = 0x020; 51 private static final int CAMERA_MSG_POSTVIEW_FRAME = 0x040; 52 private static final int CAMERA_MSG_RAW_IMAGE = 0x080; 53 private static final int CAMERA_MSG_COMPRESSED_IMAGE = 0x100; 54 private static final int CAMERA_MSG_ALL_MSGS = 0x1FF; 55 56 private int mNativeContext; // accessed by native methods 57 private EventHandler mEventHandler; 58 private ShutterCallback mShutterCallback; 59 private PictureCallback mRawImageCallback; 60 private PictureCallback mJpegCallback; 61 private PreviewCallback mPreviewCallback; 62 private PictureCallback mPostviewCallback; 63 private AutoFocusCallback mAutoFocusCallback; 64 private ZoomCallback mZoomCallback; 65 private ErrorCallback mErrorCallback; 66 private boolean mOneShot; 67 68 /** 69 * Returns a new Camera object. 70 */ 71 public static Camera open() { 72 return new Camera(); 73 } 74 75 Camera() { 76 mShutterCallback = null; 77 mRawImageCallback = null; 78 mJpegCallback = null; 79 mPreviewCallback = null; 80 mPostviewCallback = null; 81 mZoomCallback = null; 82 83 Looper looper; 84 if ((looper = Looper.myLooper()) != null) { 85 mEventHandler = new EventHandler(this, looper); 86 } else if ((looper = Looper.getMainLooper()) != null) { 87 mEventHandler = new EventHandler(this, looper); 88 } else { 89 mEventHandler = null; 90 } 91 92 native_setup(new WeakReference<Camera>(this)); 93 } 94 95 protected void finalize() { 96 native_release(); 97 } 98 99 private native final void native_setup(Object camera_this); 100 private native final void native_release(); 101 102 103 /** 104 * Disconnects and releases the Camera object resources. 105 * <p>It is recommended that you call this as soon as you're done with the 106 * Camera object.</p> 107 */ 108 public final void release() { 109 native_release(); 110 } 111 112 /** 113 * Reconnect to the camera after passing it to MediaRecorder. To save 114 * setup/teardown time, a client of Camera can pass an initialized Camera 115 * object to a MediaRecorder to use for video recording. Once the 116 * MediaRecorder is done with the Camera, this method can be used to 117 * re-establish a connection with the camera hardware. NOTE: The Camera 118 * object must first be unlocked by the process that owns it before it 119 * can be connected to another process. 120 * 121 * @throws IOException if the method fails. 122 * 123 * FIXME: Unhide after approval 124 * @hide 125 */ 126 public native final void reconnect() throws IOException; 127 128 /** 129 * Lock the camera to prevent other processes from accessing it. To save 130 * setup/teardown time, a client of Camera can pass an initialized Camera 131 * object to another process. This method is used to re-lock the Camera 132 * object prevent other processes from accessing it. By default, the 133 * Camera object is locked. Locking it again from the same process will 134 * have no effect. Attempting to lock it from another process if it has 135 * not been unlocked will fail. 136 * Returns 0 if lock was successful. 137 * 138 * FIXME: Unhide after approval 139 * @hide 140 */ 141 public native final int lock(); 142 143 /** 144 * Unlock the camera to allow another process to access it. To save 145 * setup/teardown time, a client of Camera can pass an initialized Camera 146 * object to another process. This method is used to unlock the Camera 147 * object before handing off the Camera object to the other process. 148 149 * Returns 0 if unlock was successful. 150 * 151 * FIXME: Unhide after approval 152 * @hide 153 */ 154 public native final int unlock(); 155 156 /** 157 * Sets the SurfaceHolder to be used for a picture preview. If the surface 158 * changed since the last call, the screen will blank. Nothing happens 159 * if the same surface is re-set. 160 * 161 * @param holder the SurfaceHolder upon which to place the picture preview 162 * @throws IOException if the method fails. 163 */ 164 public final void setPreviewDisplay(SurfaceHolder holder) throws IOException { 165 if (holder != null) { 166 setPreviewDisplay(holder.getSurface()); 167 } else { 168 setPreviewDisplay((Surface)null); 169 } 170 } 171 172 private native final void setPreviewDisplay(Surface surface); 173 174 /** 175 * Used to get a copy of each preview frame. 176 */ 177 public interface PreviewCallback 178 { 179 /** 180 * The callback that delivers the preview frames. 181 * 182 * @param data The contents of the preview frame in {@link 183 * android.hardware.Camera.Parameters#getPreviewFormat()} 184 * format. If {@link 185 * android.hardware.Camera.Parameters#setPreviewFormat()} 186 * is never called, the default will be the YCbCr_420_SP 187 * (NV21) format. 188 * @param camera The Camera service object. 189 */ 190 void onPreviewFrame(byte[] data, Camera camera); 191 }; 192 193 /** 194 * Start drawing preview frames to the surface. 195 */ 196 public native final void startPreview(); 197 198 /** 199 * Stop drawing preview frames to the surface. 200 */ 201 public native final void stopPreview(); 202 203 /** 204 * Return current preview state. 205 * 206 * FIXME: Unhide before release 207 * @hide 208 */ 209 public native final boolean previewEnabled(); 210 211 /** 212 * Can be called at any time to instruct the camera to use a callback for 213 * each preview frame in addition to displaying it. 214 * 215 * @param cb A callback object that receives a copy of each preview frame. 216 * Pass null to stop receiving callbacks at any time. 217 */ 218 public final void setPreviewCallback(PreviewCallback cb) { 219 mPreviewCallback = cb; 220 mOneShot = false; 221 setHasPreviewCallback(cb != null, false); 222 } 223 224 /** 225 * Installs a callback to retrieve a single preview frame, after which the 226 * callback is cleared. 227 * 228 * @param cb A callback object that receives a copy of the preview frame. 229 */ 230 public final void setOneShotPreviewCallback(PreviewCallback cb) { 231 if (cb != null) { 232 mPreviewCallback = cb; 233 mOneShot = true; 234 setHasPreviewCallback(true, true); 235 } 236 } 237 238 private native final void setHasPreviewCallback(boolean installed, boolean oneshot); 239 240 private class EventHandler extends Handler 241 { 242 private Camera mCamera; 243 244 public EventHandler(Camera c, Looper looper) { 245 super(looper); 246 mCamera = c; 247 } 248 249 @Override 250 public void handleMessage(Message msg) { 251 switch(msg.what) { 252 case CAMERA_MSG_SHUTTER: 253 if (mShutterCallback != null) { 254 mShutterCallback.onShutter(); 255 } 256 return; 257 258 case CAMERA_MSG_RAW_IMAGE: 259 if (mRawImageCallback != null) { 260 mRawImageCallback.onPictureTaken((byte[])msg.obj, mCamera); 261 } 262 return; 263 264 case CAMERA_MSG_COMPRESSED_IMAGE: 265 if (mJpegCallback != null) { 266 mJpegCallback.onPictureTaken((byte[])msg.obj, mCamera); 267 } 268 return; 269 270 case CAMERA_MSG_PREVIEW_FRAME: 271 if (mPreviewCallback != null) { 272 mPreviewCallback.onPreviewFrame((byte[])msg.obj, mCamera); 273 if (mOneShot) { 274 mPreviewCallback = null; 275 } 276 } 277 return; 278 279 case CAMERA_MSG_POSTVIEW_FRAME: 280 if (mPostviewCallback != null) { 281 mPostviewCallback.onPictureTaken((byte[])msg.obj, mCamera); 282 } 283 return; 284 285 case CAMERA_MSG_FOCUS: 286 if (mAutoFocusCallback != null) { 287 mAutoFocusCallback.onAutoFocus(msg.arg1 == 0 ? false : true, mCamera); 288 } 289 return; 290 291 case CAMERA_MSG_ZOOM: 292 if (mZoomCallback != null) { 293 mZoomCallback.onZoomUpdate(msg.arg1, mCamera); 294 } 295 return; 296 297 case CAMERA_MSG_ERROR : 298 Log.e(TAG, "Error " + msg.arg1); 299 if (mErrorCallback != null) { 300 mErrorCallback.onError(msg.arg1, mCamera); 301 } 302 return; 303 304 default: 305 Log.e(TAG, "Unknown message type " + msg.what); 306 return; 307 } 308 } 309 } 310 311 private static void postEventFromNative(Object camera_ref, 312 int what, int arg1, int arg2, Object obj) 313 { 314 Camera c = (Camera)((WeakReference)camera_ref).get(); 315 if (c == null) 316 return; 317 318 if (c.mEventHandler != null) { 319 Message m = c.mEventHandler.obtainMessage(what, arg1, arg2, obj); 320 c.mEventHandler.sendMessage(m); 321 } 322 } 323 324 /** 325 * Handles the callback for the camera auto focus. 326 */ 327 public interface AutoFocusCallback 328 { 329 /** 330 * Callback for the camera auto focus. If the camera does not support 331 * auto-focus and autoFocus is called, onAutoFocus will be called 332 * immediately with success. 333 * 334 * @param success true if focus was successful, false if otherwise 335 * @param camera the Camera service object 336 */ 337 void onAutoFocus(boolean success, Camera camera); 338 }; 339 340 /** 341 * Starts auto-focus function and registers a callback function to run when 342 * camera is focused. Only valid after startPreview() has been called. If 343 * the camera does not support auto-focus, it is a no-op and {@link 344 * AutoFocusCallback#onAutoFocus} callback will be called immediately. 345 * 346 * @param cb the callback to run 347 */ 348 public final void autoFocus(AutoFocusCallback cb) 349 { 350 mAutoFocusCallback = cb; 351 native_autoFocus(); 352 } 353 private native final void native_autoFocus(); 354 355 /** 356 * An interface which contains a callback for the shutter closing after taking a picture. 357 */ 358 public interface ShutterCallback 359 { 360 /** 361 * Can be used to play a shutter sound as soon as the image has been captured, but before 362 * the data is available. 363 */ 364 void onShutter(); 365 } 366 367 /** 368 * Handles the callback for when a picture is taken. 369 */ 370 public interface PictureCallback { 371 /** 372 * Callback for when a picture is taken. 373 * 374 * @param data a byte array of the picture data 375 * @param camera the Camera service object 376 */ 377 void onPictureTaken(byte[] data, Camera camera); 378 }; 379 380 /** 381 * Triggers an asynchronous image capture. The camera service will initiate 382 * a series of callbacks to the application as the image capture progresses. 383 * The shutter callback occurs after the image is captured. This can be used 384 * to trigger a sound to let the user know that image has been captured. The 385 * raw callback occurs when the raw image data is available (NOTE: the data 386 * may be null if the hardware does not have enough memory to make a copy). 387 * The jpeg callback occurs when the compressed image is available. If the 388 * application does not need a particular callback, a null can be passed 389 * instead of a callback method. 390 * 391 * @param shutter callback after the image is captured, may be null 392 * @param raw callback with raw image data, may be null 393 * @param jpeg callback with jpeg image data, may be null 394 */ 395 public final void takePicture(ShutterCallback shutter, PictureCallback raw, 396 PictureCallback jpeg) { 397 takePicture(shutter, raw, null, jpeg); 398 } 399 private native final void native_takePicture(); 400 401 /** 402 * Triggers an asynchronous image capture. The camera service will initiate 403 * a series of callbacks to the application as the image capture progresses. 404 * The shutter callback occurs after the image is captured. This can be used 405 * to trigger a sound to let the user know that image has been captured. The 406 * raw callback occurs when the raw image data is available (NOTE: the data 407 * may be null if the hardware does not have enough memory to make a copy). 408 * The postview callback occurs when a scaled, fully processed postview 409 * image is available (NOTE: not all hardware supports this). The jpeg 410 * callback occurs when the compressed image is available. If the 411 * application does not need a particular callback, a null can be passed 412 * instead of a callback method. 413 * 414 * @param shutter callback after the image is captured, may be null 415 * @param raw callback with raw image data, may be null 416 * @param postview callback with postview image data, may be null 417 * @param jpeg callback with jpeg image data, may be null 418 */ 419 public final void takePicture(ShutterCallback shutter, PictureCallback raw, 420 PictureCallback postview, PictureCallback jpeg) { 421 mShutterCallback = shutter; 422 mRawImageCallback = raw; 423 mPostviewCallback = postview; 424 mJpegCallback = jpeg; 425 native_takePicture(); 426 } 427 428 /** 429 * Handles the zoom callback. 430 */ 431 public interface ZoomCallback 432 { 433 /** 434 * Callback for zoom updates 435 * @param zoomLevel new zoom level in 1/1000 increments, 436 * e.g. a zoom of 3.2x is stored as 3200. Accuracy of the 437 * value is dependent on the hardware implementation. Not 438 * all devices will generate this callback. 439 * @param camera the Camera service object 440 */ 441 void onZoomUpdate(int zoomLevel, Camera camera); 442 }; 443 444 /** 445 * Registers a callback to be invoked when the zoom 446 * level is updated by the camera driver. 447 * @param cb the callback to run 448 */ 449 public final void setZoomCallback(ZoomCallback cb) 450 { 451 mZoomCallback = cb; 452 } 453 454 // These match the enum in include/ui/Camera.h 455 /** Unspecified camerar error. @see #ErrorCallback */ 456 public static final int CAMERA_ERROR_UNKNOWN = 1; 457 /** Media server died. In this case, the application must release the 458 * Camera object and instantiate a new one. @see #ErrorCallback */ 459 public static final int CAMERA_ERROR_SERVER_DIED = 100; 460 461 /** 462 * Handles the camera error callback. 463 */ 464 public interface ErrorCallback 465 { 466 /** 467 * Callback for camera errors. 468 * @param error error code: 469 * <ul> 470 * <li>{@link #CAMERA_ERROR_UNKNOWN} 471 * <li>{@link #CAMERA_ERROR_SERVER_DIED} 472 * </ul> 473 * @param camera the Camera service object 474 */ 475 void onError(int error, Camera camera); 476 }; 477 478 /** 479 * Registers a callback to be invoked when an error occurs. 480 * @param cb the callback to run 481 */ 482 public final void setErrorCallback(ErrorCallback cb) 483 { 484 mErrorCallback = cb; 485 } 486 487 private native final void native_setParameters(String params); 488 private native final String native_getParameters(); 489 490 /** 491 * Sets the Parameters for pictures from this Camera service. 492 * 493 * @param params the Parameters to use for this Camera service 494 */ 495 public void setParameters(Parameters params) { 496 native_setParameters(params.flatten()); 497 } 498 499 /** 500 * Returns the picture Parameters for this Camera service. 501 */ 502 public Parameters getParameters() { 503 Parameters p = new Parameters(); 504 String s = native_getParameters(); 505 p.unflatten(s); 506 return p; 507 } 508 509 /** 510 * Handles the picture size (dimensions). 511 */ 512 public class Size { 513 /** 514 * Sets the dimensions for pictures. 515 * 516 * @param w the photo width (pixels) 517 * @param h the photo height (pixels) 518 */ 519 public Size(int w, int h) { 520 width = w; 521 height = h; 522 } 523 /** width of the picture */ 524 public int width; 525 /** height of the picture */ 526 public int height; 527 }; 528 529 /** 530 * Handles the parameters for pictures created by a Camera service. 531 * 532 * <p>To make camera parameters take effect, applications have to call 533 * Camera.setParameters. For example, after setWhiteBalance is called, white 534 * balance is not changed until Camera.setParameters() is called. 535 * 536 * <p>Different devices may have different camera capabilities, such as 537 * picture size or flash modes. The application should query the camera 538 * capabilities before setting parameters. For example, the application 539 * should call getSupportedColorEffects before calling setEffect. If the 540 * camera does not support color effects, getSupportedColorEffects will 541 * return null. 542 */ 543 public class Parameters { 544 // Parameter keys to communicate with the camera driver. 545 private static final String KEY_PREVIEW_SIZE = "preview-size"; 546 private static final String KEY_PREVIEW_FORMAT = "preview-format"; 547 private static final String KEY_PREVIEW_FRAME_RATE = "preview-frame-rate"; 548 private static final String KEY_PICTURE_SIZE = "picture-size"; 549 private static final String KEY_PICTURE_FORMAT = "picture-format"; 550 private static final String KEY_JPEG_THUMBNAIL_WIDTH = "jpeg-thumbnail-width"; 551 private static final String KEY_JPEG_THUMBNAIL_HEIGHT = "jpeg-thumbnail-height"; 552 private static final String KEY_JPEG_THUMBNAIL_QUALITY = "jpeg-thumbnail-quality"; 553 private static final String KEY_JPEG_QUALITY = "jpeg-quality"; 554 private static final String KEY_ROTATION = "rotation"; 555 private static final String KEY_GPS_LATITUDE = "gps-latitude"; 556 private static final String KEY_GPS_LONGITUDE = "gps-longitude"; 557 private static final String KEY_GPS_ALTITUDE = "gps-altitude"; 558 private static final String KEY_GPS_TIMESTAMP = "gps-timestamp"; 559 private static final String KEY_WHITE_BALANCE = "whitebalance"; 560 private static final String KEY_EFFECT = "effect"; 561 private static final String KEY_ANTIBANDING = "antibanding"; 562 private static final String KEY_SCENE_MODE = "scene-mode"; 563 private static final String KEY_FLASH_MODE = "flash-mode"; 564 // Parameter key suffix for supported values. 565 private static final String SUPPORTED_VALUES_SUFFIX = "-values"; 566 567 // Values for white balance settings. 568 public static final String WHITE_BALANCE_AUTO = "auto"; 569 public static final String WHITE_BALANCE_INCANDESCENT = "incandescent"; 570 public static final String WHITE_BALANCE_FLUORESCENT = "fluorescent"; 571 public static final String WHITE_BALANCE_WARM_FLUORESCENT = "warm-fluorescent"; 572 public static final String WHITE_BALANCE_DAYLIGHT = "daylight"; 573 public static final String WHITE_BALANCE_CLOUDY_DAYLIGHT = "cloudy-daylight"; 574 public static final String WHITE_BALANCE_TWILIGHT = "twilight"; 575 public static final String WHITE_BALANCE_SHADE = "shade"; 576 577 // Values for color effect settings. 578 public static final String EFFECT_NONE = "none"; 579 public static final String EFFECT_MONO = "mono"; 580 public static final String EFFECT_NEGATIVE = "negative"; 581 public static final String EFFECT_SOLARIZE = "solarize"; 582 public static final String EFFECT_SEPIA = "sepia"; 583 public static final String EFFECT_POSTERIZE = "posterize"; 584 public static final String EFFECT_WHITEBOARD = "whiteboard"; 585 public static final String EFFECT_BLACKBOARD = "blackboard"; 586 public static final String EFFECT_AQUA = "aqua"; 587 588 // Values for antibanding settings. 589 public static final String ANTIBANDING_AUTO = "auto"; 590 public static final String ANTIBANDING_50HZ = "50hz"; 591 public static final String ANTIBANDING_60HZ = "60hz"; 592 public static final String ANTIBANDING_OFF = "off"; 593 594 // Values for flash mode settings. 595 /** 596 * Flash will not be fired. 597 */ 598 public static final String FLASH_MODE_OFF = "off"; 599 /** 600 * Flash will be fired automatically when required. The timing is 601 * decided by camera driver. 602 */ 603 public static final String FLASH_MODE_AUTO = "auto"; 604 /** 605 * Flash will always be fired. The timing is decided by camera driver. 606 */ 607 public static final String FLASH_MODE_ON = "on"; 608 /** 609 * Flash will be fired in red-eye reduction mode. 610 */ 611 public static final String FLASH_MODE_RED_EYE = "red-eye"; 612 613 // Values for scene mode settings. 614 public static final String SCENE_MODE_AUTO = "auto"; 615 public static final String SCENE_MODE_ACTION = "action"; 616 public static final String SCENE_MODE_PORTRAIT = "portrait"; 617 public static final String SCENE_MODE_LANDSCAPE = "landscape"; 618 public static final String SCENE_MODE_NIGHT = "night"; 619 public static final String SCENE_MODE_NIGHT_PORTRAIT = "night-portrait"; 620 public static final String SCENE_MODE_THEATRE = "theatre"; 621 public static final String SCENE_MODE_BEACH = "beach"; 622 public static final String SCENE_MODE_SNOW = "snow"; 623 public static final String SCENE_MODE_SUNSET = "sunset"; 624 public static final String SCENE_MODE_STEADYPHOTO = "steadyphoto"; 625 public static final String SCENE_MODE_FIREWORKS = "fireworks"; 626 public static final String SCENE_MODE_SPORTS = "sports"; 627 public static final String SCENE_MODE_PARTY = "party"; 628 public static final String SCENE_MODE_CANDLELIGHT = "candlelight"; 629 630 // Formats for setPreviewFormat and setPictureFormat. 631 private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp"; 632 private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp"; 633 private static final String PIXEL_FORMAT_RGB565 = "rgb565"; 634 private static final String PIXEL_FORMAT_JPEG = "jpeg"; 635 636 private HashMap<String, String> mMap; 637 638 private Parameters() { 639 mMap = new HashMap<String, String>(); 640 } 641 642 /** 643 * Writes the current Parameters to the log. 644 * @hide 645 * @deprecated 646 */ 647 public void dump() { 648 Log.e(TAG, "dump: size=" + mMap.size()); 649 for (String k : mMap.keySet()) { 650 Log.e(TAG, "dump: " + k + "=" + mMap.get(k)); 651 } 652 } 653 654 /** 655 * Creates a single string with all the parameters set in 656 * this Parameters object. 657 * <p>The {@link #unflatten(String)} method does the reverse.</p> 658 * 659 * @return a String with all values from this Parameters object, in 660 * semi-colon delimited key-value pairs 661 */ 662 public String flatten() { 663 StringBuilder flattened = new StringBuilder(); 664 for (String k : mMap.keySet()) { 665 flattened.append(k); 666 flattened.append("="); 667 flattened.append(mMap.get(k)); 668 flattened.append(";"); 669 } 670 // chop off the extra semicolon at the end 671 flattened.deleteCharAt(flattened.length()-1); 672 return flattened.toString(); 673 } 674 675 /** 676 * Takes a flattened string of parameters and adds each one to 677 * this Parameters object. 678 * <p>The {@link #flatten()} method does the reverse.</p> 679 * 680 * @param flattened a String of parameters (key-value paired) that 681 * are semi-colon delimited 682 */ 683 public void unflatten(String flattened) { 684 mMap.clear(); 685 686 StringTokenizer tokenizer = new StringTokenizer(flattened, ";"); 687 while (tokenizer.hasMoreElements()) { 688 String kv = tokenizer.nextToken(); 689 int pos = kv.indexOf('='); 690 if (pos == -1) { 691 continue; 692 } 693 String k = kv.substring(0, pos); 694 String v = kv.substring(pos + 1); 695 mMap.put(k, v); 696 } 697 } 698 699 public void remove(String key) { 700 mMap.remove(key); 701 } 702 703 /** 704 * Sets a String parameter. 705 * 706 * @param key the key name for the parameter 707 * @param value the String value of the parameter 708 */ 709 public void set(String key, String value) { 710 if (key.indexOf('=') != -1 || key.indexOf(';') != -1) { 711 Log.e(TAG, "Key \"" + key + "\" contains invalid character (= or ;)"); 712 return; 713 } 714 if (value.indexOf('=') != -1 || value.indexOf(';') != -1) { 715 Log.e(TAG, "Value \"" + value + "\" contains invalid character (= or ;)"); 716 return; 717 } 718 719 mMap.put(key, value); 720 } 721 722 /** 723 * Sets an integer parameter. 724 * 725 * @param key the key name for the parameter 726 * @param value the int value of the parameter 727 */ 728 public void set(String key, int value) { 729 mMap.put(key, Integer.toString(value)); 730 } 731 732 /** 733 * Returns the value of a String parameter. 734 * 735 * @param key the key name for the parameter 736 * @return the String value of the parameter 737 */ 738 public String get(String key) { 739 return mMap.get(key); 740 } 741 742 /** 743 * Returns the value of an integer parameter. 744 * 745 * @param key the key name for the parameter 746 * @return the int value of the parameter 747 */ 748 public int getInt(String key) { 749 return Integer.parseInt(mMap.get(key)); 750 } 751 752 /** 753 * Sets the dimensions for preview pictures. 754 * 755 * @param width the width of the pictures, in pixels 756 * @param height the height of the pictures, in pixels 757 */ 758 public void setPreviewSize(int width, int height) { 759 String v = Integer.toString(width) + "x" + Integer.toString(height); 760 set(KEY_PREVIEW_SIZE, v); 761 } 762 763 /** 764 * Returns the dimensions setting for preview pictures. 765 * 766 * @return a Size object with the height and width setting 767 * for the preview picture 768 */ 769 public Size getPreviewSize() { 770 String pair = get(KEY_PREVIEW_SIZE); 771 return strToSize(pair); 772 } 773 774 /** 775 * Gets the supported preview sizes. 776 * 777 * @return a List of Size object. null if preview size setting is not 778 * supported. 779 */ 780 public List<Size> getSupportedPreviewSizes() { 781 String str = get(KEY_PREVIEW_SIZE + SUPPORTED_VALUES_SUFFIX); 782 return splitSize(str); 783 } 784 785 /** 786 * Sets the dimensions for EXIF thumbnail in Jpeg picture. 787 * 788 * @param width the width of the thumbnail, in pixels 789 * @param height the height of the thumbnail, in pixels 790 */ 791 public void setJpegThumbnailSize(int width, int height) { 792 set(KEY_JPEG_THUMBNAIL_WIDTH, width); 793 set(KEY_JPEG_THUMBNAIL_HEIGHT, height); 794 } 795 796 /** 797 * Returns the dimensions for EXIF thumbnail in Jpeg picture. 798 * 799 * @return a Size object with the height and width setting for the EXIF 800 * thumbnails 801 */ 802 public Size getJpegThumbnailSize() { 803 return new Size(getInt(KEY_JPEG_THUMBNAIL_WIDTH), 804 getInt(KEY_JPEG_THUMBNAIL_HEIGHT)); 805 } 806 807 /** 808 * Sets the quality of the EXIF thumbnail in Jpeg picture. 809 * 810 * @param quality the JPEG quality of the EXIF thumbnail. The range is 1 811 * to 100, with 100 being the best. 812 */ 813 public void setJpegThumbnailQuality(int quality) { 814 set(KEY_JPEG_THUMBNAIL_QUALITY, quality); 815 } 816 817 /** 818 * Returns the quality setting for the EXIF thumbnail in Jpeg picture. 819 * 820 * @return the JPEG quality setting of the EXIF thumbnail. 821 */ 822 public int getJpegThumbnailQuality() { 823 return getInt(KEY_JPEG_THUMBNAIL_QUALITY); 824 } 825 826 /** 827 * Sets Jpeg quality of captured picture. 828 * 829 * @param quality the JPEG quality of captured picture. The range is 1 830 * to 100, with 100 being the best. 831 */ 832 public void setJpegQuality(int quality) { 833 set(KEY_JPEG_QUALITY, quality); 834 } 835 836 /** 837 * Returns the quality setting for the JPEG picture. 838 * 839 * @return the JPEG picture quality setting. 840 */ 841 public int getJpegQuality() { 842 return getInt(KEY_JPEG_QUALITY); 843 } 844 845 /** 846 * Sets the rate at which preview frames are received. 847 * 848 * @param fps the frame rate (frames per second) 849 */ 850 public void setPreviewFrameRate(int fps) { 851 set(KEY_PREVIEW_FRAME_RATE, fps); 852 } 853 854 /** 855 * Returns the setting for the rate at which preview frames 856 * are received. 857 * 858 * @return the frame rate setting (frames per second) 859 */ 860 public int getPreviewFrameRate() { 861 return getInt(KEY_PREVIEW_FRAME_RATE); 862 } 863 864 /** 865 * Gets the supported preview frame rates. 866 * 867 * @return a List of Integer objects (preview frame rates). null if 868 * preview frame rate setting is not supported. 869 */ 870 public List<Integer> getSupportedPreviewFrameRates() { 871 String str = get(KEY_PREVIEW_FRAME_RATE + SUPPORTED_VALUES_SUFFIX); 872 return splitInt(str); 873 } 874 875 /** 876 * Sets the image format for preview pictures. If this is never called, 877 * the default will be the YCbCr_420_SP (NV21) format. 878 * 879 * @param pixel_format the desired preview picture format 880 * (<var>PixelFormat.YCbCr_420_SP (NV21)</var>, 881 * <var>PixelFormat.RGB_565</var>, or 882 * <var>PixelFormat.JPEG</var>) 883 * @see android.graphics.PixelFormat 884 */ 885 public void setPreviewFormat(int pixel_format) { 886 String s = cameraFormatForPixelFormat(pixel_format); 887 if (s == null) { 888 throw new IllegalArgumentException( 889 "Invalid pixel_format=" + pixel_format); 890 } 891 892 set(KEY_PREVIEW_FORMAT, s); 893 } 894 895 /** 896 * Returns the image format for preview pictures got from 897 * {@link PreviewCallback}. 898 * 899 * @return the PixelFormat int representing the preview picture format 900 * @see android.graphics.PixelFormat 901 */ 902 public int getPreviewFormat() { 903 return pixelFormatForCameraFormat(get(KEY_PREVIEW_FORMAT)); 904 } 905 906 /** 907 * Gets the supported preview formats. 908 * 909 * @return a List of Integer objects. null if preview format setting is 910 * not supported. 911 */ 912 public List<Integer> getSupportedPreviewFormats() { 913 String str = get(KEY_PREVIEW_FORMAT + SUPPORTED_VALUES_SUFFIX); 914 return splitInt(str); 915 } 916 917 /** 918 * Sets the dimensions for pictures. 919 * 920 * @param width the width for pictures, in pixels 921 * @param height the height for pictures, in pixels 922 */ 923 public void setPictureSize(int width, int height) { 924 String v = Integer.toString(width) + "x" + Integer.toString(height); 925 set(KEY_PICTURE_SIZE, v); 926 } 927 928 /** 929 * Returns the dimension setting for pictures. 930 * 931 * @return a Size object with the height and width setting 932 * for pictures 933 */ 934 public Size getPictureSize() { 935 String pair = get(KEY_PICTURE_SIZE); 936 return strToSize(pair); 937 } 938 939 /** 940 * Gets the supported picture sizes. 941 * 942 * @return a List of Size objects. null if picture size setting is not 943 * supported. 944 */ 945 public List<Size> getSupportedPictureSizes() { 946 String str = get(KEY_PICTURE_SIZE + SUPPORTED_VALUES_SUFFIX); 947 return splitSize(str); 948 } 949 950 /** 951 * Sets the image format for pictures. 952 * 953 * @param pixel_format the desired picture format 954 * (<var>PixelFormat.YCbCr_420_SP (NV21)</var>, 955 * <var>PixelFormat.RGB_565</var>, or 956 * <var>PixelFormat.JPEG</var>) 957 * @see android.graphics.PixelFormat 958 */ 959 public void setPictureFormat(int pixel_format) { 960 String s = cameraFormatForPixelFormat(pixel_format); 961 if (s == null) { 962 throw new IllegalArgumentException( 963 "Invalid pixel_format=" + pixel_format); 964 } 965 966 set(KEY_PICTURE_FORMAT, s); 967 } 968 969 /** 970 * Returns the image format for pictures. 971 * 972 * @return the PixelFormat int representing the picture format 973 */ 974 public int getPictureFormat() { 975 return pixelFormatForCameraFormat(get(KEY_PICTURE_FORMAT)); 976 } 977 978 /** 979 * Gets the supported picture formats. 980 * 981 * @return a List of Integer objects (values are PixelFormat.XXX). null 982 * if picture setting is not supported. 983 */ 984 public List<Integer> getSupportedPictureFormats() { 985 String str = get(KEY_PICTURE_SIZE + SUPPORTED_VALUES_SUFFIX); 986 return splitInt(str); 987 } 988 989 private String cameraFormatForPixelFormat(int pixel_format) { 990 switch(pixel_format) { 991 case PixelFormat.YCbCr_422_SP: return PIXEL_FORMAT_YUV422SP; 992 case PixelFormat.YCbCr_420_SP: return PIXEL_FORMAT_YUV420SP; 993 case PixelFormat.RGB_565: return PIXEL_FORMAT_RGB565; 994 case PixelFormat.JPEG: return PIXEL_FORMAT_JPEG; 995 default: return null; 996 } 997 } 998 999 private int pixelFormatForCameraFormat(String format) { 1000 if (format == null) 1001 return PixelFormat.UNKNOWN; 1002 1003 if (format.equals(PIXEL_FORMAT_YUV422SP)) 1004 return PixelFormat.YCbCr_422_SP; 1005 1006 if (format.equals(PIXEL_FORMAT_YUV420SP)) 1007 return PixelFormat.YCbCr_420_SP; 1008 1009 if (format.equals(PIXEL_FORMAT_RGB565)) 1010 return PixelFormat.RGB_565; 1011 1012 if (format.equals(PIXEL_FORMAT_JPEG)) 1013 return PixelFormat.JPEG; 1014 1015 return PixelFormat.UNKNOWN; 1016 } 1017 1018 /** 1019 * Sets the orientation of the device in degrees, which instructs the 1020 * camera driver to rotate the picture and thumbnail, in order to match 1021 * what the user sees from the viewfinder. For example, suppose the 1022 * natural position of the device is landscape. If the user takes a 1023 * picture in landscape mode in 2048x1536 resolution, the rotation 1024 * should be set to 0. If the user rotates the phone 90 degrees 1025 * clockwise, the rotation should be set to 90. Applications can use 1026 * {@link android.view.OrientationEventListener} to set this parameter. 1027 * 1028 * Since the picture is rotated, the orientation in the EXIF header is 1029 * missing or always 1 (row #0 is top and column #0 is left side). 1030 * 1031 * @param rotation The orientation of the device in degrees. Rotation 1032 * can only be 0, 90, 180 or 270. 1033 * @throws IllegalArgumentException if rotation value is invalid. 1034 * @see android.view.OrientationEventListener 1035 */ 1036 public void setRotation(int rotation) { 1037 if (rotation == 0 || rotation == 90 || rotation == 180 1038 || rotation == 270) { 1039 set(KEY_ROTATION, Integer.toString(rotation)); 1040 } else { 1041 throw new IllegalArgumentException( 1042 "Invalid rotation=" + rotation); 1043 } 1044 } 1045 1046 /** 1047 * Sets GPS latitude coordinate. This will be stored in JPEG EXIF 1048 * header. 1049 * 1050 * @param latitude GPS latitude coordinate. 1051 */ 1052 public void setGpsLatitude(double latitude) { 1053 set(KEY_GPS_LATITUDE, Double.toString(latitude)); 1054 } 1055 1056 /** 1057 * Sets GPS longitude coordinate. This will be stored in JPEG EXIF 1058 * header. 1059 * 1060 * @param longitude GPS longitude coordinate. 1061 */ 1062 public void setGpsLongitude(double longitude) { 1063 set(KEY_GPS_LONGITUDE, Double.toString(longitude)); 1064 } 1065 1066 /** 1067 * Sets GPS altitude. This will be stored in JPEG EXIF header. 1068 * 1069 * @param altitude GPS altitude in meters. 1070 */ 1071 public void setGpsAltitude(double altitude) { 1072 set(KEY_GPS_ALTITUDE, Double.toString(altitude)); 1073 } 1074 1075 /** 1076 * Sets GPS timestamp. This will be stored in JPEG EXIF header. 1077 * 1078 * @param timestamp GPS timestamp (UTC in seconds since January 1, 1079 * 1970). 1080 */ 1081 public void setGpsTimestamp(long timestamp) { 1082 set(KEY_GPS_TIMESTAMP, Long.toString(timestamp)); 1083 } 1084 1085 /** 1086 * Removes GPS latitude, longitude, altitude, and timestamp from the 1087 * parameters. 1088 */ 1089 public void removeGpsData() { 1090 remove(KEY_GPS_LATITUDE); 1091 remove(KEY_GPS_LONGITUDE); 1092 remove(KEY_GPS_ALTITUDE); 1093 remove(KEY_GPS_TIMESTAMP); 1094 } 1095 1096 /** 1097 * Gets the current white balance setting. 1098 * 1099 * @return one of WHITE_BALANCE_XXX string constant. null if white 1100 * balance setting is not supported. 1101 */ 1102 public String getWhiteBalance() { 1103 return get(KEY_WHITE_BALANCE); 1104 } 1105 1106 /** 1107 * Sets the white balance. 1108 * 1109 * @param value WHITE_BALANCE_XXX string constant. 1110 */ 1111 public void setWhiteBalance(String value) { 1112 set(KEY_WHITE_BALANCE, value); 1113 } 1114 1115 /** 1116 * Gets the supported white balance. 1117 * 1118 * @return a List of WHITE_BALANCE_XXX string constants. null if white 1119 * balance setting is not supported. 1120 */ 1121 public List<String> getSupportedWhiteBalance() { 1122 String str = get(KEY_WHITE_BALANCE + SUPPORTED_VALUES_SUFFIX); 1123 return split(str); 1124 } 1125 1126 /** 1127 * Gets the current color effect setting. 1128 * 1129 * @return one of EFFECT_XXX string constant. null if color effect 1130 * setting is not supported. 1131 */ 1132 public String getColorEffect() { 1133 return get(KEY_EFFECT); 1134 } 1135 1136 /** 1137 * Sets the current color effect setting. 1138 * 1139 * @param value EFFECT_XXX string constants. 1140 */ 1141 public void setColorEffect(String value) { 1142 set(KEY_EFFECT, value); 1143 } 1144 1145 /** 1146 * Gets the supported color effects. 1147 * 1148 * @return a List of EFFECT_XXX string constants. null if color effect 1149 * setting is not supported. 1150 */ 1151 public List<String> getSupportedColorEffects() { 1152 String str = get(KEY_EFFECT + SUPPORTED_VALUES_SUFFIX); 1153 return split(str); 1154 } 1155 1156 1157 /** 1158 * Gets the current antibanding setting. 1159 * 1160 * @return one of ANTIBANDING_XXX string constant. null if antibanding 1161 * setting is not supported. 1162 */ 1163 public String getAntibanding() { 1164 return get(KEY_ANTIBANDING); 1165 } 1166 1167 /** 1168 * Sets the antibanding. 1169 * 1170 * @param antibanding ANTIBANDING_XXX string constant. 1171 */ 1172 public void setAntibanding(String antibanding) { 1173 set(KEY_ANTIBANDING, antibanding); 1174 } 1175 1176 /** 1177 * Gets the supported antibanding values. 1178 * 1179 * @return a List of ANTIBANDING_XXX string constants. null if 1180 * antibanding setting is not supported. 1181 */ 1182 public List<String> getSupportedAntibanding() { 1183 String str = get(KEY_ANTIBANDING + SUPPORTED_VALUES_SUFFIX); 1184 return split(str); 1185 } 1186 1187 /** 1188 * Gets the current scene mode setting. 1189 * 1190 * @return one of SCENE_MODE_XXX string constant. null if scene mode 1191 * setting is not supported. 1192 */ 1193 public String getSceneMode() { 1194 return get(KEY_SCENE_MODE); 1195 } 1196 1197 /** 1198 * Sets the scene mode. 1199 * 1200 * @param value SCENE_MODE_XXX string constants. 1201 */ 1202 public void setSceneMode(String value) { 1203 set(KEY_SCENE_MODE, value); 1204 } 1205 1206 /** 1207 * Gets the supported scene modes. 1208 * 1209 * @return a List of SCENE_MODE_XXX string constant. null if scene mode 1210 * setting is not supported. 1211 */ 1212 public List<String> getSupportedSceneModes() { 1213 String str = get(KEY_SCENE_MODE + SUPPORTED_VALUES_SUFFIX); 1214 return split(str); 1215 } 1216 1217 /** 1218 * Gets the current flash mode setting. 1219 * 1220 * @return one of FLASH_MODE_XXX string constant. null if flash mode 1221 * setting is not supported. 1222 */ 1223 public String getFlashMode() { 1224 return get(KEY_FLASH_MODE); 1225 } 1226 1227 /** 1228 * Sets the flash mode. 1229 * 1230 * @param value FLASH_MODE_XXX string constants. 1231 */ 1232 public void setFlashMode(String value) { 1233 set(KEY_FLASH_MODE, value); 1234 } 1235 1236 /** 1237 * Gets the supported flash modes. 1238 * 1239 * @return a List of FLASH_MODE_XXX string constants. null if flash mode 1240 * setting is not supported. 1241 */ 1242 public List<String> getSupportedFlashModes() { 1243 String str = get(KEY_FLASH_MODE + SUPPORTED_VALUES_SUFFIX); 1244 return split(str); 1245 } 1246 1247 // Splits a comma delimited string to an ArrayList of String. 1248 // Return null if the passing string is null or the size is 0. 1249 private ArrayList<String> split(String str) { 1250 if (str == null) return null; 1251 1252 // Use StringTokenizer because it is faster than split. 1253 StringTokenizer tokenizer = new StringTokenizer(str, ","); 1254 ArrayList<String> substrings = new ArrayList<String>(); 1255 while (tokenizer.hasMoreElements()) { 1256 substrings.add(tokenizer.nextToken()); 1257 } 1258 return substrings; 1259 } 1260 1261 // Splits a comma delimited string to an ArrayList of Integer. 1262 // Return null if the passing string is null or the size is 0. 1263 private ArrayList<Integer> splitInt(String str) { 1264 if (str == null) return null; 1265 1266 StringTokenizer tokenizer = new StringTokenizer(str, ","); 1267 ArrayList<Integer> substrings = new ArrayList<Integer>(); 1268 while (tokenizer.hasMoreElements()) { 1269 String token = tokenizer.nextToken(); 1270 substrings.add(Integer.parseInt(token)); 1271 } 1272 if (substrings.size() == 0) return null; 1273 return substrings; 1274 } 1275 1276 // Splits a comma delimited string to an ArrayList of Size. 1277 // Return null if the passing string is null or the size is 0. 1278 private ArrayList<Size> splitSize(String str) { 1279 if (str == null) return null; 1280 1281 StringTokenizer tokenizer = new StringTokenizer(str, ","); 1282 ArrayList<Size> sizeList = new ArrayList<Size>(); 1283 while (tokenizer.hasMoreElements()) { 1284 Size size = strToSize(tokenizer.nextToken()); 1285 if (size != null) sizeList.add(size); 1286 } 1287 if (sizeList.size() == 0) return null; 1288 return sizeList; 1289 } 1290 1291 // Parses a string (ex: "480x320") to Size object. 1292 // Return null if the passing string is null. 1293 private Size strToSize(String str) { 1294 if (str == null) return null; 1295 1296 int pos = str.indexOf('x'); 1297 if (pos != -1) { 1298 String width = str.substring(0, pos); 1299 String height = str.substring(pos + 1); 1300 return new Size(Integer.parseInt(width), 1301 Integer.parseInt(height)); 1302 } 1303 Log.e(TAG, "Invalid size parameter string=" + str); 1304 return null; 1305 } 1306 }; 1307} 1308 1309 1310