@carviz/capacitor-camera-preview 8.0.1 → 8.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -45,6 +45,7 @@ public class CameraActivity extends Fragment {
45
45
  void onSnapshotTakenError(String message);
46
46
  void onBackButton();
47
47
  void onCameraStarted();
48
+ void onCameraStartError(String message);
48
49
  }
49
50
 
50
51
  public interface ZoomChangeListener {
@@ -324,7 +325,16 @@ public class CameraActivity extends Fragment {
324
325
  public void onResume() {
325
326
  super.onResume();
326
327
 
327
- mCamera = Camera.open(defaultCameraId);
328
+ try {
329
+ mCamera = Camera.open(defaultCameraId);
330
+ } catch (RuntimeException e) {
331
+ Log.e(TAG, "Failed to open camera on resume", e);
332
+ mCamera = null;
333
+ if (eventListener != null) {
334
+ eventListener.onCameraStartError(e.getMessage() != null ? e.getMessage() : "Failed to open camera");
335
+ }
336
+ return;
337
+ }
328
338
 
329
339
  if (cameraParameters != null) {
330
340
  mCamera.setParameters(cameraParameters);
@@ -789,25 +799,25 @@ public class CameraActivity extends Fragment {
789
799
 
790
800
  public void setFocusArea(final int pointX, final int pointY, final Camera.AutoFocusCallback callback) {
791
801
  if (mCamera != null) {
792
- mCamera.cancelAutoFocus();
802
+ try {
803
+ mCamera.cancelAutoFocus();
793
804
 
794
- Camera.Parameters parameters = mCamera.getParameters();
795
-
796
- // Store the original focus mode to restore it later
797
- final String originalFocusMode = parameters.getFocusMode();
805
+ Camera.Parameters parameters = mCamera.getParameters();
798
806
 
799
- Rect focusRect = calculateTapArea(pointX, pointY, 1f);
800
- parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
801
- parameters.setFocusAreas(Arrays.asList(new Camera.Area(focusRect, 1000)));
807
+ // Store the original focus mode to restore it later
808
+ final String originalFocusMode = parameters.getFocusMode();
802
809
 
803
- if (parameters.getMaxNumMeteringAreas() > 0) {
804
- Rect meteringRect = calculateTapArea(pointX, pointY, 1.5f);
805
- parameters.setMeteringAreas(Arrays.asList(new Camera.Area(meteringRect, 1000)));
806
- }
810
+ Rect focusRect = calculateTapArea(pointX, pointY, 1f);
811
+ parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
812
+ parameters.setFocusAreas(Arrays.asList(new Camera.Area(focusRect, 1000)));
813
+
814
+ if (parameters.getMaxNumMeteringAreas() > 0) {
815
+ Rect meteringRect = calculateTapArea(pointX, pointY, 1.5f);
816
+ parameters.setMeteringAreas(Arrays.asList(new Camera.Area(meteringRect, 1000)));
817
+ }
807
818
 
808
- try {
809
819
  setCameraParameters(parameters);
810
-
820
+
811
821
  // Wrap the callback to restore focus mode after autofocus completes
812
822
  mCamera.autoFocus(new Camera.AutoFocusCallback() {
813
823
  @Override
@@ -440,6 +440,19 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
440
440
  bridge.releaseCall(pluginCall);
441
441
  }
442
442
 
443
+ @Override
444
+ public void onCameraStartError(String message) {
445
+ PluginCall pluginCall = bridge.getSavedCall(cameraStartCallbackId);
446
+ if (pluginCall != null) {
447
+ pluginCall.reject(message);
448
+ bridge.releaseCall(pluginCall);
449
+ cameraStartCallbackId = "";
450
+ }
451
+ JSObject result = new JSObject();
452
+ result.put("message", message);
453
+ notifyListeners("cameraStartError", result);
454
+ }
455
+
443
456
  @Override
444
457
  public void onZoomChanged(float zoom) {
445
458
  JSObject result = new JSObject();
@@ -477,7 +490,7 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
477
490
  new View.OnTouchListener() {
478
491
  @Override
479
492
  public boolean onTouch(View v, MotionEvent event) {
480
- if ((null != fragment) && (fragment.toBack == true)) {
493
+ if (fragment != null && fragment.toBack && fragment.frameContainerLayout != null) {
481
494
  fragment.frameContainerLayout.dispatchTouchEvent(event);
482
495
  }
483
496
  return false;
@@ -62,9 +62,9 @@ class Preview extends RelativeLayout implements SurfaceHolder.Callback, TextureV
62
62
  }
63
63
 
64
64
  public void setCamera(Camera camera, int cameraId) {
65
+ mCamera = camera;
66
+ this.cameraId = cameraId;
65
67
  if (camera != null) {
66
- mCamera = camera;
67
- this.cameraId = cameraId;
68
68
  mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
69
69
  setCameraDisplayOrientation();
70
70
 
@@ -101,46 +101,58 @@ class Preview extends RelativeLayout implements SurfaceHolder.Callback, TextureV
101
101
  }
102
102
 
103
103
  public void setCameraDisplayOrientation() {
104
- Camera.CameraInfo info = new Camera.CameraInfo();
105
- int rotation = ((Activity) getContext()).getWindowManager().getDefaultDisplay().getRotation();
106
- int degrees = 0;
107
- DisplayMetrics dm = new DisplayMetrics();
108
-
109
- Camera.getCameraInfo(cameraId, info);
110
- ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(dm);
111
-
112
- switch (rotation) {
113
- case Surface.ROTATION_0:
114
- degrees = 0;
115
- break;
116
- case Surface.ROTATION_90:
117
- degrees = 90;
118
- break;
119
- case Surface.ROTATION_180:
120
- degrees = 180;
121
- break;
122
- case Surface.ROTATION_270:
123
- degrees = 270;
124
- break;
125
- }
126
- facing = info.facing;
127
- if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
128
- displayOrientation = (info.orientation + degrees) % 360;
129
- displayOrientation = (360 - displayOrientation) % 360;
130
- } else {
131
- displayOrientation = (info.orientation - degrees + 360) % 360;
104
+ if (mCamera == null) {
105
+ return;
132
106
  }
107
+ try {
108
+ Camera.CameraInfo info = new Camera.CameraInfo();
109
+ int rotation = ((Activity) getContext()).getWindowManager().getDefaultDisplay().getRotation();
110
+ int degrees = 0;
111
+ DisplayMetrics dm = new DisplayMetrics();
112
+
113
+ Camera.getCameraInfo(cameraId, info);
114
+ ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(dm);
115
+
116
+ switch (rotation) {
117
+ case Surface.ROTATION_0:
118
+ degrees = 0;
119
+ break;
120
+ case Surface.ROTATION_90:
121
+ degrees = 90;
122
+ break;
123
+ case Surface.ROTATION_180:
124
+ degrees = 180;
125
+ break;
126
+ case Surface.ROTATION_270:
127
+ degrees = 270;
128
+ break;
129
+ }
130
+ facing = info.facing;
131
+ if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
132
+ displayOrientation = (info.orientation + degrees) % 360;
133
+ displayOrientation = (360 - displayOrientation) % 360;
134
+ } else {
135
+ displayOrientation = (info.orientation - degrees + 360) % 360;
136
+ }
133
137
 
134
- Log.d(TAG, "screen is rotated " + degrees + "deg from natural");
135
- Log.d(
136
- TAG,
137
- (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT ? "front" : "back") +
138
- " camera is oriented -" +
139
- info.orientation +
140
- "deg from natural"
141
- );
142
- Log.d(TAG, "need to rotate preview " + displayOrientation + "deg");
143
- mCamera.setDisplayOrientation(displayOrientation);
138
+ Log.d(TAG, "screen is rotated " + degrees + "deg from natural");
139
+ Log.d(
140
+ TAG,
141
+ (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT ? "front" : "back") +
142
+ " camera is oriented -" +
143
+ info.orientation +
144
+ "deg from natural"
145
+ );
146
+ Log.d(TAG, "need to rotate preview " + displayOrientation + "deg");
147
+ mCamera.setDisplayOrientation(displayOrientation);
148
+ } catch (RuntimeException e) {
149
+ // The Camera1 handle can be released / mid-teardown / not yet fully opened when an
150
+ // orientation or configuration change arrives (screen-orientation lock/unlock, device
151
+ // rotation, or leaving the camera screen). In that state Camera.setDisplayOrientation()
152
+ // throws "set display orientation failed". Swallow it: the preview is either going away,
153
+ // or the orientation is re-applied by startCamera() on the next valid surface pass.
154
+ Log.e(TAG, "setCameraDisplayOrientation failed; camera in invalid state", e);
155
+ }
144
156
  }
145
157
 
146
158
  public void switchCamera(Camera camera, int cameraId) {
@@ -328,7 +340,10 @@ class Preview extends RelativeLayout implements SurfaceHolder.Callback, TextureV
328
340
  Camera.Parameters parameters = mCamera.getParameters();
329
341
  parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
330
342
  requestLayout();
331
- //mCamera.setDisplayOrientation(90);
343
+ // Re-apply orientation on a camera just confirmed alive by getParameters() above. This
344
+ // self-heals if setCameraDisplayOrientation() was swallowed during a config-change race:
345
+ // a rotation resizes the surface, so surfaceChanged -> startCamera() runs here.
346
+ setCameraDisplayOrientation();
332
347
  mCamera.setParameters(parameters);
333
348
  mCamera.startPreview();
334
349
  }
@@ -62,6 +62,10 @@ export interface CameraZoomChangeEvent {
62
62
  /** The new zoom level */
63
63
  zoom: number;
64
64
  }
65
+ export interface CameraStartErrorEvent {
66
+ /** The error message from the native camera service */
67
+ message: string;
68
+ }
65
69
  export interface CameraPreviewPosition {
66
70
  /** The x position in points (iOS) or dp (Android) */
67
71
  x: number;
@@ -125,6 +129,8 @@ export interface CameraPreviewPlugin {
125
129
  requestPermissions(): Promise<PermissionState>;
126
130
  /** Listen for zoom changes - Android / iOS only */
127
131
  addListener(eventName: 'zoomChanged', listenerFunc: (event: CameraZoomChangeEvent) => void): Promise<PluginListenerHandle>;
132
+ /** Listen for camera start failures (e.g. the camera service rejecting an open on resume) - Android only */
133
+ addListener(eventName: 'cameraStartError', listenerFunc: (event: CameraStartErrorEvent) => void): Promise<PluginListenerHandle>;
128
134
  /** Remove all listeners for this plugin */
129
135
  removeAllListeners(): Promise<void>;
130
136
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carviz/capacitor-camera-preview",
3
- "version": "8.0.1",
3
+ "version": "8.0.3",
4
4
  "description": "Fork of the capacitor-community/camera-preview plugin focusing on high resolution photos without bloating up the code.",
5
5
  "type": "module",
6
6
  "main": "dist/plugin.cjs.js",