android开发之camera相关功能
最简单直接了解android camera的方法:
看一下源代码就好了是吧?
后面会对函数做一些说明 做翻译吧
/* * copyright (c) 2008 the android open source project * * licensed under the apache license, version 2.0 (the "license"); * you may not use this file except in compliance with the license. * you may obtain a copy of the license at * *http://www.apache.org/licenses/license-2.0 * * unless required by applicable law or agreed to in writing, software * distributed under the license is distributed on an "as is" basis, * without warranties or conditions of any kind, either express or implied. * see the license for the specific language governing permissions and * limitations under the license. */ package android.hardware; import static android.system.osconstants.*; import android.annotation.sdkconstant; import android.annotation.sdkconstant.sdkconstanttype; import android.app.activitythread; import android.content.context; import android.graphics.imageformat; import android.graphics.point; import android.graphics.rect; import android.graphics.surfacetexture; import android.media.iaudioservice; import android.os.handler; import android.os.ibinder; import android.os.looper; import android.os.message; import android.os.remoteexception; import android.os.servicemanager; import android.renderscript.allocation; import android.renderscript.element; import android.renderscript.rsillegalargumentexception; import android.renderscript.renderscript; import android.renderscript.type; import android.text.textutils; import android.util.log; import android.view.surface; import android.view.surfaceholder; import java.io.ioexception; import java.lang.ref.weakreference; import java.util.arraylist; import java.util.linkedhashmap; import java.util.list; /** * the camera class is used to set image capture settings, start/stop preview, * snap pictures, and retrieve frames for encoding for video. this class is a * client for the camera service, which manages the actual camera hardware. * *
to access the device camera, you must declare the * {@link android.manifest.permission#camera} permission in your android * manifest. also be sure to include the * <uses-feature> * manifest element to declare camera features used by your application. * for example, if you use the camera and auto-focus feature, your manifest * should include the following:
*<uses-permission android:name="android.permission.camera" /> * <uses-feature android:name="android.hardware.camera" /> * <uses-feature android:name="android.hardware.camera.autofocus" />* *
to take pictures with this class, use the following steps:
* *- *
- obtain an instance of camera from {@link #open(int)}. * *
- get existing (default) settings with {@link #getparameters()}. * *
- if necessary, modify the returned {@link camera.parameters} object and call * {@link #setparameters(camera.parameters)}. * *
- call {@link #setdisplayorientation(int)} to ensure correct orientation of preview. * *
- important: pass a fully initialized {@link surfaceholder} to * {@link #setpreviewdisplay(surfaceholder)}. without a surface, the camera * will be unable to start the preview. * *
- important: call {@link #startpreview()} to start updating the * preview surface. preview must be started before you can take a picture. * *
- when you want, call {@link #takepicture(camera.shuttercallback, * camera.picturecallback, camera.picturecallback, camera.picturecallback)} to * capture a photo. wait for the callbacks to provide the actual image data. * *
- after taking a picture, preview display will have stopped. to take more * photos, call {@link #startpreview()} again first. * *
- call {@link #stoppreview()} to stop updating the preview surface. * *
- important: call {@link #release()} to release the camera for * use by other applications. applications should release the camera * immediately in {@link android.app.activity#onpause()} (and re-{@link #open()} * it in {@link android.app.activity#onresume()}). *
to quickly switch to video recording mode, use these steps:
* *- *
- obtain and initialize a camera and start preview as described above. * *
- call {@link #unlock()} to allow the media process to access the camera. * *
- pass the camera to {@link android.media.mediarecorder#setcamera(camera)}. * see {@link android.media.mediarecorder} information about video recording. * *
- when finished recording, call {@link #reconnect()} to re-acquire * and re-lock the camera. * *
- if desired, restart preview and take more photos or videos. * *
- call {@link #stoppreview()} and {@link #release()} as described above. *
this class is not thread-safe, and is meant for use from one event thread. * most long-running operations (preview, focus, photo capture, etc) happen * asynchronously and invoke callbacks as necessary. callbacks will be invoked * on the event thread {@link #open(int)} was called from. this class's methods * must never be called from multiple threads at once.
* *caution: different android-powered devices * may have different hardware specifications, such as megapixel ratings and * auto-focus capabilities. in order for your application to be compatible with * more devices, you should not make assumptions about the device camera * specifications.
* * *developer guides
*for more information about using cameras, read the * camera developer guide.
* * * @deprecated we recommend using the new {@link android.hardware.camera2} api for new * applications. */ @deprecated public class camera { private static final string tag = "camera"; // these match the enums in frameworks/base/include/camera/camera.h private static final int camera_msg_error= 0x001; private static final int camera_msg_shutter = 0x002; private static final int camera_msg_focus= 0x004; private static final int camera_msg_zoom = 0x008; private static final int camera_msg_preview_frame = 0x010; private static final int camera_msg_video_frame= 0x020; private static final int camera_msg_postview_frame= 0x040; private static final int camera_msg_raw_image = 0x080; private static final int camera_msg_compressed_image = 0x100; private static final int camera_msg_raw_image_notify = 0x200; private static final int camera_msg_preview_metadata = 0x400; private static final int camera_msg_focus_move = 0x800; private long mnativecontext; // accessed by native methods private eventhandler meventhandler; private shuttercallback mshuttercallback; private picturecallback mrawimagecallback; private picturecallback mjpegcallback; private previewcallback mpreviewcallback; private boolean musingpreviewallocation; private picturecallback mpostviewcallback; private autofocuscallback mautofocuscallback; private autofocusmovecallback mautofocusmovecallback; private onzoomchangelistener mzoomlistener; private facedetectionlistener mfacelistener; private errorcallback merrorcallback; private boolean moneshot; private boolean mwithbuffer; private boolean mfacedetectionrunning = false; private final object mautofocuscallbacklock = new object(); private static final int no_error = 0; /** * broadcast action: a new picture is taken by the camera, and the entry of * the picture has been added to the media store. * {@link android.content.intent#getdata} is uri of the picture. * *in {@link android.os.build.version_codes#n android n} this broadcast was removed, and * applications are recommended to use * {@link android.app.job.jobinfo.builder jobinfo.builder}.{@link android.app.job.jobinfo.builder#addtriggercontenturi} * instead.
* *in {@link android.os.build.version_codes#o android o} this broadcast has been brought * back, but only for registered receivers. apps that are actively running can * again listen to the broadcast if they want an immediate clear signal about a picture * being taken, however anything doing heavy work (or needing to be launched) as a result of * this should still use jobscheduler.
*/ @sdkconstant(sdkconstanttype.broadcast_intent_action) public static final string action_new_picture = "android.hardware.action.new_picture"; /** * broadcast action: a new video is recorded by the camera, and the entry * of the video has been added to the media store. * {@link android.content.intent#getdata} is uri of the video. * *in {@link android.os.build.version_codes#n android n} this broadcast was removed, and * applications are recommended to use * {@link android.app.job.jobinfo.builder jobinfo.builder}.{@link android.app.job.jobinfo.builder#addtriggercontenturi} * instead.
* *in {@link android.os.build.version_codes#o android o} this broadcast has been brought * back, but only for registered receivers. apps that are actively running can * again listen to the broadcast if they want an immediate clear signal about a video * being taken, however anything doing heavy work (or needing to be launched) as a result of * this should still use jobscheduler.
*/ @sdkconstant(sdkconstanttype.broadcast_intent_action) public static final string action_new_video = "android.hardware.action.new_video"; /** * camera hal device api version 1.0 * @hide */ public static final int camera_hal_api_version_1_0 = 0x100; /** * a constant meaning the normal camera connect/open will be used. */ private static final int camera_hal_api_version_normal_connect = -2; /** * used to indicate hal version un-specified. */ private static final int camera_hal_api_version_unspecified = -1; /** * hardware face detection. it does not use much cpu. */ private static final int camera_face_detection_hw = 0; /** * software face detection. it uses some cpu. */ private static final int camera_face_detection_sw = 1; /** * returns the number of physical cameras available on this device. * * @return total number of accessible camera devices, or 0 if there are no *cameras or an error was encountered enumerating them. */ public native static int getnumberofcameras(); /** * returns the information about a particular camera. * if {@link #getnumberofcameras()} returns n, the valid id is 0 to n-1. * * @throws runtimeexception if an invalid id is provided, or if there is an * error retrieving the information (generally due to a hardware or other * low-level failure). */ public static void getcamerainfo(int cameraid, camerainfo camerainfo) { _getcamerainfo(cameraid, camerainfo); ibinder b = servicemanager.getservice(context.audio_service); iaudioservice audioservice = iaudioservice.stub.asinterface(b); try { if (audioservice.iscamerasoundforced()) { // only set this when sound is forced; otherwise let native code // decide. camerainfo.candisableshuttersound = false; } } catch (remoteexception e) { log.e(tag, "audio service is unavailable for queries"); } } private native static void _getcamerainfo(int cameraid, camerainfo camerainfo); /** * information about a camera * * @deprecated we recommend using the new {@link android.hardware.camera2} api for new * applications. */ @deprecated public static class camerainfo { /** * the facing of the camera is opposite to that of the screen. */ public static final int camera_facing_back = 0; /** * the facing of the camera is the same as that of the screen. */ public static final int camera_facing_front = 1; /** * the direction that the camera faces. it should be * camera_facing_back or camera_facing_front. */ public int facing; /** *the orientation of the camera image. the value is the angle that the * camera image needs to be rotated clockwise so it shows correctly on * the display in its natural orientation. it should be 0, 90, 180, or 270.
* *for example, suppose a device has a naturally tall screen. the * back-facing camera sensor is mounted in landscape. you are looking at * the screen. if the top side of the camera sensor is aligned with the * right edge of the screen in natural orientation, the value should be * 90. if the top side of a front-facing camera sensor is aligned with * the right of the screen, the value should be 270.
* * @see #setdisplayorientation(int) * @see parameters#setrotation(int) * @see parameters#setpreviewsize(int, int) * @see parameters#setpicturesize(int, int) * @see parameters#setjpegthumbnailsize(int, int) */ public int orientation; /** *whether the shutter sound can be disabled.
* *on some devices, the camera shutter sound cannot be turned off * through {@link #enableshuttersound enableshuttersound}. this field * can be used to determine whether a call to disable the shutter sound * will succeed.
* *if this field is set to true, then a call of * {@code enableshuttersound(false)} will be successful. if set to * false, then that call will fail, and the shutter sound will be played * when {@link camera#takepicture takepicture} is called.
*/ public boolean candisableshuttersound; }; /** * creates a new camera object to access a particular hardware camera. if * the same camera is opened by other applications, this will throw a * runtimeexception. * *you must call {@link #release()} when you are done using the camera, * otherwise it will remain locked and be unavailable to other applications. * *
your application should only have one camera object active at a time * for a particular hardware camera. * *
callbacks from other methods are delivered to the event loop of the * thread which called open(). if this thread has no event loop, then * callbacks are delivered to the main application event loop. if there * is no main application event loop, callbacks are not delivered. * *
caution: on some devices, this method may * take a long time to complete. it is best to call this method from a * worker thread (possibly using {@link android.os.asynctask}) to avoid * blocking the main application ui thread. * * @param cameraid the hardware camera to access, between 0 and * {@link #getnumberofcameras()}-1. * @return a new camera object, connected, locked and ready for use. * @throws runtimeexception if opening the camera fails (for example, if the * camera is in use by another process or device policy manager has * disabled the camera). * @see android.app.admin.devicepolicymanager#getcameradisabled(android.content.componentname) */ public static camera open(int cameraid) { return new camera(cameraid); } /** * creates a new camera object to access the first back-facing camera on the * device. if the device does not have a back-facing camera, this returns * null. otherwise acts like the {@link #open(int)} call. * * @return a new camera object for the first back-facing camera, or null if there is no * backfacing camera * @see #open(int) */ public static camera open() { int numberofcameras = getnumberofcameras(); camerainfo camerainfo = new camerainfo(); for (int i = 0; i < numberofcameras; i++) { getcamerainfo(i, camerainfo); if (camerainfo.facing == camerainfo.camera_facing_back) { return new camera(i); } } return null; } /** * creates a new camera object to access a particular hardware camera with * given hal api version. if the same camera is opened by other applications * or the hal api version is not supported by this device, this will throw a * runtimeexception. *
* you must call {@link #release()} when you are done using the camera, * otherwise it will remain locked and be unavailable to other applications. *
* your application should only have one camera object active at a time for * a particular hardware camera. *
* callbacks from other methods are delivered to the event loop of the * thread which called open(). if this thread has no event loop, then * callbacks are delivered to the main application event loop. if there is * no main application event loop, callbacks are not delivered. *
* caution: on some devices, this method may take a long time to * complete. it is best to call this method from a worker thread (possibly * using {@link android.os.asynctask}) to avoid blocking the main * application ui thread. * * @param cameraid the hardware camera to access, between 0 and * {@link #getnumberofcameras()}-1. * @param halversion the hal api version this camera device to be opened as. * @return a new camera object, connected, locked and ready for use. * * @throws illegalargumentexception if the {@code halversion} is invalid * * @throws runtimeexception if opening the camera fails (for example, if the * camera is in use by another process or device policy manager has disabled * the camera). * * @see android.app.admin.devicepolicymanager#getcameradisabled(android.content.componentname) * @see #camera_hal_api_version_1_0 * * @hide */ public static camera openlegacy(int cameraid, int halversion) { if (halversion < camera_hal_api_version_1_0) { throw new illegalargumentexception("invalid hal version " + halversion); } return new camera(cameraid, halversion); } /** * create a legacy camera object. * * @param cameraid the hardware camera to access, between 0 and * {@link #getnumberofcameras()}-1. * @param halversion the hal api version this camera device to be opened as. */ private camera(int cameraid, int halversion) { int err = camerainitversion(cameraid, halversion); if (checkiniterrors(err)) { if (err == -eacces) { throw new runtimeexception("fail to connect to camera service"); } else if (err == -enodev) { throw new runtimeexception("camera initialization failed"); } else if (err == -enosys) { throw new runtimeexception("camera initialization failed because some methods" + " are not implemented"); } else if (err == -eopnotsupp) { throw new runtimeexception("camera initialization failed because the hal" + " version is not supported by this device"); } else if (err == -einval) { throw new runtimeexception("camera initialization failed because the input" + " arugments are invalid"); } else if (err == -ebusy) { throw new runtimeexception("camera initialization failed because the camera" + " device was already opened"); } else if (err == -eusers) { throw new runtimeexception("camera initialization failed because the max" + " number of camera devices were already opened"); } // should never hit this. throw new runtimeexception("unknown camera error"); } } private int camerainitversion(int cameraid, int halversion) { mshuttercallback = null; mrawimagecallback = null; mjpegcallback = null; mpreviewcallback = null; mpostviewcallback = null; musingpreviewallocation = false; mzoomlistener = null; looper looper; if ((looper = looper.mylooper()) != null) { meventhandler = new eventhandler(this, looper); } else if ((looper = looper.getmainlooper()) != null) { meventhandler = new eventhandler(this, looper); } else { meventhandler = null; } return native_setup(new weakreference
* this acts the same as normal except that it will return * the detailed error code if open fails instead of * converting everything into {@code no_init}.
* *intended to use by the camera2 shim only, do not use this for other code.
* * @return a detailed errno error code, or {@code no_error} on success * * @hide */ public int camerainitunspecified(int cameraid) { return camerainitversion(cameraid, camera_hal_api_version_unspecified); } /** used by camera#open, camera#open(int) */ camera(int cameraid) { int err = camerainitnormal(cameraid); if (checkiniterrors(err)) { if (err == -eacces) { throw new runtimeexception("fail to connect to camera service"); } else if (err == -enodev) { throw new runtimeexception("camera initialization failed"); } // should never hit this. throw new runtimeexception("unknown camera error"); } } /** * @hide */ public static boolean checkiniterrors(int err) { return err != no_error; } /** * @hide */ public static camera openuninitialized() { return new camera(); } /** * an empty camera for testing purpose. */ camera() { } @override protected void finalize() { release(); } private native final int native_setup(object camera_this, int cameraid, int halversion, string packagename); private native final void native_release(); /** * disconnects and releases the camera object resources. * *you must call this as soon as you're done with the camera object.
*/ public final void release() { native_release(); mfacedetectionrunning = false; } /** * unlocks the camera to allow another process to access it. * normally, the camera is locked to the process with an active camera * object until {@link #release()} is called. to allow rapid handoff * between processes, you can call this method to release the camera * temporarily for another process to use; once the other process is done * you can call {@link #reconnect()} to reclaim the camera. * *this must be done before calling * {@link android.media.mediarecorder#setcamera(camera)}. this cannot be * called after recording starts. * *
if you are not recording video, you probably do not need this method. * * @throws runtimeexception if the camera cannot be unlocked. */ public native final void unlock(); /** * re-locks the camera to prevent other processes from accessing it. * camera objects are locked by default unless {@link #unlock()} is * called. normally {@link #reconnect()} is used instead. * *
since api level 14, camera is automatically locked for applications in * {@link android.media.mediarecorder#start()}. applications can use the * camera (ex: zoom) after recording starts. there is no need to call this * after recording starts or stops. * *
if you are not recording video, you probably do not need this method. * * @throws runtimeexception if the camera cannot be re-locked (for * example, if the camera is still in use by another process). */ public native final void lock(); /** * reconnects to the camera service after another process used it. * after {@link #unlock()} is called, another process may use the * camera; when the process is done, you must reconnect to the camera, * which will re-acquire the lock and allow you to continue using the * camera. * *
since api level 14, camera is automatically locked for applications in * {@link android.media.mediarecorder#start()}. applications can use the * camera (ex: zoom) after recording starts. there is no need to call this * after recording starts or stops. * *
if you are not recording video, you probably do not need this method. * * @throws ioexception if a connection cannot be re-established (for * example, if the camera is still in use by another process). * @throws runtimeexception if release() has been called on this camera * instance. */ public native final void reconnect() throws ioexception; /** * sets the {@link surface} to be used for live preview. * either a surface or surface texture is necessary for preview, and * preview is necessary to take pictures. the same surface can be re-set * without harm. setting a preview surface will un-set any preview surface * texture that was set via {@link #setpreviewtexture}. * *
the {@link surfaceholder} must already contain a surface when this * method is called. if you are using {@link android.view.surfaceview}, * you will need to register a {@link surfaceholder.callback} with * {@link surfaceholder#addcallback(surfaceholder.callback)} and wait for * {@link surfaceholder.callback#surfacecreated(surfaceholder)} before * calling setpreviewdisplay() or starting preview. * *
this method must be called before {@link #startpreview()}. the * one exception is that if the preview surface is not set (or set to null) * before startpreview() is called, then this method may be called once * with a non-null parameter to set the preview surface. (this allows * camera setup and surface creation to happen in parallel, saving time.) * the preview surface may not otherwise change while preview is running. * * @param holder containing the surface on which to place the preview, * or null to remove the preview surface * @throws ioexception if the method fails (for example, if the surface * is unavailable or unsuitable). * @throws runtimeexception if release() has been called on this camera * instance. */ public final void setpreviewdisplay(surfaceholder holder) throws ioexception { if (holder != null) { setpreviewsurface(holder.getsurface()); } else { setpreviewsurface((surface)null); } } /** * @hide */ public native final void setpreviewsurface(surface surface) throws ioexception; /** * sets the {@link surfacetexture} to be used for live preview. * either a surface or surface texture is necessary for preview, and * preview is necessary to take pictures. the same surface texture can be * re-set without harm. setting a preview surface texture will un-set any * preview surface that was set via {@link #setpreviewdisplay}. * *
this method must be called before {@link #startpreview()}. the * one exception is that if the preview surface texture is not set (or set * to null) before startpreview() is called, then this method may be called * once with a non-null parameter to set the preview surface. (this allows * camera setup and surface creation to happen in parallel, saving time.) * the preview surface texture may not otherwise change while preview is * running. * *
the timestamps provided by {@link surfacetexture#gettimestamp()} for a * surfacetexture set as the preview texture have an unspecified zero point, * and cannot be directly compared between different cameras or different * instances of the same camera, or across multiple runs of the same * program. * *
if you are using the preview data to create video or still images, * strongly consider using {@link android.media.mediaactionsound} to * properly indicate image capture or recording start/stop to the user.
* * @see android.media.mediaactionsound * @see android.graphics.surfacetexture * @see android.view.textureview * @param surfacetexture the {@link surfacetexture} to which the preview * images are to be sent or null to remove the current preview surface * texture * @throws ioexception if the method fails (for example, if the surface * texture is unavailable or unsuitable). * @throws runtimeexception if release() has been called on this camera * instance. */ public native final void setpreviewtexture(surfacetexture surfacetexture) throws ioexception; /** * callback interface used to deliver copies of preview frames as * they are displayed. * * @see #setpreviewcallback(camera.previewcallback) * @see #setoneshotpreviewcallback(camera.previewcallback) * @see #setpreviewcallbackwithbuffer(camera.previewcallback) * @see #startpreview() * * @deprecated we recommend using the new {@link android.hardware.camera2} api for new * applications. */ @deprecated public interface previewcallback { /** * called as preview frames are displayed. this callback is invoked * on the event thread {@link #open(int)} was called from. * *if using the {@link android.graphics.imageformat#yv12} format, * refer to the equations in {@link camera.parameters#setpreviewformat} * for the arrangement of the pixel data in the preview callback * buffers. * * @param data the contents of the preview frame in the format defined * by {@link android.graphics.imageformat}, which can be queried * with {@link android.hardware.camera.parameters#getpreviewformat()}. * if {@link android.hardware.camera.parameters#setpreviewformat(int)} * is never called, the default will be the ycbcr_420_sp * (nv21) format. * @param camera the camera service object. */ void onpreviewframe(byte[] data, camera camera); }; /** * starts capturing and drawing preview frames to the screen. * preview will not actually start until a surface is supplied * with {@link #setpreviewdisplay(surfaceholder)} or * {@link #setpreviewtexture(surfacetexture)}. * *
if {@link #setpreviewcallback(camera.previewcallback)}, * {@link #setoneshotpreviewcallback(camera.previewcallback)}, or * {@link #setpreviewcallbackwithbuffer(camera.previewcallback)} were * called, {@link camera.previewcallback#onpreviewframe(byte[], camera)} * will be called when preview data becomes available. * * @throws runtimeexception if starting preview fails; usually this would be * because of a hardware or other low-level error, or because release() * has been called on this camera instance. */ public native final void startpreview(); /** * stops capturing and drawing preview frames to the surface, and * resets the camera for a future call to {@link #startpreview()}. * * @throws runtimeexception if stopping preview fails; usually this would be * because of a hardware or other low-level error, or because release() * has been called on this camera instance. */ public final void stoppreview() { _stoppreview(); mfacedetectionrunning = false; mshuttercallback = null; mrawimagecallback = null; mpostviewcallback = null; mjpegcallback = null; synchronized (mautofocuscallbacklock) { mautofocuscallback = null; } mautofocusmovecallback = null; } private native final void _stoppreview(); /** * return current preview state. * * fixme: unhide before release * @hide */ public native final boolean previewenabled(); /** *
installs a callback to be invoked for every preview frame in addition * to displaying them on the screen. the callback will be repeatedly called * for as long as preview is active. this method can be called at any time, * even while preview is live. any other preview callbacks are * overridden.
* *if you are using the preview data to create video or still images, * strongly consider using {@link android.media.mediaactionsound} to * properly indicate image capture or recording start/stop to the user.
* * @param cb a callback object that receives a copy of each preview frame, * or null to stop receiving callbacks. * @throws runtimeexception if release() has been called on this camera * instance. * @see android.media.mediaactionsound */ public final void setpreviewcallback(previewcallback cb) { mpreviewcallback = cb; moneshot = false; mwithbuffer = false; if (cb != null) { musingpreviewallocation = false; } // always use one-shot mode. we fake camera preview mode by // doing one-shot preview continuously. sethaspreviewcallback(cb != null, false); } /** *installs a callback to be invoked for the next preview frame in * addition to displaying it on the screen. after one invocation, the * callback is cleared. this method can be called any time, even when * preview is live. any other preview callbacks are overridden.
* *if you are using the preview data to create video or still images, * strongly consider using {@link android.media.mediaactionsound} to * properly indicate image capture or recording start/stop to the user.
* * @param cb a callback object that receives a copy of the next preview frame, * or null to stop receiving callbacks. * @throws runtimeexception if release() has been called on this camera * instance. * @see android.media.mediaactionsound */ public final void setoneshotpreviewcallback(previewcallback cb) { mpreviewcallback = cb; moneshot = true; mwithbuffer = false; if (cb != null) { musingpreviewallocation = false; } sethaspreviewcallback(cb != null, false); } private native final void sethaspreviewcallback(boolean installed, boolean manualbuffer); /** *installs a callback to be invoked for every preview frame, using * buffers supplied with {@link #addcallbackbuffer(byte[])}, in addition to * displaying them on the screen. the callback will be repeatedly called * for as long as preview is active and buffers are available. any other * preview callbacks are overridden.
* *the purpose of this method is to improve preview efficiency and frame * rate by allowing preview frame memory reuse. you must call * {@link #addcallbackbuffer(byte[])} at some point -- before or after * calling this method -- or no callbacks will received.
* *the buffer queue will be cleared if this method is called with a null * callback, {@link #setpreviewcallback(camera.previewcallback)} is called, * or {@link #setoneshotpreviewcallback(camera.previewcallback)} is * called.
* *if you are using the preview data to create video or still images, * strongly consider using {@link android.media.mediaactionsound} to * properly indicate image capture or recording start/stop to the user.
* * @param cb a callback object that receives a copy of the preview frame, * or null to stop receiving callbacks and clear the buffer queue. * @throws runtimeexception if release() has been called on this camera * instance. * @see #addcallbackbuffer(byte[]) * @see android.media.mediaactionsound */ public final void setpreviewcallbackwithbuffer(previewcallback cb) { mpreviewcallback = cb; moneshot = false; mwithbuffer = true; if (cb != null) { musingpreviewallocation = false; } sethaspreviewcallback(cb != null, true); } /** * adds a pre-allocated buffer to the preview callback buffer queue. * applications can add one or more buffers to the queue. when a preview * frame arrives and there is still at least one available buffer, the * buffer will be used and removed from the queue. then preview callback is * invoked with the buffer. if a frame arrives and there is no buffer left, * the frame is discarded. applications should add buffers back when they * finish processing the data in them. * *for formats besides yv12, the size of the buffer is determined by * multiplying the preview image width, height, and bytes per pixel. the * width and height can be read from * {@link camera.parameters#getpreviewsize()}. bytes per pixel can be * computed from {@link android.graphics.imageformat#getbitsperpixel(int)} / * 8, using the image format from * {@link camera.parameters#getpreviewformat()}. * *
if using the {@link android.graphics.imageformat#yv12} format, the * size can be calculated using the equations listed in * {@link camera.parameters#setpreviewformat}. * *
this method is only necessary when * {@link #setpreviewcallbackwithbuffer(previewcallback)} is used. when * {@link #setpreviewcallback(previewcallback)} or * {@link #setoneshotpreviewcallback(previewcallback)} are used, buffers * are automatically allocated. when a supplied buffer is too small to * hold the preview frame data, preview callback will return null and * the buffer will be removed from the buffer queue. * * @param callbackbuffer the buffer to add to the queue. the size of the *buffer must match the values described above. * @see #setpreviewcallbackwithbuffer(previewcallback) */ public final void addcallbackbuffer(byte[] callbackbuffer) { _addcallbackbuffer(callbackbuffer, camera_msg_preview_frame); } /** * adds a pre-allocated buffer to the raw image callback buffer queue. * applications can add one or more buffers to the queue. when a raw image * frame arrives and there is still at least one available buffer, the * buffer will be used to hold the raw image data and removed from the * queue. then raw image callback is invoked with the buffer. if a raw * image frame arrives but there is no buffer left, the frame is * discarded. applications should add buffers back when they finish * processing the data in them by calling this method again in order * to avoid running out of raw image callback buffers. * *
the size of the buffer is determined by multiplying the raw image * width, height, and bytes per pixel. the width and height can be * read from {@link camera.parameters#getpicturesize()}. bytes per pixel * can be computed from * {@link android.graphics.imageformat#getbitsperpixel(int)} / 8, * using the image format from {@link camera.parameters#getpreviewformat()}. * *
this method is only necessary when the picturecallbck for raw image * is used while calling {@link #takepicture(camera.shuttercallback, * camera.picturecallback, camera.picturecallback, camera.picturecallback)}. * *
please note that by calling this method, the mode for * application-managed callback buffers is triggered. if this method has * never been called, null will be returned by the raw image callback since * there is no image callback buffer available. furthermore, when a supplied * buffer is too small to hold the raw image data, raw image callback will * return null and the buffer will be removed from the buffer queue. * * @param callbackbuffer the buffer to add to the raw image callback buffer * queue. the size should be width * height * (bits per pixel) / 8. an * null callbackbuffer will be ignored and won't be added to the queue. * * @see #takepicture(camera.shuttercallback, * camera.picturecallback, camera.picturecallback, camera.picturecallback)}. * * {@hide} */ public final void addrawimagecallbackbuffer(byte[] callbackbuffer) { addcallbackbuffer(callbackbuffer, camera_msg_raw_image); } private final void addcallbackbuffer(byte[] callbackbuffer, int msgtype) { // camera_msg_video_frame may be allowed in the future. if (msgtype != camera_msg_preview_frame && msgtype != camera_msg_raw_image) { throw new illegalargumentexception( "unsupported message type: " + msgtype); } _addcallbackbuffer(callbackbuffer, msgtype); } private native final void _addcallbackbuffer( byte[] callbackbuffer, int msgtype); /** *
create a {@link android.renderscript renderscript} * {@link android.renderscript.allocation allocation} to use as a * destination of preview callback frames. use * {@link #setpreviewcallbackallocation setpreviewcallbackallocation} to use * the created allocation as a destination for camera preview frames.
* *the allocation will be created with a yuv type, and its contents must * be accessed within renderscript with the {@code rsgetelementatyuv_*} * accessor methods. its size will be based on the current * {@link parameters#getpreviewsize preview size} configured for this * camera.
* * @param rs the renderscript context for this allocation. * @param usage additional usage flags to set for the allocation. the usage *flag {@link android.renderscript.allocation#usage_io_input} will always *be set on the created allocation, but additional flags may be provided *here. * @return a new yuv-type allocation with dimensions equal to the current *preview size. * @throws rsillegalargumentexception if the usage flags are not compatible *with an yuv allocation. * @see #setpreviewcallbackallocation * @hide */ public final allocation createpreviewallocation(renderscript rs, int usage) throws rsillegalargumentexception { parameters p = getparameters(); size previewsize = p.getpreviewsize(); type.builder yuvbuilder = new type.builder(rs, element.createpixel(rs, element.datatype.unsigned_8, element.datakind.pixel_yuv)); // use yv12 for wide compatibility. changing this requires also // adjusting camera service's format selection. yuvbuilder.setyuvformat(imageformat.yv12); yuvbuilder.setx(previewsize.width); yuvbuilder.sety(previewsize.height); allocation a = allocation.createtyped(rs, yuvbuilder.create(), usage | allocation.usage_io_input); return a; } /** *set an {@link android.renderscript.allocation allocation} as the * target of preview callback data. use this method for efficient processing * of camera preview data with renderscript. the allocation must be created * with the {@link #createpreviewallocation createpreviewallocation } * method.
* *setting a preview allocation will disable any active preview callbacks * set by {@link #setpreviewcallback setpreviewcallback} or * {@link #setpreviewcallbackwithbuffer setpreviewcallbackwithbuffer}, and * vice versa. using a preview allocation still requires an active standard * preview target to be set, either with * {@link #setpreviewtexture setpreviewtexture} or * {@link #setpreviewdisplay setpreviewdisplay}.
* *to be notified when new frames are available to the allocation, use * {@link android.renderscript.allocation#setioinputnotificationhandler allocation.setioinputnotificationhandler}. to * update the frame currently accessible from the allocation to the latest * preview frame, call * {@link android.renderscript.allocation#ioreceive allocation.ioreceive}.
* *to disable preview into the allocation, call this method with a * {@code null} parameter.
* *once a preview allocation is set, the preview size set by * {@link parameters#setpreviewsize setpreviewsize} cannot be changed. if * you wish to change the preview size, first remove the preview allocation * by calling {@code setpreviewcallbackallocation(null)}, then change the * preview size, create a new preview allocation with * {@link #createpreviewallocation createpreviewallocation}, and set it as * the new preview callback allocation target.
* *if you are using the preview data to create video or still images, * strongly consider using {@link android.media.mediaactionsound} to * properly indicate image capture or recording start/stop to the user.
* * @param previewallocation the allocation to use as destination for preview * @throws ioexception if configuring the camera to use the allocation for *preview fails. * @throws illegalargumentexception if the allocation's dimensions or other *parameters don't meet the requirements. * @see #createpreviewallocation * @see #setpreviewcallback * @see #setpreviewcallbackwithbuffer * @hide */ public final void setpreviewcallbackallocation(allocation previewallocation) throws ioexception { surface previewsurface = null; if (previewallocation != null) { parameters p = getparameters(); size previewsize = p.getpreviewsize(); if (previewsize.width != previewallocation.gettype().getx() || previewsize.height != previewallocation.gettype().gety()) { throw new illegalargumentexception( "allocation dimensions don't match preview dimensions: " + "allocation is " + previewallocation.gettype().getx() + ", " + previewallocation.gettype().gety() + ". preview is " + previewsize.width + ", " + previewsize.height); } if ((previewallocation.getusage() & allocation.usage_io_input) == 0) { throw new illegalargumentexception( "allocation usage does not include usage_io_input"); } if (previewallocation.gettype().getelement().getdatakind() != element.datakind.pixel_yuv) { throw new illegalargumentexception( "allocation is not of a yuv type"); } previewsurface = previewallocation.getsurface(); musingpreviewallocation = true; } else { musingpreviewallocation = false; } setpreviewcallbacksurface(previewsurface); } private native final void setpreviewcallbacksurface(surface s); private class eventhandler extends handler { private final camera mcamera; public eventhandler(camera c, looper looper) { super(looper); mcamera = c; } @override public void handlemessage(message msg) { switch(msg.what) { case camera_msg_shutter: if (mshuttercallback != null) { mshuttercallback.onshutter(); } return; case camera_msg_raw_image: if (mrawimagecallback != null) { mrawimagecallback.onpicturetaken((byte[])msg.obj, mcamera); } return; case camera_msg_compressed_image: if (mjpegcallback != null) { mjpegcallback.onpicturetaken((byte[])msg.obj, mcamera); } return; case camera_msg_preview_frame: previewcallback pcb = mpreviewcallback; if (pcb != null) { if (moneshot) { // clear the callback variable before the callback // in case the app calls setpreviewcallback from // the callback function mpreviewcallback = null; } else if (!mwithbuffer) { // we're faking the camera preview mode to prevent // the app from being flooded with preview frames. // set to oneshot mode again. sethaspreviewcallback(true, false); } pcb.onpreviewframe((byte[])msg.obj, mcamera); } return; case camera_msg_postview_frame: if (mpostviewcallback != null) { mpostviewcallback.onpicturetaken((byte[])msg.obj, mcamera); } return; case camera_msg_focus: autofocuscallback cb = null; synchronized (mautofocuscallbacklock) { cb = mautofocuscallback; } if (cb != null) { boolean success = msg.arg1 == 0 ? false : true; cb.onautofocus(success, mcamera); } return; case camera_msg_zoom: if (mzoomlistener != null) { mzoomlistener.onzoomchange(msg.arg1, msg.arg2 != 0, mcamera); } return; case camera_msg_preview_metadata: if (mfacelistener != null) { mfacelistener.onfacedetection((face[])msg.obj, mcamera); } return; case camera_msg_error : log.e(tag, "error " + msg.arg1); if (merrorcallback != null) { merrorcallback.onerror(msg.arg1, mcamera); } return; case camera_msg_focus_move: if (mautofocusmovecallback != null) { mautofocusmovecallback.onautofocusmoving(msg.arg1 == 0 ? false : true, mcamera); } return; default: log.e(tag, "unknown message type " + msg.what); return; } } } private static void posteventfromnative(object camera_ref, int what, int arg1, int arg2, object obj) { camera c = (camera)((weakreference)camera_ref).get(); if (c == null) return; if (c.meventhandler != null) { message m = c.meventhandler.obtainmessage(what, arg1, arg2, obj); c.meventhandler.sendmessage(m); } } /** * callback interface used to notify on completion of camera auto focus. * *devices that do not support auto-focus will receive a "fake" * callback to this interface. if your application needs auto-focus and * should not be installed on devices without auto-focus, you must * declare that your app uses the * {@code android.hardware.camera.autofocus} feature, in the * <uses-feature> * manifest element.
* * @see #autofocus(autofocuscallback) * @deprecated we recommend using the new {@link android.hardware.camera2} api for new * applications. */ @deprecated public interface autofocuscallback { /** * called when the camera auto focus completes. if the camera * does not support auto-focus and autofocus is called, * onautofocus will be called immediately with a fake value of *success set to true. * * the auto-focus routine does not lock auto-exposure and auto-white * balance after it completes. * * @param success true if focus was successful, false if otherwise * @param camera the camera service object * @see android.hardware.camera.parameters#setautoexposurelock(boolean) * @see android.hardware.camera.parameters#setautowhitebalancelock(boolean) */ void onautofocus(boolean success, camera camera); } /** * starts camera auto-focus and registers a callback function to run when * the camera is focused. this method is only valid when preview is active * (between {@link #startpreview()} and before {@link #stoppreview()}). * *
callers should check * {@link android.hardware.camera.parameters#getfocusmode()} to determine if * this method should be called. if the camera does not support auto-focus, * it is a no-op and {@link autofocuscallback#onautofocus(boolean, camera)} * callback will be called immediately. * *
if your application should not be installed * on devices without auto-focus, you must declare that your application * uses auto-focus with the * <uses-feature> * manifest element.
* *
if the current flash mode is not * {@link android.hardware.camera.parameters#flash_mode_off}, flash may be * fired during auto-focus, depending on the driver and camera hardware.
* *
auto-exposure lock {@link android.hardware.camera.parameters#getautoexposurelock()} * and auto-white balance locks {@link android.hardware.camera.parameters#getautowhitebalancelock()} * do not change during and after autofocus. but auto-focus routine may stop * auto-exposure and auto-white balance transiently during focusing. * *
stopping preview with {@link #stoppreview()}, or triggering still * image capture with {@link #takepicture(camera.shuttercallback, * camera.picturecallback, camera.picturecallback)}, will not change the * the focus position. applications must call cancelautofocus to reset the * focus.
* *
if autofocus is successful, consider using * {@link android.media.mediaactionsound} to properly play back an autofocus * success sound to the user.
* * @param cb the callback to run * @throws runtimeexception if starting autofocus fails; usually this would * be because of a hardware or other low-level error, or because * release() has been called on this camera instance. * @see #cancelautofocus() * @see android.hardware.camera.parameters#setautoexposurelock(boolean) * @see android.hardware.camera.parameters#setautowhitebalancelock(boolean) * @see android.media.mediaactionsound */ public final void autofocus(autofocuscallback cb) { synchronized (mautofocuscallbacklock) { mautofocuscallback = cb; } native_autofocus(); } private native final void native_autofocus(); /** * cancels any auto-focus function in progress. * whether or not auto-focus is currently in progress, * this function will return the focus position to the default. * if the camera does not support auto-focus, this is a no-op. * * @throws runtimeexception if canceling autofocus fails; usually this would * be because of a hardware or other low-level error, or because * release() has been called on this camera instance. * @see #autofocus(camera.autofocuscallback) */ public final void cancelautofocus() { synchronized (mautofocuscallbacklock) { mautofocuscallback = null; } native_cancelautofocus(); // camera_msg_focus should be removed here because the following // scenario can happen: // - an application uses the same thread for autofocus, cancelautofocus //and looper thread. // - the application calls autofocus. // - hal sends camera_msg_focus, which enters the looper message queue. //before event handler's handlemessage() is invoked, the application //calls cancelautofocus and autofocus. // - the application gets the old camera_msg_focus and thinks autofocus //has been completed. but in fact it is not. // // as documented in the beginning of the file, apps should not use // multiple threads to call autofocus and cancelautofocus at the same // time. it is hal's responsibility not to send a camera_msg_focus // message after native_cancelautofocus is called. meventhandler.removemessages(camera_msg_focus); } private native final void native_cancelautofocus(); /** * callback interface used to notify on auto focus start and stop. * *
this is only supported in continuous autofocus modes -- {@link * parameters#focus_mode_continuous_video} and {@link * parameters#focus_mode_continuous_picture}. applications can show * autofocus animation based on this.
* * @deprecated we recommend using the new {@link android.hardware.camera2} api for new * applications. */ @deprecated public interface autofocusmovecallback { /** * called when the camera auto focus starts or stops. * * @param start true if focus starts to move, false if focus stops to move * @param camera the camera service object */ void onautofocusmoving(boolean start, camera camera); } /** * sets camera auto-focus move callback. * * @param cb the callback to run * @throws runtimeexception if enabling the focus move callback fails; * usually this would be because of a hardware or other low-level error, * or because release() has been called on this camera instance. */ public void setautofocusmovecallback(autofocusmovecallback cb) { mautofocusmovecallback = cb; enablefocusmovecallback((mautofocusmovecallback != null) ? 1 : 0); } private native void enablefocusmovecallback(int enable); /** * callback interface used to signal the moment of actual image capture. * * @see #takepicture(shuttercallback, picturecallback, picturecallback, picturecallback) * * @deprecated we recommend using the new {@link android.hardware.camera2} api for new * applications. */ @deprecated public interface shuttercallback { /** * called as near as possible to the moment when a photo is captured * from the sensor. this is a good opportunity to play a shutter sound * or give other feedback of camera operation. this may be some time * after the photo was triggered, but some time before the actual data * is available. */ void onshutter(); } /** * callback interface used to supply image data from a photo capture. * * @see #takepicture(shuttercallback, picturecallback, picturecallback, picturecallback) * * @deprecated we recommend using the new {@link android.hardware.camera2} api for new * applications. */ @deprecated public interface picturecallback { /** * called when image data is available after a picture is taken. * the format of the data depends on the context of the callback * and {@link camera.parameters} settings. * * @param dataa byte array of the picture data * @param camera the camera service object */ void onpicturetaken(byte[] data, camera camera); }; /** * equivalent to
takepicture(shutter, raw, null, jpeg)
. * * @see #takepicture(shuttercallback, picturecallback, picturecallback, picturecallback) */ public final void takepicture(shuttercallback shutter, picturecallback raw, picturecallback jpeg) { takepicture(shutter, raw, null, jpeg); } private native final void native_takepicture(int msgtype); /** * triggers an asynchronous image capture. the camera service will initiate * a series of callbacks to the application as the image capture progresses. * the shutter callback occurs after the image is captured. this can be used * to trigger a sound to let the user know that image has been captured. the * raw callback occurs when the raw image data is available (note: the data * will be null if there is no raw image callback buffer available or the * raw image callback buffer is not large enough to hold the raw image). * the postview callback occurs when a scaled, fully processed postview * image is available (note: not all hardware supports this). the jpeg * callback occurs when the compressed image is available. if the * application does not need a particular callback, a null can be passed * instead of a callback method. * *
this method is only valid when preview is active (after * {@link #startpreview()}). preview will be stopped after the image is * taken; callers must call {@link #startpreview()} again if they want to * re-start preview or take more pictures. this should not be called between * {@link android.media.mediarecorder#start()} and * {@link android.media.mediarecorder#stop()}. * *
after calling this method, you must not call {@link #startpreview()} * or take another picture until the jpeg callback has returned. * * @param shutterthe callback for image capture moment, or null * @param raw the callback for raw (uncompressed) image data, or null * @param postview callback with postview image data, may be null * @param jpegthe callback for jpeg image data, or null * @throws runtimeexception if starting picture capture fails; usually this * would be because of a hardware or other low-level error, or because * release() has been called on this camera instance. */ public final void takepicture(shuttercallback shutter, picturecallback raw, picturecallback postview, picturecallback jpeg) { mshuttercallback = shutter; mrawimagecallback = raw; mpostviewcallback = postview; mjpegcallback = jpeg; // if callback is not set, do not send me callbacks. int msgtype = 0; if (mshuttercallback != null) { msgtype |= camera_msg_shutter; } if (mrawimagecallback != null) { msgtype |= camera_msg_raw_image; } if (mpostviewcallback != null) { msgtype |= camera_msg_postview_frame; } if (mjpegcallback != null) { msgtype |= camera_msg_compressed_image; } native_takepicture(msgtype); mfacedetectionrunning = false; } /** * zooms to the requested value smoothly. the driver will notify {@link * onzoomchangelistener} of the zoom value and whether zoom is stopped at * the time. for example, suppose the current zoom is 0 and startsmoothzoom * is called with value 3. the * {@link camera.onzoomchangelistener#onzoomchange(int, boolean, camera)} * method will be called three times with zoom values 1, 2, and 3. * applications can call {@link #stopsmoothzoom} to stop the zoom earlier. * applications should not call startsmoothzoom again or change the zoom * value before zoom stops. if the supplied zoom value equals to the current * zoom value, no zoom callback will be generated. this method is supported * if {@link android.hardware.camera.parameters#issmoothzoomsupported} * returns true. * * @param value zoom value. the valid range is 0 to {@link * android.hardware.camera.parameters#getmaxzoom}. * @throws illegalargumentexception if the zoom value is invalid. * @throws runtimeexception if the method fails. * @see #setzoomchangelistener(onzoomchangelistener) */ public native final void startsmoothzoom(int value); /** * stops the smooth zoom. applications should wait for the {@link * onzoomchangelistener} to know when the zoom is actually stopped. this * method is supported if {@link * android.hardware.camera.parameters#issmoothzoomsupported} is true. * * @throws runtimeexception if the method fails. */ public native final void stopsmoothzoom(); /** * set the clockwise rotation of preview display in degrees. this affects * the preview frames and the picture displayed after snapshot. this method * is useful for portrait mode applications. note that preview display of * front-facing cameras is flipped horizontally before the rotation, that * is, the image is reflected along the central vertical axis of the camera * sensor. so the users can see themselves as looking into a mirror. * *
this does not affect the order of byte array passed in {@link * previewcallback#onpreviewframe}, jpeg pictures, or recorded videos. this * method is not allowed to be called during preview. * *
if you want to make the camera image show in the same orientation as * the display, you can use the following code. *
* public static void setcameradisplayorientation(activity activity, *int cameraid, android.hardware.camera camera) { * android.hardware.camera.camerainfo info = * new android.hardware.camera.camerainfo(); * android.hardware.camera.getcamerainfo(cameraid, info); * int rotation = activity.getwindowmanager().getdefaultdisplay() * .getrotation(); * int degrees = 0; * switch (rotation) { *case surface.rotation_0: degrees = 0; break; *case surface.rotation_90: degrees = 90; break; *case surface.rotation_180: degrees = 180; break; *case surface.rotation_270: degrees = 270; break; * } * * int result; * if (info.facing == camera.camerainfo.camera_facing_front) { *result = (info.orientation + degrees) % 360; *result = (360 - result) % 360; // compensate the mirror * } else { // back-facing *result = (info.orientation - degrees + 360) % 360; * } * camera.setdisplayorientation(result); * } *
* *
starting from api level 14, this method can be called when preview is * active. * *
note: before api level 24, the default value for orientation is 0. starting in * api level 24, the default orientation will be such that applications in forced-landscape mode * will have correct preview orientation, which may be either a default of 0 or * 180. applications that operate in portrait mode or allow for changing orientation must still * call this method after each orientation change to ensure correct preview display in all * cases.
* * @param degrees the angle that the picture will be rotated clockwise. * valid values are 0, 90, 180, and 270. * @throws runtimeexception if setting orientation fails; usually this would * be because of a hardware or other low-level error, or because * release() has been called on this camera instance. * @see #setpreviewdisplay(surfaceholder) */ public native final void setdisplayorientation(int degrees); /** *
enable or disable the default shutter sound when taking a picture.
* *
by default, the camera plays the system-defined camera shutter sound * when {@link #takepicture} is called. using this method, the shutter sound * can be disabled. it is strongly recommended that an alternative shutter * sound is played in the {@link shuttercallback} when the system shutter * sound is disabled.
* *
note that devices may not always allow disabling the camera shutter * sound. if the shutter sound state cannot be set to the desired value, * this method will return false. {@link camerainfo#candisableshuttersound} * can be used to determine whether the device will allow the shutter sound * to be disabled.
* * @param enabled whether the camera should play the system shutter sound * when {@link #takepicture takepicture} is called. * @return {@code true} if the shutter sound state was successfully *changed. {@code false} if the shutter sound state could not be *changed. {@code true} is also returned if shutter sound playback *is already set to the requested state. * @throws runtimeexception if the call fails; usually this would be because * of a hardware or other low-level error, or because release() has been * called on this camera instance. * @see #takepicture * @see camerainfo#candisableshuttersound * @see shuttercallback */ public final boolean enableshuttersound(boolean enabled) { if (!enabled) { ibinder b = servicemanager.getservice(context.audio_service); iaudioservice audioservice = iaudioservice.stub.asinterface(b); try { if (audioservice.iscamerasoundforced()) return false; } catch (remoteexception e) { log.e(tag, "audio service is unavailable for queries"); } } return _enableshuttersound(enabled); } /** * disable the shutter sound unconditionally. * *
* this is only guaranteed to work for legacy cameras * (i.e. initialized with {@link #camerainitunspecified}). trying to call this on * a regular camera will force a conditional check in the camera service. *
* * @return {@code true} if the shutter sound state was successfully *changed. {@code false} if the shutter sound state could not be *changed. {@code true} is also returned if shutter sound playback *is already set to the requested state. * * @hide */ public final boolean disableshuttersound() { return _enableshuttersound(/*enabled*/false); } private native final boolean _enableshuttersound(boolean enabled); /** * callback interface for zoom changes during a smooth zoom operation. * * @see #setzoomchangelistener(onzoomchangelistener) * @see #startsmoothzoom(int) * * @deprecated we recommend using the new {@link android.hardware.camera2} api for new * applications. */ @deprecated public interface onzoomchangelistener { /** * called when the zoom value has changed during a smooth zoom. * * @param zoomvalue the current zoom value. in smooth zoom mode, camera *calls this for every new zoom value. * @param stopped whether smooth zoom is stopped. if the value is true, * this is the last zoom update for the application. * @param camera the camera service object */ void onzoomchange(int zoomvalue, boolean stopped, camera camera); }; /** * registers a listener to be notified when the zoom value is updated by the * camera driver during smooth zoom. * * @param listener the listener to notify * @see #startsmoothzoom(int) */ public final void setzoomchangelistener(onzoomchangelistener listener) { mzoomlistener = listener; } /** * callback interface for face detected in the preview frame. * * @deprecated we recommend using the new {@link android.hardware.camera2} api for new * applications. */ @deprecated public interface facedetectionlistener { /** * notify the listener of the detected faces in the preview frame. * * @param faces the detected faces in a list * @param camera the {@link camera} service object */ void onfacedetection(face[] faces, camera camera); } /** * regist