Подтвердить что ты не робот

Управление фонариком в Marshmallow

У меня проблема с камерой в самой последней сборке 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 не удалось (пустые параметры)

RuntimeException: сбой setParameters

Я попытался запустить и остановить предварительный просмотр, прежде чем получать параметры, которые больше не вызывают ошибок. Однако предварительный просмотр не возобновляется, когда я вызываю camera.startPreview().

Я боюсь, что освобождение камеры и повторное открытие не могут быть решены, так как это занимает несколько секунд и приведет к плохим результатам.

Любые предложения по включению/выключению фонарика в Marshmallow?

4b9b3361

Ответ 1

Google представил факел в ОС 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();
    }
}

Все, что вам нужно сделать, это: Получить список камер, из которых нулевой номер камеры (0) - это ваша основная камера, для которой вы хотите включить/выключить вспышку. Просто передайте CameraID в setTochMode API с логическим значением для включения или выключения.

Обратите внимание, что этот фрагмент кода будет работать только с ОС 6, поэтому вам необходимо проверить ОС устройства и на основании этого вам нужно выбрать, какой API вызывать для устройств с предварительным указателем.

Не забудьте отметить это как решение, если оно решит вашу проблему.

Ответ 2

Как Saurabh7474 ответил, чтобы проверить версию Android и использовать setTorchMode API, это очень правильно.

Хотя вы также можете использовать paramssetFlashMode (...) в зефире, используя

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);

Мой ответ основан на примерах CameraSource API Vision, который использует 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

Причина, по которой вы можете найти здесь fooobar.com/questions/454981/...

Ответ 3

Обновите приложение, чтобы проверить разрешения во время выполнения. Вы должны иметь android.permission.CAMERA. Включая его в манифест вашего приложения, он не собирается предоставлять его вам на Marshmallow. Вам нужно будет определить, было ли оно предоставлено или запрошено.

Ответ 4

Построение ответа Saurabh7474, вы можете переключить Marshmallow torchMode, зарегистрировав torchCallback:

 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);