diff --git a/CHANGELOG.md b/CHANGELOG.md index 971b377..656bf04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [2.0.18](https://github.com/spoonconsulting/cordova-plugin-simple-camera-preview/compare/v2.0.17...v2.0.18) (2024-05-12) + +* **iOS:** Added a method "switchCameraTo" to help switch between ultra-wide camera and default camera. ([#68](https://github.com/spoonconsulting/cordova-plugin-simple-camera-preview/pull/68)) +* **Android:** Added a method "switchCameraTo" to help switch between ultra-wide camera and default camera. ([#68](https://github.com/spoonconsulting/cordova-plugin-simple-camera-preview/pull/68)) +* **iOS:** Added a method "deviceHasUltraWideCamera" to check if device has ultra-wide camera. ([#68](https://github.com/spoonconsulting/cordova-plugin-simple-camera-preview/pull/68)) +* **Android:** Added a method "deviceHasUltraWideCamera" to check if device has ultra-wide camera. ([#68](https://github.com/spoonconsulting/cordova-plugin-simple-camera-preview/pull/68)) + ## [2.0.17](https://github.com/spoonconsulting/cordova-plugin-simple-camera-preview/compare/v2.0.16...v2.0.17) (2023-07-04) * **iOS:** Use interfaceOrientation for ios 13+. ([#67](https://github.com/spoonconsulting/cordova-plugin-simple-camera-preview/pull/67)) diff --git a/README.md b/README.md index 393eb5b..d7c493d 100644 --- a/README.md +++ b/README.md @@ -99,3 +99,46 @@ SimpleCameraPreview.setSize(size, () => { console.log("Camera frame size set"); }); ``` + +### deviceHasUltraWideCamera(successCallback, errorCallback) + +Check if device has ultra-wide camera +
+ +```javascript + +SimpleCameraPreview.deviceHasUltraWideCamera(size, (value: boolean) => { + console.log("Device has ultra-wide camera?: ", value); +}); +``` + +### switchCameraTo(option, successCallback, errorCallback) + +Switch camera between ultra-wide or default + +The variable captureDevice can take two values: +```javascript + "ultra-wide-angle" + + or + + "default" +``` +
+ +```javascript + +const params = { + captureDevice: "ultra-wide-angle", +} + +SimpleCameraPreview.switchCameraTo( + params, + (value: unknown) => { + return (typeof value === "boolean" ? value : false); + }, + (e: unknown) => { + console.log("cannot switch camera: ", e); + } +); +``` diff --git a/package-lock.json b/package-lock.json index a2cf1fb..1403cb9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@spoonconsulting/cordova-plugin-simple-camera-preview", - "version": "2.0.17", + "version": "2.0.18", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@spoonconsulting/cordova-plugin-simple-camera-preview", - "version": "2.0.17", + "version": "2.0.18", "license": "Apache 2.0", "devDependencies": {} } diff --git a/package.json b/package.json index f793732..6e0239b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@spoonconsulting/cordova-plugin-simple-camera-preview", - "version": "2.0.17", + "version": "2.0.18", "description": "Cordova plugin that allows camera interaction from HTML code for showing camera preview below or on top of the HTML.", "keywords": [ "cordova", diff --git a/plugin.xml b/plugin.xml index 6d78762..297a332 100644 --- a/plugin.xml +++ b/plugin.xml @@ -1,6 +1,6 @@ - + cordova-plugin-simple-camera-preview Cordova plugin that allows camera interaction from HTML code. Show camera preview popup on top of the HTML. diff --git a/src/android/CameraPreviewFragment.java b/src/android/CameraPreviewFragment.java index a808b31..c0a299f 100644 --- a/src/android/CameraPreviewFragment.java +++ b/src/android/CameraPreviewFragment.java @@ -4,9 +4,12 @@ import android.content.Context; import android.content.res.Configuration; import android.graphics.Point; +import android.hardware.camera2.CameraCharacteristics; import android.location.Location; import android.net.Uri; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.util.Log; import android.util.Size; import android.view.Display; @@ -18,7 +21,9 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.camera.camera2.internal.Camera2CameraInfoImpl; import androidx.camera.core.Camera; +import androidx.camera.core.CameraInfo; import androidx.camera.core.CameraSelector; import androidx.camera.core.ImageCapture; import androidx.camera.core.ImageCaptureException; @@ -36,6 +41,9 @@ import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.UUID; import java.util.concurrent.ExecutionException; @@ -55,6 +63,14 @@ interface HasFlashCallback { void onResult(boolean result); } +interface CameraSwitchedCallback { + void onSwitch(boolean result); +} + +interface HasUltraWideCameraCallback { + void onResult(boolean result); +} + public class CameraPreviewFragment extends Fragment { private PreviewView viewFinder; @@ -69,6 +85,7 @@ public class CameraPreviewFragment extends Fragment { private static float ratio = (4 / (float) 3); private static final String TAG = "SimpleCameraPreview"; + private String captureDevice; public CameraPreviewFragment() { @@ -82,6 +99,11 @@ public CameraPreviewFragment(int cameraDirection, CameraStartedCallback cameraSt } catch (JSONException e) { e.printStackTrace(); } + try { + this.captureDevice = options.getString("captureDevice"); + } catch (JSONException e) { + e.printStackTrace(); + } startCameraCallback = cameraStartedCallback; } @@ -114,47 +136,51 @@ public void startCamera() { startCameraCallback.onCameraStarted(new Exception("Unable to start camera")); return; } + setUpCamera(captureDevice,cameraProvider); - CameraSelector cameraSelector = new CameraSelector.Builder() - .requireLensFacing(direction) - .build(); + preview.setSurfaceProvider(viewFinder.getSurfaceProvider()); - Size targetResolution = null; - if (targetSize > 0) { - targetResolution = CameraPreviewFragment.calculateResolution(getContext(), targetSize); + if (startCameraCallback != null) { + startCameraCallback.onCameraStarted(null); } + } - preview = new Preview.Builder().build(); - imageCapture = new ImageCapture.Builder() - .setTargetResolution(targetResolution) - .build(); + @SuppressLint("RestrictedApi") + public void deviceHasUltraWideCamera(HasUltraWideCameraCallback hasUltraWideCameraCallback) { + ListenableFuture cameraProviderFuture = ProcessCameraProvider.getInstance(getActivity()); + ProcessCameraProvider cameraProvider = null; - cameraProvider.unbindAll(); try { - camera = cameraProvider.bindToLifecycle( - this, - cameraSelector, - preview, - imageCapture - ); - } catch (IllegalArgumentException e) { - // Error with result in capturing image with default resolution + cameraProvider = cameraProviderFuture.get(); + } catch (ExecutionException | InterruptedException e) { + Log.e(TAG, "Error occurred while trying to obtain the camera provider: " + e.getMessage()); e.printStackTrace(); - imageCapture = new ImageCapture.Builder() - .build(); - camera = cameraProvider.bindToLifecycle( - this, - cameraSelector, - preview, - imageCapture - ); + hasUltraWideCameraCallback.onResult(false); + return; + } + List cameraInfos = cameraProvider.getAvailableCameraInfos(); + + boolean defaultCamera = false; + boolean ultraWideCamera = false; + List backCameras = new ArrayList<>(); + for (CameraInfo cameraInfo : cameraInfos) { + if (cameraInfo instanceof Camera2CameraInfoImpl) { + Camera2CameraInfoImpl camera2CameraInfo = (Camera2CameraInfoImpl) cameraInfo; + if (camera2CameraInfo.getLensFacing() == CameraSelector.LENS_FACING_BACK) { + backCameras.add(camera2CameraInfo); + } + } } - preview.setSurfaceProvider(viewFinder.getSurfaceProvider()); - - if (startCameraCallback != null) { - startCameraCallback.onCameraStarted(null); + for (Camera2CameraInfoImpl backCamera : backCameras) { + if (backCamera.getCameraCharacteristicsCompat().get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)[0] >= 2.4) { + defaultCamera = true; + } else if( backCamera.getCameraCharacteristicsCompat().get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)[0] < 2.4) { + ultraWideCamera = true; + } } + + hasUltraWideCameraCallback.onResult(defaultCamera == true && ultraWideCamera == true); } public static Size calculateResolution(Context context, int targetSize) { @@ -309,4 +335,94 @@ public void setLocation(Location loc) { this.location = loc; } } + + + public void switchCameraTo(String device, CameraSwitchedCallback cameraSwitchedCallback) { + Handler mainHandler = new Handler(Looper.getMainLooper()); + mainHandler.post(() -> { + ListenableFuture cameraProviderFuture = ProcessCameraProvider.getInstance(getActivity()); + ProcessCameraProvider cameraProvider = null; + try { + cameraProvider = cameraProviderFuture.get(); + } catch (ExecutionException | InterruptedException e) { + Log.e(TAG, "Error occurred while trying to obtain the camera provider: " + e.getMessage()); + e.printStackTrace(); + cameraSwitchedCallback.onSwitch(false); + return; + } + + setUpCamera(device,cameraProvider); + + preview.setSurfaceProvider(viewFinder.getSurfaceProvider()); + cameraSwitchedCallback.onSwitch(true); + }); + } + + @SuppressLint("RestrictedApi") + public void setUpCamera(String captureDevice, ProcessCameraProvider cameraProvider) { + CameraSelector cameraSelector; + if (captureDevice.equals("ultra-wide-angle")) { + cameraSelector = new CameraSelector.Builder() + .addCameraFilter(cameraInfos -> { + List backCameras = new ArrayList<>(); + for (CameraInfo cameraInfo : cameraInfos) { + if (cameraInfo instanceof Camera2CameraInfoImpl) { + Camera2CameraInfoImpl camera2CameraInfo = (Camera2CameraInfoImpl) cameraInfo; + if (camera2CameraInfo.getLensFacing() == CameraSelector.LENS_FACING_BACK) { + backCameras.add(camera2CameraInfo); + } + } + } + + Camera2CameraInfoImpl selectedCamera = Collections.min(backCameras, (o1, o2) -> { + Float focalLength1 = o1.getCameraCharacteristicsCompat().get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)[0]; + Float focalLength2 = o2.getCameraCharacteristicsCompat().get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)[0]; + return Float.compare(focalLength1, focalLength2); + }); + + if (selectedCamera != null) { + return Collections.singletonList(selectedCamera); + } else { + return cameraInfos; + } + }) + .build(); + } else { + cameraSelector = new CameraSelector.Builder() + .requireLensFacing(direction) + .build(); + } + + Size targetResolution = null; + if (targetSize > 0) { + targetResolution = CameraPreviewFragment.calculateResolution(getContext(), targetSize); + } + + preview = new Preview.Builder().build(); + imageCapture = new ImageCapture.Builder() + .setTargetResolution(targetResolution) + .build(); + + cameraProvider.unbindAll(); + try { + camera = cameraProvider.bindToLifecycle( + getActivity(), + cameraSelector, + preview, + imageCapture + ); + } catch (IllegalArgumentException e) { + // Error with result in capturing image with default resolution + e.printStackTrace(); + imageCapture = new ImageCapture.Builder() + .build(); + camera = cameraProvider.bindToLifecycle( + getActivity(), + cameraSelector, + preview, + imageCapture + ); + } + + } } diff --git a/src/android/SimpleCameraPreview.java b/src/android/SimpleCameraPreview.java index be44226..4bc7b40 100644 --- a/src/android/SimpleCameraPreview.java +++ b/src/android/SimpleCameraPreview.java @@ -74,6 +74,12 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo case "deviceHasFlash": return deviceHasFlash(callbackContext); + + case "deviceHasUltraWideCamera": + return deviceHasUltraWideCamera(callbackContext); + + case "switchCameraTo": + return switchCameraTo(args.getString(0), callbackContext); default: break; } @@ -146,6 +152,15 @@ private boolean enable(JSONObject options, CallbackContext callbackContext) { e.printStackTrace(); } + String captureDevice = "default"; + try { + if (options.getString("captureDevice") != null && !options.getString("captureDevice").equals("null")) { + captureDevice = options.getString("captureDevice"); + } + } catch (JSONException | NumberFormatException e) { + e.printStackTrace(); + } + JSONObject cameraPreviewOptions = new JSONObject(); try { cameraPreviewOptions.put("targetSize", targetSize); @@ -153,6 +168,12 @@ private boolean enable(JSONObject options, CallbackContext callbackContext) { e.printStackTrace(); } + try { + cameraPreviewOptions.put("captureDevice", captureDevice); + } catch (JSONException e) { + e.printStackTrace(); + } + fragment = new CameraPreviewFragment(cameraDirection, (err) -> { if (err != null) { callbackContext.error(err.getMessage()); @@ -272,6 +293,14 @@ private boolean deviceHasFlash(CallbackContext callbackContext) { return true; } + private boolean deviceHasUltraWideCamera(CallbackContext callbackContext) { + fragment.deviceHasUltraWideCamera((boolean result) -> { + PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, result); + callbackContext.sendPluginResult(pluginResult); + }); + return true; + } + private boolean torchSwitch(boolean torchState, CallbackContext callbackContext) { if (fragment == null) { callbackContext.error("Camera is closed, cannot switch " + torchState + " torch"); @@ -323,6 +352,19 @@ public void run() { } } + private boolean switchCameraTo(String device, CallbackContext callbackContext) { + if (fragment == null) { + callbackContext.error("Camera is closed, cannot switch camera"); + return true; + } + + fragment.switchCameraTo(device, (boolean result) -> { + PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, result); + callbackContext.sendPluginResult(pluginResult); + }); + return true; + } + public boolean hasAllPermissions() { for(String p : REQUIRED_PERMISSIONS) { if(!PermissionHelper.hasPermission(this, p)) { @@ -395,6 +437,7 @@ public void onRequestPermissionResult(int requestCode, String[] permissions, int } } } + @Override public void onDestroy() { diff --git a/src/ios/CameraSessionManager.h b/src/ios/CameraSessionManager.h index c0b006b..d3c82be 100644 --- a/src/ios/CameraSessionManager.h +++ b/src/ios/CameraSessionManager.h @@ -8,6 +8,8 @@ - (void) setupSession:(NSString *)defaultCamera completion:(void(^)(BOOL started))completion options:(NSDictionary *)options photoSettings:(AVCapturePhotoSettings *)photoSettings; - (void) setFlashMode:(NSInteger)flashMode photoSettings:(AVCapturePhotoSettings *)photoSettings; - (void) torchSwitch:(NSInteger)torchState; +- (void) switchCameraTo:(NSString *)cameraMode completion:(void (^)(BOOL success))completion; +- (BOOL) deviceHasUltraWideCamera; - (void) updateOrientation:(AVCaptureVideoOrientation)orientation; - (AVCaptureVideoOrientation) getCurrentOrientation:(UIInterfaceOrientation)toInterfaceOrientation; + (AVCaptureSessionPreset) calculateResolution:(NSInteger)targetSize; diff --git a/src/ios/CameraSessionManager.m b/src/ios/CameraSessionManager.m index bc8791c..b81042d 100644 --- a/src/ios/CameraSessionManager.m +++ b/src/ios/CameraSessionManager.m @@ -54,7 +54,13 @@ - (void) setupSession:(NSString *)defaultCamera completion:(void(^)(BOOL started self.defaultCamera = AVCaptureDevicePositionBack; } - AVCaptureDevice *videoDevice = [self cameraWithPosition: self.defaultCamera]; + AVCaptureDevice *videoDevice; + videoDevice = [self cameraWithPosition:self.defaultCamera captureDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera]; + if ([options[@"captureDevice"] isEqual:@"ultra-wide-angle"] && [self deviceHasUltraWideCamera]) { + if (@available(iOS 13.0, *)) { + videoDevice = [self cameraWithPosition:self.defaultCamera captureDeviceType:AVCaptureDeviceTypeBuiltInUltraWideCamera]; + } + } if ([videoDevice hasFlash]) { if ([videoDevice lockForConfiguration:&error]) { @@ -167,6 +173,67 @@ - (void) torchSwitch:(NSInteger)torchState{ } } +- (void)switchCameraTo:(NSString*)cameraMode completion:(void (^)(BOOL success))completion { + if (![self deviceHasUltraWideCamera]) { + if (completion) { + completion(NO); + } + return; + } + + dispatch_async(self.sessionQueue, ^{ + BOOL cameraSwitched = FALSE; + if (@available(iOS 13.0, *)) { + AVCaptureDevice *ultraWideCamera; + if([cameraMode isEqualToString:@"ultra-wide-angle"]) { + ultraWideCamera = [self cameraWithPosition:self.defaultCamera captureDeviceType:AVCaptureDeviceTypeBuiltInUltraWideCamera]; + } else { + ultraWideCamera = [self cameraWithPosition:self.defaultCamera captureDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera]; + } + if (ultraWideCamera) { + // Remove the current input + [self.session removeInput:self.videoDeviceInput]; + + // Create a new input with the ultra-wide camera + NSError *error = nil; + AVCaptureDeviceInput *ultraWideVideoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:ultraWideCamera error:&error]; + + if (!error) { + // Add the new input to the session + if ([self.session canAddInput:ultraWideVideoDeviceInput]) { + [self.session addInput:ultraWideVideoDeviceInput]; + self.videoDeviceInput = ultraWideVideoDeviceInput; + __block AVCaptureVideoOrientation orientation; + dispatch_sync(dispatch_get_main_queue(), ^{ + orientation = [self getCurrentOrientation]; + }); + [self updateOrientation:orientation]; + self.device = ultraWideCamera; + cameraSwitched = TRUE; + } else { + NSLog(@"Failed to add ultra-wide input to session"); + } + } else { + NSLog(@"Error creating ultra-wide device input: %@", error.localizedDescription); + } + } else { + NSLog(@"Ultra-wide camera not found"); + } + } + + completion ? completion(cameraSwitched): NULL; + }); +} + +- (BOOL)deviceHasUltraWideCamera { + if (@available(iOS 13.0, *)) { + AVCaptureDeviceDiscoverySession *discoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInUltraWideCamera] mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionUnspecified]; + return discoverySession.devices.count > 0; + } else { + return NO; + } +} + - (void)setFlashMode:(NSInteger)flashMode photoSettings:(AVCapturePhotoSettings *)photoSettings { NSError *error = nil; // Let's save the setting even if we can't set it up on this camera. @@ -186,8 +253,8 @@ - (void)setFlashMode:(NSInteger)flashMode photoSettings:(AVCapturePhotoSettings } } // Find a camera with the specified AVCaptureDevicePosition, returning nil if one is not found -- (AVCaptureDevice *) cameraWithPosition:(AVCaptureDevicePosition) position { - AVCaptureDeviceDiscoverySession *captureDeviceDiscoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera] mediaType:AVMediaTypeVideo position:self.defaultCamera]; +- (AVCaptureDevice *) cameraWithPosition:(AVCaptureDevicePosition) position captureDeviceType:(AVCaptureDeviceType) captureDeviceType { + AVCaptureDeviceDiscoverySession *captureDeviceDiscoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[ captureDeviceType] mediaType:AVMediaTypeVideo position:self.defaultCamera]; NSArray *devices = [captureDeviceDiscoverySession devices]; for (AVCaptureDevice *device in devices){ if ([device position] == position) diff --git a/src/ios/SimpleCameraPreview.h b/src/ios/SimpleCameraPreview.h index 018bb90..0e77694 100644 --- a/src/ios/SimpleCameraPreview.h +++ b/src/ios/SimpleCameraPreview.h @@ -16,6 +16,8 @@ - (void) capture:(CDVInvokedUrlCommand*)command; - (void) setSize:(CDVInvokedUrlCommand*)command; - (void) torchSwitch: (CDVInvokedUrlCommand*)command; +- (void) switchCameraTo: (CDVInvokedUrlCommand*) command; +- (void) deviceHasUltraWideCamera: (CDVInvokedUrlCommand*) command; - (void) deviceHasFlash: (CDVInvokedUrlCommand*)command; @property (nonatomic) CameraSessionManager *sessionManager; @property (nonatomic) CameraRenderController *cameraRenderController; diff --git a/src/ios/SimpleCameraPreview.m b/src/ios/SimpleCameraPreview.m index e2dd4a1..9455d12 100644 --- a/src/ios/SimpleCameraPreview.m +++ b/src/ios/SimpleCameraPreview.m @@ -65,22 +65,24 @@ - (void) enable:(CDVInvokedUrlCommand*)command { // Setup session self.sessionManager.delegate = self.cameraRenderController; - NSDictionary *setupSessionOptions; + NSMutableDictionary *setupSessionOptions = [NSMutableDictionary dictionary]; if (command.arguments.count > 0) { NSDictionary* config = command.arguments[0]; @try { if (config[@"targetSize"] != [NSNull null] && ![config[@"targetSize"] isEqual: @"null"]) { NSInteger targetSize = ((NSNumber*)config[@"targetSize"]).intValue; - setupSessionOptions = @{ @"targetSize" : [NSNumber numberWithInteger:targetSize] }; + [setupSessionOptions setValue:[NSNumber numberWithInteger:targetSize] forKey:@"targetSize"]; + } + NSString *captureDevice = config[@"captureDevice"]; + if (captureDevice && [captureDevice length] > 0) { + [setupSessionOptions setValue:captureDevice forKey:@"captureDevice"]; } } @catch(NSException *exception) { [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"targetSize not well defined"] callbackId:command.callbackId]; } } - self.photoSettings = [AVCapturePhotoSettings photoSettingsWithFormat:@{AVVideoCodecKey : AVVideoCodecTypeJPEG}]; - - [self.sessionManager setupSession:@"back" completion:^(BOOL started) { + self.photoSettings = [AVCapturePhotoSettings photoSettingsWithFormat:@{AVVideoCodecKey : AVVideoCodecTypeJPEG}]; [self.sessionManager setupSession:@"back" completion:^(BOOL started) { dispatch_async(dispatch_get_main_queue(), ^{ CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; [pluginResult setKeepCallbackAsBool:true]; @@ -152,6 +154,33 @@ - (void) torchSwitch:(CDVInvokedUrlCommand*)command{ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } +- (void) switchCameraTo:(CDVInvokedUrlCommand*)command{ + NSString *device = [command.arguments objectAtIndex:0]; + BOOL cameraSwitched = FALSE; + if (self.sessionManager != nil) { + [self.sessionManager switchCameraTo: device completion:^(BOOL success) { + if (success) { + NSLog(@"Camera switched successfully"); + CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:TRUE]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } else { + NSLog(@"Failed to switch camera"); + CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:FALSE]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; + } + }]; + } +} + +- (void) deviceHasUltraWideCamera:(CDVInvokedUrlCommand *)command{ + BOOL hasUltraWideCamera = NO; + if (self.sessionManager != nil) { + hasUltraWideCamera = [self.sessionManager deviceHasUltraWideCamera]; + } + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:hasUltraWideCamera]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; +} + - (void) deviceHasFlash:(CDVInvokedUrlCommand*)command{ AVCaptureDeviceDiscoverySession *captureDeviceDiscoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera] mediaType:AVMediaTypeVideo @@ -188,7 +217,6 @@ - (void) capture:(CDVInvokedUrlCommand*)command { } } - - (NSDictionary *)getGPSDictionaryForLocation { if (!currentLocation) return nil; diff --git a/www/SimpleCameraPreview.js b/www/SimpleCameraPreview.js index b1f4d96..7b1b9e8 100755 --- a/www/SimpleCameraPreview.js +++ b/www/SimpleCameraPreview.js @@ -28,8 +28,18 @@ SimpleCameraPreview.torchSwitch = function (options, onSuccess, onError) { exec(onSuccess, onError, PLUGIN_NAME, "torchSwitch", [options]); }; +SimpleCameraPreview.switchCameraTo = function (options, onSuccess, onError) { + options = options || {}; + options.captureDevice = options.captureDevice || "default"; + exec(onSuccess, onError, PLUGIN_NAME, "switchCameraTo", [options.captureDevice]); +}; + SimpleCameraPreview.deviceHasFlash = function (onSuccess, onError) { exec(onSuccess, onError, PLUGIN_NAME, "deviceHasFlash", []); }; +SimpleCameraPreview.deviceHasUltraWideCamera = function (onSuccess, onError) { + exec(onSuccess, onError, PLUGIN_NAME, "deviceHasUltraWideCamera", []); +}; + module.exports = SimpleCameraPreview;