From 669a96a78f390e691f7a8b0fbfe4f1c3fd0e4512 Mon Sep 17 00:00:00 2001 From: Olivier Guennec Date: Tue, 24 Apr 2018 10:27:12 +0100 Subject: [PATCH 1/2] fix#6 support for torch state checking --- .../cubicphuse/RCTTorch/RCTTorchModule.java | 58 ++++++++++++++----- index.android.js | 19 +++++- ios/RCTTorch.m | 22 ++++++- 3 files changed, 82 insertions(+), 17 deletions(-) diff --git a/android/src/main/java/com/cubicphuse/RCTTorch/RCTTorchModule.java b/android/src/main/java/com/cubicphuse/RCTTorch/RCTTorchModule.java index f212f70..0d37fef 100644 --- a/android/src/main/java/com/cubicphuse/RCTTorch/RCTTorchModule.java +++ b/android/src/main/java/com/cubicphuse/RCTTorch/RCTTorchModule.java @@ -2,42 +2,74 @@ * Created by Ludo van den Boom on 06/04/2017. */ -package com.cubicphuse.RCTTorch; + package com.cubicphuse.RCTTorch; -import android.content.Context; -import android.hardware.Camera; -import android.hardware.camera2.CameraAccessException; -import android.hardware.camera2.CameraManager; -import android.os.Build; + import android.content.Context; + import android.hardware.Camera; + import android.hardware.camera2.CameraAccessException; + import android.hardware.camera2.CameraManager; + import android.os.Build; + import android.os.Handler; + import android.os.Looper; -import com.facebook.react.bridge.Callback; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; + import com.facebook.react.bridge.Callback; + import com.facebook.react.bridge.ReactApplicationContext; + import com.facebook.react.bridge.ReactContextBaseJavaModule; + import com.facebook.react.bridge.ReactMethod; public class RCTTorchModule extends ReactContextBaseJavaModule { private final ReactApplicationContext myReactContext; private Boolean isTorchOn = false; private Camera camera; + private CameraManager cameraManager; public RCTTorchModule(ReactApplicationContext reactContext) { super(reactContext); // Need access to reactContext to check for camera this.myReactContext = reactContext; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + cameraManager = + (CameraManager) this.myReactContext.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); + isTorchOn = enabled; + } + }; + @Override public String getName() { return "RCTTorch"; } @ReactMethod - public void switchState(Boolean newState, Callback successCallback, Callback failureCallback) { + public void getTorchStatus(Callback successCallback, Callback failureCallback) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - CameraManager cameraManager = - (CameraManager) this.myReactContext.getSystemService(Context.CAMERA_SERVICE); + cameraManager.registerTorchCallback(torchCallback, null); + try { + successCallback.invoke(isTorchOn); + } catch (Exception e) { + String errorMessage = e.getMessage(); + failureCallback.invoke("Error: " + errorMessage); + } + } + } + @ReactMethod + public void switchState(Boolean newState, Callback successCallback, Callback failureCallback) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { try { String cameraId = cameraManager.getCameraIdList()[0]; cameraManager.setTorchMode(cameraId, newState); diff --git a/index.android.js b/index.android.js index d98e8d8..d1063d6 100644 --- a/index.android.js +++ b/index.android.js @@ -58,6 +58,20 @@ async function requestCameraPermission( } } +async function getStatus(): Promise { + let done; + let failure; + + const result = new Promise((resolve, reject) => { + done = resolve; + failure = reject; + }); + + Torch.getTorchStatus(done, failure); + + return result; +} + async function switchState(newState: boolean): Promise { let done; let failure; @@ -73,8 +87,9 @@ async function switchState(newState: boolean): Promise { const TorchWithPermissionCheck = { ...Torch, - switchState, - requestCameraPermission + getStatus, + requestCameraPermission, + switchState }; export default TorchWithPermissionCheck; diff --git a/ios/RCTTorch.m b/ios/RCTTorch.m index 3cb0362..a1b087f 100644 --- a/ios/RCTTorch.m +++ b/ios/RCTTorch.m @@ -19,16 +19,34 @@ @implementation RCTTorch AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if ([device hasTorch]){ [device lockForConfiguration:nil]; - + if (newState) { [device setTorchMode:AVCaptureTorchModeOn]; } else { [device setTorchMode:AVCaptureTorchModeOff]; } - + [device unlockForConfiguration]; } } } +RCT_EXPORT_METHOD(getStatus:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) +{ + if ([AVCaptureDevice class]) { + AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + if ([device hasTorch]){ + BOOL isOn = device.torchMode == AVCaptureTorchModeOn; + resolve(isOn ? @"true" : @"false"); + } else { + NSError *error = [[NSError alloc] initWithDomain:@"torch" code:0 userInfo:nil]; + reject(@"no_torch_available", @"This device has no torch", error); + } + } else { + NSError *error = [[NSError alloc] initWithDomain:@"torch" code:0 userInfo:nil]; + reject(@"no_torch_available", @"This device has no torch", error); + } +} + @end + From baf88842ae02345f0cca9e45bcd85aef8b6dbfc8 Mon Sep 17 00:00:00 2001 From: Olivier Guennec Date: Mon, 14 May 2018 16:29:28 +0100 Subject: [PATCH 2/2] iOS - fix getStatus --- ios/RCTTorch.m | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ios/RCTTorch.m b/ios/RCTTorch.m index a1b087f..fbe0aad 100644 --- a/ios/RCTTorch.m +++ b/ios/RCTTorch.m @@ -13,14 +13,14 @@ @implementation RCTTorch RCT_EXPORT_MODULE() -RCT_EXPORT_METHOD(switchState:(BOOL *)newState) +RCT_EXPORT_METHOD(switchState:(nonnull NSNumber*)newState) { if ([AVCaptureDevice class]) { AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if ([device hasTorch]){ [device lockForConfiguration:nil]; - if (newState) { + if ([newState boolValue]) { [device setTorchMode:AVCaptureTorchModeOn]; } else { [device setTorchMode:AVCaptureTorchModeOff]; @@ -37,7 +37,7 @@ @implementation RCTTorch AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; if ([device hasTorch]){ BOOL isOn = device.torchMode == AVCaptureTorchModeOn; - resolve(isOn ? @"true" : @"false"); + resolve([NSNumber numberWithBool:isOn]); } else { NSError *error = [[NSError alloc] initWithDomain:@"torch" code:0 userInfo:nil]; reject(@"no_torch_available", @"This device has no torch", error); @@ -49,4 +49,3 @@ @implementation RCTTorch } @end -