@capacitor-community/camera-preview 1.1.3 → 2.0.0-beta.2

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.
@@ -1,8 +1,8 @@
1
1
  package com.ahm.capacitor.camera.preview;
2
2
 
3
- import android.Manifest;
4
3
  import android.app.FragmentManager;
5
4
  import android.app.FragmentTransaction;
5
+ import android.content.pm.ActivityInfo;
6
6
  import android.graphics.Color;
7
7
  import android.graphics.Point;
8
8
  import android.hardware.Camera;
@@ -13,33 +13,40 @@ import android.view.ViewGroup;
13
13
  import android.widget.FrameLayout;
14
14
 
15
15
  import com.getcapacitor.JSObject;
16
- import com.getcapacitor.NativePlugin;
16
+ import com.getcapacitor.Logger;
17
+ import com.getcapacitor.PermissionState;
17
18
  import com.getcapacitor.Plugin;
18
19
  import com.getcapacitor.PluginCall;
19
20
  import com.getcapacitor.PluginMethod;
21
+ import com.getcapacitor.annotation.CapacitorPlugin;
22
+ import com.getcapacitor.annotation.Permission;
23
+ import com.getcapacitor.annotation.PermissionCallback;
20
24
 
21
25
  import org.json.JSONArray;
22
- import org.json.JSONException;
23
- import org.json.JSONObject;
24
26
 
25
- import java.util.List;
26
27
  import java.io.File;
28
+ import java.util.List;
27
29
 
