棉花糖中的手电筒控制
Posted
技术标签:
【中文标题】棉花糖中的手电筒控制【英文标题】:Flashlight control in Marshmallow 【发布时间】:2016-01-21 20:17:07 【问题描述】:我对最新 Marshmallow 版本中的相机有疑问,尤其是手电筒。 在任何 Marshmallow 之前的版本中,打开/关闭闪光灯所需的操作如下:
private void turnFlashOn(final Camera camera, int flashLightDurationMs)
if (!isFlashOn())
final List<String> supportedFlashModes = camera.getParameters().getSupportedFlashModes();
if (supportedFlashModes != null && supportedFlashModes.contains(Camera.Parameters.FLASH_MODE_TORCH))
mParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(mParams);
和
private void turnFlashOff(Camera camera)
if (camera != null)
final List<String> supportedFlashModes = camera.getParameters().getSupportedFlashModes();
if (supportedFlashModes != null && supportedFlashModes.contains(Camera.Parameters.FLASH_MODE_OFF))
mParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(mParams);
不幸的是,Marshmallow 设备开始在野外崩溃。不知何故,camera.getParameters()
和 camera.setParameters()
开始失败,并显示如下消息:
RuntimeException: getParameters failed(空参数)
RuntimeException: setParameters 失败
我尝试在获取参数之前启动和停止预览,这不再引发错误。但是,当我调用 camera.startPreview()
时,预览不会恢复。
我担心释放相机并重新打开它是不可能的,因为这需要几秒钟并且会产生糟糕的体验。
关于如何在棉花糖中可靠地打开/关闭手电筒有什么建议吗?
【问题讨论】:
【参考方案1】:Google 已在 OS 6 (android M) 中引入了手电筒模式。 如果您的目的只是打开/关闭闪光灯,下面的代码可以帮助您:
private static void handleActionTurnOnFlashLight(Context context)
try
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
String[] list = manager.getCameraIdList();
manager.setTorchMode(list[0], true);
catch (CameraAccessException cae)
Log.e(TAG, cae.getMessage());
cae.printStackTrace();
private static void handleActionTurnOffFlashLight(Context context)
try
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
manager.setTorchMode(manager.getCameraIdList()[0], false);
catch (CameraAccessException cae)
Log.e(TAG, cae.getMessage());
cae.printStackTrace();
您所要做的就是:获取 cameraid 的列表,其中相机 ID 零 (0) 是您想要打开/关闭闪光灯的主要相机。只需将 cameraID 传递给带有布尔值的 setTochMode API 即可打开或关闭它。
请注意,这段代码仅适用于 OS 6,因此您需要检查设备操作系统,并根据此选择为 pre-marshmallow 设备调用哪些 API。
如果它解决了您的问题,请将此标记为解决方案。
【讨论】:
【参考方案2】:作为Saurabh7474 has responded,检查Android版本并使用setTorchMode API非常正确。
虽然你也可以在棉花糖中使用 params.setFlashMode (...)
mCamera.setPreviewTexture (new SurfaceTexture (100))
在 Camera.open (...) 之后和调用 mCamera.startPreview() 之前;
try
Log.i(TAG, "getCamera");
int requestedCameraId = getIdForRequestedCamera(mFacing);
if (requestedCameraId == -1)
throw new RuntimeException("Could not find requested camera.");
mCamera = Camera.open(requestedCameraId);
mCamera.setPreviewTexture(new SurfaceTexture(DUMMY_TEXTURE_NAME));
params = mCamera.getParameters();
catch (RuntimeException e)
Log.e("Failed to Open. Error:", e.getMessage());
catch (IOException e)
Log.e("Failed to Open. can't setPreviewTexture:", e.getMessage());
那么当你想要的时候,你可以使用
mParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(mParams);
我的答案基于 Vision API 的 CameraSource 示例,该示例使用 params.setFlashMode (...) 并在 Api 23 及更高版本中工作。 如果您决定检查 CameraSource,解决相同问题的关键方法是“start()”,在第 312 行 ...
https://github.com/googlesamples/android-vision/blob/master/visionSamples/barcode-reader/app/src/main/java/com/google/android/gms/samples/vision/barcodereader/ui/camera/CameraSource.java
您可以在这里找到原因 https://***.com/a/33333046/4114846
【讨论】:
【参考方案3】:更新您的应用以在运行时检查权限。您必须授予android.permission.CAMERA
。将它包含在您的应用程序清单中不会在 Marshmallow 上授予您它。您需要检测它是否已被授予并请求它。
【讨论】:
我已经拥有相机权限。我的目标不是 23,所以我还不需要检查运行时权限,对吧?。 是和不是。如果您的目标不是 23,那么该权限应该已经被授予。但是,用户可能会在安装后禁用该权限。在这种情况下,您需要检查(如果在 API 23 设备上运行)您是否有权限。如果您不这样做是因为用户拒绝了它,那么相机 API 可能会返回空数据或 null 数据。本次演讲将提供有关 Marshmallow 权限更改的更多详细信息:youtu.be/WGz-alwVh8A?list=PLnVy79PaFHMUqqvwbjyKJZv1N8rzHOCBi 你说得对,确实如此。但是,即使授予了权限,应用也会崩溃,因此与相机 API 相关的某些内容似乎发生了变化,并且其行为与在 Lollipop 或 Kitkat 中的行为不同。 我希望这是导致崩溃的另一个根本原因。在授予权限与未授予权限的情况下检查崩溃输出。【参考方案4】:根据 Saurabh7474 的回答,您可以通过注册 torchCallback 来切换 Marshmallow 的 torchMode:
final CameraManager mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
CameraManager.TorchCallback torchCallback = new CameraManager.TorchCallback()
@Override
public void onTorchModeUnavailable(String cameraId)
super.onTorchModeUnavailable(cameraId);
@Override
public void onTorchModeChanged(String cameraId, boolean enabled)
super.onTorchModeChanged(cameraId, enabled);
boolean currentTorchState = enabled;
try
mCameraManager.setTorchMode(cameraId, !currentTorchState);
catch (CameraAccessException e)
;
mCameraManager.registerTorchCallback(torchCallback, null);//fires onTorchModeChanged upon register
mCameraManager.unregisterTorchCallback(torchCallback);
【讨论】:
以上是关于棉花糖中的手电筒控制的主要内容,如果未能解决你的问题,请参考以下文章
Android Studio getSlotFromBufferLocked:棉花糖中的未知缓冲区错误