棉花糖中的手电筒控制

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:棉花糖中的未知缓冲区错误

获取棉花糖中的当前位置 0,其中 23 API 以下使用融合位置给出准确的当前位置

清除棉花糖中所有应用程序的缓存?

安卓10源码学习开发定制(29)手电筒控制源码分析

在棉花糖中获取蓝牙本地mac地址

Galaxy Nexus 上的 LED 手电筒可由啥 API 控制?