28
- @NativePlugin(
30
+ import static android.Manifest.permission.CAMERA;
31
+
32
+ @CapacitorPlugin(
33
+ name = "CameraPreview",
29
34
  permissions = {
30
- Manifest.permission.CAMERA,
31
- Manifest.permission.RECORD_AUDIO,
32
- Manifest.permission.WRITE_EXTERNAL_STORAGE,
33
- Manifest.permission.READ_EXTERNAL_STORAGE
34
- },
35
- requestCodes = {
36
- CameraPreview.REQUEST_CAMERA_PERMISSION
35
+ @Permission(strings = {CAMERA}, alias = CameraPreview.CAMERA_PERMISSION_ALIAS)
37
36
  }
38
37
  )
39
38
  public class CameraPreview extends Plugin implements CameraActivity.CameraPreviewListener {
39
+ static final String CAMERA_PERMISSION_ALIAS = "camera";
40
+
40
41
  private static String VIDEO_FILE_PATH = "";
41
42
  private static String VIDEO_FILE_EXTENSION = ".mp4";
42
- static final int REQUEST_CAMERA_PERMISSION = 1234;
43
+
44
+ private String captureCallbackId = "";
45
+ private String snapshotCallbackId = "";
46
+ private String recordCallbackId = "";
47
+
48
+ // keep track of previously specified orientation to support locking orientation:
49
+ private int previousOrientationRequest = -1;
43
50
 
44
51
  private CameraActivity fragment;
45
52
  private int containerViewId = 20;
@@ -50,26 +57,19 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
50
57
 
51
58
  JSObject ret = new JSObject();
52
59
  ret.put("value", value);
53
- call.success(ret);
60
+ call.resolve(ret);
54
61
  }
55
62
 
56
63
  @PluginMethod()
57
64
  public void start(PluginCall call) {
58
- saveCall(call);
59
-
60
- if (hasRequiredPermissions()) {
65
+ if (PermissionState.GRANTED.equals(getPermissionState(CAMERA_PERMISSION_ALIAS))) {
61
66
  startCamera(call);
62
67
  } else {
63
- pluginRequestPermissions(new String[]{
64
- Manifest.permission.CAMERA,
65
- Manifest.permission.RECORD_AUDIO,
66
- Manifest.permission.WRITE_EXTERNAL_STORAGE,
67
- Manifest.permission.READ_EXTERNAL_STORAGE
68
- }, REQUEST_CAMERA_PERMISSION);
68
+ requestPermissionForAlias(CAMERA_PERMISSION_ALIAS, call, "handleCameraPermissionResult");
69
69
  }
70
70
  }
71
71
 
72
- @PluginMethod
72
+ @PluginMethod()
73
73
  public void flip(PluginCall call) {
74
74
  try {
75
75
  fragment.switchCamera();
@@ -82,11 +82,11 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
82
82
  @PluginMethod()
83
83
  public void capture(PluginCall call) {
84
84
  if(this.hasCamera(call) == false){
85
- call.error("Camera is not running");
85
+ call.reject("Camera is not running");
86
86
  return;
87
87
  }
88
-
89
- saveCall(call);
88
+ bridge.saveCall(call);
89
+ captureCallbackId = call.getCallbackId();
90
90
 
91
91
  Integer quality = call.getInt("quality", 85);
92
92
  // Image Dimensions - Optional
@@ -95,6 +95,19 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
95
95
  fragment.takePicture(width, height, quality);
96
96
  }
97
97
 
98
+ @PluginMethod()
99
+ public void captureSample(PluginCall call) {
100
+ if(this.hasCamera(call) == false){
101
+ call.reject("Camera is not running");
102
+ return;
103
+ }
104
+ bridge.saveCall(call);
105
+ snapshotCallbackId = call.getCallbackId();
106
+
107
+ Integer quality = call.getInt("quality", 85);
108
+ fragment.takeSnapshot(quality);
109
+ }
110
+
98
111
  @PluginMethod()
99
112
  public void stop(final PluginCall call) {
100
113
  bridge.getActivity().runOnUiThread(new Runnable() {
@@ -102,6 +115,9 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
102
115
  public void run() {
103
116
  FrameLayout containerView = getBridge().getActivity().findViewById(containerViewId);
104
117
 
118
+ // allow orientation changes after closing camera:
119
+ getBridge().getActivity().setRequestedOrientation(previousOrientationRequest);
120
+
105
121
  if (containerView != null) {
106
122
  ((ViewGroup)getBridge().getWebView().getParent()).removeView(containerView);
107
123
  getBridge().getWebView().setBackgroundColor(Color.WHITE);
@@ -111,7 +127,7 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
111
127
  fragmentTransaction.commit();
112
128
  fragment = null;
113
129
 
114
- call.success();
130
+ call.resolve();
115
131
  } else {
116
132
  call.reject("camera already stopped");
117
133
  }
@@ -122,7 +138,7 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
122
138
  @PluginMethod()
123
139
  public void getSupportedFlashModes(PluginCall call) {
124
140
  if(this.hasCamera(call) == false){
125
- call.error("Camera is not running");
141
+ call.reject("Camera is not running");
126
142
  return;
127
143
  }
128
144
 
@@ -140,20 +156,20 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
140
156
 
141
157
  JSObject jsObject = new JSObject();
142
158
  jsObject.put("result", jsonFlashModes);
143
- call.success(jsObject);
159
+ call.resolve(jsObject);
144
160
 
145
161
  }
146
162
 
147
163
  @PluginMethod()
148
164
  public void setFlashMode(PluginCall call) {
149
165
  if(this.hasCamera(call) == false){
150
- call.error("Camera is not running");
166
+ call.reject("Camera is not running");
151
167
  return;
152
168
  }
153
169
 
154
170
  String flashMode = call.getString("flashMode");
155
171
  if(flashMode == null || flashMode.isEmpty() == true) {
156
- call.error("flashMode required parameter is missing");
172
+ call.reject("flashMode required parameter is missing");
157
173
  return;
158
174
  }
159
175
 
@@ -165,36 +181,75 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
165
181
  if (supportedFlashModes.indexOf(flashMode) > -1) {
166
182
  params.setFlashMode(flashMode);
167
183
  } else {
168
- call.error("Flash mode not recognised: " + flashMode);
184
+ call.reject("Flash mode not recognised: " + flashMode);
169
185
  return;
170
186
  }
171
187
 
172
188
  fragment.setCameraParameters(params);
173
189
 
174
- call.success();
190
+ call.resolve();
175
191
  }
176
192
 
177
- @Override
178
- protected void handleRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
179
- super.handleRequestPermissionsResult(requestCode, permissions, grantResults);
180
- if (requestCode == REQUEST_CAMERA_PERMISSION) {
181
- boolean permissionsGranted = true;
182
- for (int grantResult: grantResults) {
183
- if (grantResult != 0) {
184
- permissionsGranted = false;
185
- }
186
- }
193
+ @PluginMethod()
194
+ public void startRecordVideo(final PluginCall call) {
195
+ if(this.hasCamera(call) == false){
196
+ call.reject("Camera is not running");
197
+ return;
198
+ }
199
+ final String filename = "videoTmp";
200
+ VIDEO_FILE_PATH = getActivity().getCacheDir().toString() + "/";
187
201
 
188
- PluginCall savedCall = getSavedCall();
189
- if (permissionsGranted) {
190
- startCamera(savedCall);
191
- } else {
192
- savedCall.reject("permission failed");
202
+ final String position = call.getString("position", "front");
203
+ final Integer width = call.getInt("width", 0);
204
+ final Integer height = call.getInt("height", 0);
205
+ final Boolean withFlash = call.getBoolean("withFlash", false);
206
+ final Integer maxDuration = call.getInt("maxDuration", 0);
207
+ // final Integer quality = call.getInt("quality", 0);
208
+ bridge.saveCall(call);
209
+ recordCallbackId = call.getCallbackId();
210
+
211
+ bridge.getActivity().runOnUiThread(new Runnable() {
212
+ @Override
213
+ public void run() {
214
+ // fragment.startRecord(getFilePath(filename), position, width, height, quality, withFlash);
215
+ fragment.startRecord(getFilePath(filename), position, width, height, 70, withFlash, maxDuration);
193
216
  }
217
+ });
218
+
219
+ call.resolve();
220
+ }
221
+
222
+ @PluginMethod()
223
+ public void stopRecordVideo(PluginCall call) {
224
+ if(this.hasCamera(call) == false){
225
+ call.reject("Camera is not running");
226
+ return;
194
227
  }
195
228
 
229
+ System.out.println("stopRecordVideo - Callbackid=" + call.getCallbackId());
230
+
231
+ bridge.saveCall(call);
232
+ recordCallbackId = call.getCallbackId();
233
+
234
+ // bridge.getActivity().runOnUiThread(new Runnable() {
235
+ // @Override
236
+ // public void run() {
237
+ // fragment.stopRecord();
238
+ // }
239
+ // });
196
240
 
241
+ fragment.stopRecord();
242
+ // call.resolve();
243
+ }
197
244
 
245
+ @PermissionCallback
246
+ private void handleCameraPermissionResult(PluginCall call) {
247
+ if (PermissionState.GRANTED.equals(getPermissionState(CAMERA_PERMISSION_ALIAS))) {
248
+ startCamera(call);
249
+ } else {
250
+ Logger.debug(getLogTag(), "User denied camera permission: " + getPermissionState(CAMERA_PERMISSION_ALIAS).toString());
251
+ call.reject("Permission failed: user denied access to camera.");
252
+ }
198
253
  }
199
254
 
200
255
  private void startCamera(final PluginCall call) {
@@ -215,6 +270,8 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
215
270
  final Boolean toBack = call.getBoolean("toBack", false);
216
271
  final Boolean storeToFile = call.getBoolean("storeToFile", false);
217
272
  final Boolean disableExifHeaderStripping = call.getBoolean("disableExifHeaderStripping", true);
273
+ final Boolean lockOrientation = call.getBoolean("lockAndroidOrientation", false);
274
+ previousOrientationRequest = getBridge().getActivity().getRequestedOrientation();
218
275
 
219
276
  fragment = new CameraActivity();
220
277
  fragment.setEventListener(this);
@@ -230,6 +287,11 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
230
287
  @Override
231
288
  public void run() {
232
289
  DisplayMetrics metrics = getBridge().getActivity().getResources().getDisplayMetrics();
290
+ // lock orientation if specified in options:
291
+ if (lockOrientation) {
292
+ getBridge().getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
293
+ }
294
+
233
295
  // offset
234
296
  int computedX = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, x, metrics);
235
297
  int computedY = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, y, metrics);
@@ -283,7 +345,7 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
283
345
  fragmentTransaction.add(containerView.getId(), fragment);
284
346
  fragmentTransaction.commit();
285
347
 
286
- call.success();
348
+ call.resolve();
287
349
  } else {
288
350
  call.reject("camera already started");
289
351
  }
@@ -291,7 +353,6 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
291
353
  });
292
354
  }
293
355
 
294
-
295
356
  @Override
296
357
  protected void handleOnResume() {
297
358
  super.handleOnResume();
@@ -301,29 +362,24 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
301
362
  public void onPictureTaken(String originalPicture) {
302
363
  JSObject jsObject = new JSObject();
303
364
  jsObject.put("value", originalPicture);
304
- getSavedCall().success(jsObject);
365
+ bridge.getSavedCall(captureCallbackId).resolve(jsObject);
305
366
  }
306
367
 
307
368
  @Override
308
369
  public void onPictureTakenError(String message) {
309
- getSavedCall().reject(message);
370
+ bridge.getSavedCall(captureCallbackId).reject(message);
310
371
  }
311
372
 
312
373
  @Override
313
374
  public void onSnapshotTaken(String originalPicture) {
314
- JSONArray data = new JSONArray();
315
- data.put(originalPicture);
316
-
317
- PluginCall call = getSavedCall();
318
-
319
375
  JSObject jsObject = new JSObject();
320
- jsObject.put("result", data);
321
- call.success(jsObject);
376
+ jsObject.put("value", originalPicture);
377
+ bridge.getSavedCall(snapshotCallbackId).resolve(jsObject);
322
378
  }
323
379
 
324
380
  @Override
325
381
  public void onSnapshotTakenError(String message) {
326
- getSavedCall().reject(message);
382
+ bridge.getSavedCall(snapshotCallbackId).reject(message);
327
383
  }
328
384
 
329
385
  @Override
@@ -343,9 +399,7 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
343
399
 
344
400
  @Override
345
401
  public void onCameraStarted() {
346
- PluginCall pluginCall = getSavedCall();
347
402
  System.out.println("camera started");
348
- pluginCall.success();
349
403
  }
350
404
 
351
405
  @Override
@@ -354,20 +408,22 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
354
408
  }
355
409
  @Override
356
410
  public void onStartRecordVideoError(String message) {
357
- getSavedCall().reject(message);
411
+ bridge.getSavedCall(recordCallbackId).reject(message);
358
412
  }
359
413
  @Override
360
414
  public void onStopRecordVideo(String file) {
361
- PluginCall pluginCall = getSavedCall();
415
+ PluginCall pluginCall = bridge.getSavedCall(recordCallbackId);
362
416
  JSObject jsObject = new JSObject();
363
417
  jsObject.put("videoFilePath", file);
364
- pluginCall.success(jsObject);
418
+ pluginCall.resolve(jsObject);
365
419
  }
366
420
  @Override
367
421
  public void onStopRecordVideoError(String error) {
368
- getSavedCall().reject(error);
422
+ bridge.getSavedCall(recordCallbackId).reject(error);
369
423
  }
370
424
 
425
+
426
+
371
427
  private boolean hasView(PluginCall call) {
372
428
  if(fragment == null) {
373
429
  return false;
@@ -388,62 +444,15 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
388
444
  return true;
389
445
  }
390
446
 
391
- @PluginMethod()
392
- public void startRecordVideo(final PluginCall call) {
393
- if(this.hasCamera(call) == false){
394
- call.error("Camera is not running");
395
- return;
396
- }
397
- final String filename = "videoTmp";
398
- VIDEO_FILE_PATH = getActivity().getCacheDir().toString() + "/";
399
-
400
- final String position = call.getString("position", "front");
401
- final Integer width = call.getInt("width", 0);
402
- final Integer height = call.getInt("height", 0);
403
- final Boolean withFlash = call.getBoolean("withFlash", false);
404
- final Integer maxDuration = call.getInt("maxDuration", 0);
405
- // final Integer quality = call.getInt("quality", 0);
406
-
407
- bridge.getActivity().runOnUiThread(new Runnable() {
408
- @Override
409
- public void run() {
410
- // fragment.startRecord(getFilePath(filename), position, width, height, quality, withFlash);
411
- fragment.startRecord(getFilePath(filename), position, width, height, 70, withFlash, maxDuration);
412
- }
413
- });
414
-
415
- call.success();
416
- }
417
-
418
- @PluginMethod()
419
- public void stopRecordVideo(PluginCall call) {
420
- if(this.hasCamera(call) == false){
421
- call.error("Camera is not running");
422
- return;
423
- }
424
-
425
- saveCall(call);
426
-
427
- // bridge.getActivity().runOnUiThread(new Runnable() {
428
- // @Override
429
- // public void run() {
430
- // fragment.stopRecord();
431
- // }
432
- // });
433
-
434
- fragment.stopRecord();
435
- // call.success();
436
- }
437
-
438
447
  private String getFilePath(String filename) {
439
448
  String fileName = filename;
440
449
 
441
450
  int i = 1;
442
451
 
443
452
  while (new File(VIDEO_FILE_PATH + fileName + VIDEO_FILE_EXTENSION).exists()) {
444
- // Add number suffix if file exists
445
- fileName = filename + '_' + i;
446
- i++;
453
+ // Add number suffix if file exists
454
+ fileName = filename + '_' + i;
455
+ i++;
447
456
  }
448
457
 
449
458
  return VIDEO_FILE_PATH + fileName + VIDEO_FILE_EXTENSION;
@@ -1,8 +1,3 @@
1
- declare module "@capacitor/core" {
2
- interface PluginRegistry {
3
- CameraPreview: CameraPreviewPlugin;
4
- }
5
- }
6
1
  export declare type CameraPosition = 'rear' | 'front';
7
2
  export interface CameraPreviewOptions {
8
3
  /** Parent element to attach the video preview element to (applicable to the web platform only) */
@@ -29,6 +24,12 @@ export interface CameraPreviewOptions {
29
24
  storeToFile?: boolean;
30
25
  /** Defaults to false - Android Only - Disable automatic rotation of the image, and let the browser deal with it (keep reading on how to achieve it) */
31
26
  disableExifHeaderStripping?: boolean;
27
+ /** Defaults to false - iOS only - Activate high resolution image capture so that output images are from the highest resolution possible on the device **/
28
+ enableHighResolution?: boolean;
29
+ /** Defaults to false - Web only - Disables audio stream to prevent permission requests and output switching */
30
+ disableAudio?: boolean;
31
+ /** Defaults to false - Android Only - Locks device orientation when camera is showing. */
32
+ lockAndroidOrientation?: boolean;
32
33
  }
33
34
  export interface CameraPreviewPictureOptions {
34
35
  /** The picture height, optional, default 0 (Device default) */
@@ -38,6 +39,10 @@ export interface CameraPreviewPictureOptions {
38
39
  /** The picture quality, 0 - 100, default 85 */
39
40
  quality?: number;
40
41
  }
42
+ export interface CameraSampleOptions {
43
+ /** The picture quality, 0 - 100, default 85 */
44
+ quality?: number;
45
+ }
41
46
  export declare type CameraPreviewFlashMode = 'off' | 'on' | 'auto' | 'red-eye' | 'torch';
42
47
  export interface CameraPreviewPlugin {
43
48
  start(options: CameraPreviewOptions): Promise<{}>;
@@ -45,6 +50,9 @@ export interface CameraPreviewPlugin {
45
50
  capture(options: CameraPreviewPictureOptions): Promise<{
46
51
  value: string;
47
52
  }>;
53
+ captureSample(options: CameraSampleOptions): Promise<{
54
+ value: string;
55
+ }>;
48
56
  getSupportedFlashModes(): Promise<{
49
57
  result: CameraPreviewFlashMode[];
50
58
  }>;
@@ -1 +1,2 @@
1
+ export {};
1
2
  //# sourceMappingURL=definitions.js.map
@@ -1,2 +1,4 @@
1
+ import { CameraPreviewPlugin } from './definitions';
2
+ declare const CameraPreview: CameraPreviewPlugin;
1
3
  export * from './definitions';
2
- export * from './web';
4
+ export { CameraPreview };
package/dist/esm/index.js CHANGED
@@ -1,3 +1,7 @@
1
+ import { registerPlugin } from '@capacitor/core';
2
+ const CameraPreview = registerPlugin('CameraPreview', {
3
+ web: () => import('./web').then(m => new m.CameraPreviewWeb()),
4
+ });
1
5
  export * from './definitions';
2
- export * from './web';
6
+ export { CameraPreview };
3
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,OAAO,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAG/C,MAAM,aAAa,GAAG,cAAc,CAAsB,eAAe,EAAE;IACzE,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;CAC/D,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAC,aAAa,EAAC,CAAC"}
package/dist/esm/web.d.ts CHANGED
@@ -1,10 +1,16 @@
1
1
  import { WebPlugin } from "@capacitor/core";
2
- import { CameraPreviewOptions, CameraPreviewPictureOptions, CameraPreviewPlugin, CameraPreviewFlashMode } from "./definitions";
2
+ import { CameraPreviewOptions, CameraPreviewPictureOptions, CameraPreviewPlugin, CameraPreviewFlashMode, CameraSampleOptions } from "./definitions";
3
3
  export declare class CameraPreviewWeb extends WebPlugin implements CameraPreviewPlugin {
4
+ /**
5
+ * track which camera is used based on start options
6
+ * used in capture
7
+ */
8
+ private isBackCamera;
4
9
  constructor();
5
10
  start(options: CameraPreviewOptions): Promise<{}>;
6
11
  stop(): Promise<any>;
7
12
  capture(_options: CameraPreviewPictureOptions): Promise<any>;
13
+ captureSample(_options: CameraSampleOptions): Promise<any>;
8
14
  getSupportedFlashModes(): Promise<{
9
15
  result: CameraPreviewFlashMode[];
10
16
  }>;