@capacitor-community/camera-preview 2.0.0-beta.0 → 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.
Files changed (95) hide show
  1. package/CapacitorCommunityCameraPreview.podspec +3 -2
  2. package/LICENSE +21 -0
  3. package/README.md +46 -57
  4. package/android/build.gradle +4 -4
  5. package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +127 -118
  6. package/dist/esm/definitions.d.ts +9 -5
  7. package/dist/esm/definitions.js +1 -0
  8. package/dist/esm/index.d.ts +3 -1
  9. package/dist/esm/index.js +5 -1
  10. package/dist/esm/index.js.map +1 -1
  11. package/dist/esm/web.d.ts +7 -1
  12. package/dist/esm/web.js +89 -77
  13. package/dist/esm/web.js.map +1 -1
  14. package/ios/Plugin/CameraController.swift +155 -48
  15. package/ios/Plugin/Plugin.m +3 -0
  16. package/ios/Plugin/Plugin.swift +125 -46
  17. package/ios/Plugin.xcodeproj/project.pbxproj +2 -6
  18. package/ios/Podfile +2 -2
  19. package/ios/Podfile.lock +4 -4
  20. package/package.json +7 -6
  21. package/android/local.properties +0 -8
  22. package/ios/Plugin.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  23. package/ios/Plugin.xcodeproj/xcuserdata/nielsvanharen.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  24. package/ios/Plugin.xcworkspace/xcuserdata/ahernandez.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  25. package/ios/Plugin.xcworkspace/xcuserdata/arielhernandezmusa.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  26. package/ios/Plugin.xcworkspace/xcuserdata/nielsvanharen.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  27. package/ios/Pods/CapacitorCordova/LICENSE +0 -23
  28. package/ios/Pods/CapacitorCordova/README.md +0 -39
  29. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/CapacitorCordova.h +0 -21
  30. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/AppDelegate.h +0 -8
  31. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/AppDelegate.m +0 -5
  32. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDV.h +0 -28
  33. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVAvailability.h +0 -109
  34. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegate.h +0 -51
  35. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegateImpl.h +0 -39
  36. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegateImpl.m +0 -154
  37. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVConfigParser.h +0 -31
  38. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVConfigParser.m +0 -81
  39. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVInvokedUrlCommand.h +0 -52
  40. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVInvokedUrlCommand.m +0 -116
  41. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin.h +0 -81
  42. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin.m +0 -154
  43. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginManager.h +0 -25
  44. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginManager.m +0 -77
  45. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginResult.h +0 -82
  46. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginResult.m +0 -216
  47. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVScreenOrientationDelegate.h +0 -33
  48. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVUIWebViewDelegate.h +0 -41
  49. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVUIWebViewDelegate.m +0 -399
  50. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVURLProtocol.h +0 -27
  51. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVURLProtocol.m +0 -74
  52. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVUserAgentUtil.h +0 -27
  53. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVUserAgentUtil.m +0 -156
  54. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVViewController.h +0 -30
  55. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVViewController.m +0 -34
  56. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/NSDictionary+CordovaPreferences.h +0 -35
  57. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/NSDictionary+CordovaPreferences.m +0 -63
  58. package/ios/Pods/Local Podspecs/Capacitor.podspec.json +0 -31
  59. package/ios/Pods/Manifest.lock +0 -23
  60. package/ios/Pods/Pods.xcodeproj/project.pbxproj +0 -1296
  61. package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/Capacitor.xcscheme +0 -60
  62. package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/CapacitorCordova.xcscheme +0 -58
  63. package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/Pods-Plugin.xcscheme +0 -58
  64. package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/Pods-PluginTests.xcscheme +0 -58
  65. package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/xcschememanagement.plist +0 -39
  66. package/ios/Pods/Target Support Files/Capacitor/Capacitor-Info.plist +0 -26
  67. package/ios/Pods/Target Support Files/Capacitor/Capacitor-dummy.m +0 -5
  68. package/ios/Pods/Target Support Files/Capacitor/Capacitor-prefix.pch +0 -12
  69. package/ios/Pods/Target Support Files/Capacitor/Capacitor.debug.xcconfig +0 -13
  70. package/ios/Pods/Target Support Files/Capacitor/Capacitor.modulemap +0 -7
  71. package/ios/Pods/Target Support Files/Capacitor/Capacitor.release.xcconfig +0 -13
  72. package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-Info.plist +0 -26
  73. package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-dummy.m +0 -5
  74. package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-prefix.pch +0 -12
  75. package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-umbrella.h +0 -32
  76. package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.debug.xcconfig +0 -12
  77. package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.modulemap +0 -6
  78. package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.release.xcconfig +0 -12
  79. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-Info.plist +0 -26
  80. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-acknowledgements.markdown +0 -57
  81. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-acknowledgements.plist +0 -95
  82. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-dummy.m +0 -5
  83. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-umbrella.h +0 -16
  84. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.debug.xcconfig +0 -13
  85. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.modulemap +0 -6
  86. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.release.xcconfig +0 -13
  87. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-Info.plist +0 -26
  88. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-acknowledgements.markdown +0 -57
  89. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-acknowledgements.plist +0 -95
  90. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-dummy.m +0 -5
  91. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-frameworks.sh +0 -187
  92. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-umbrella.h +0 -16
  93. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.debug.xcconfig +0 -14
  94. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.modulemap +0 -6
  95. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.release.xcconfig +0 -14
@@ -1,13 +1,14 @@
1
1
 
2
2
  Pod::Spec.new do |s|
3
3
  s.name = 'CapacitorCommunityCameraPreview'
4
- s.version = '0.0.1'
4
+ s.version = '2.0.0'
5
5
  s.summary = 'Camera preview'
6
6
  s.license = 'MIT'
7
7
  s.homepage = 'https://github.com/capacitor-community/camera-preview.git'
8
8
  s.author = 'Ariel Hernandez Musa'
9
9
  s.source = { :git => 'https://github.com/capacitor-community/camera-preview.git', :tag => s.version.to_s }
10
10
  s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
11
- s.ios.deployment_target = '11.0'
11
+ s.ios.deployment_target = '12.0'
12
12
  s.dependency 'Capacitor'
13
+ s.swift_version = '5.1'
13
14
  end
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Ariel Hernandez Musa.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,10 +1,15 @@
1
- # Beta version with initial support for capacitor 3
2
-
3
- # Capacitor Camera Preview
1
+ <p align="center"><br><img src="https://user-images.githubusercontent.com/236501/85893648-1c92e880-b7a8-11ea-926d-95355b8175c7.png" width="128" height="128" /></p>
2
+ <h3 align="center">Capacitor Camera Preview</h3>
3
+ <p align="center"><strong><code>@capacitor-community/camera-preview</code></strong></p>
4
+ <br>
5
+ <p align="center"><strong>CAPACITOR 3</strong></p><br>
4
6
 
5
- Capacitor plugin that allows camera interaction from Javascript and HTML (based on cordova-plugin-camera-preview)
7
+ <p align="center">
8
+ Capacitor plugin that allows camera interaction from Javascript and HTML<br>(based on cordova-plugin-camera-preview).
9
+ </p>
10
+ <br>
6
11
 
7
- **Releases are being kept up to date when appropriate. However, this plugin is under constant development. As such it is recommended to use master to always have the latest fixes & features.**
12
+ Version 2 of this plugin is compatible with Ionic 5 and Capacitor 3. If your project uses Capacitor 2, please make sure you install [version 1](https://github.com/capacitor-community/camera-preview/releases/tag/v1.2.1) of this plugin.
8
13
 
9
14
  **PR's are greatly appreciated. Maintainer(s) wanted.**
10
15
 
@@ -25,22 +30,6 @@ Capacitor plugin that allows camera interaction from Javascript and HTML (based
25
30
 
26
31
  # Installation
27
32
 
28
- <!-- Use any one of the installation methods listed below depending on which framework you use. -->
29
-
30
- <!-- To install the master version with latest fixes and features -->
31
-
32
- <!-- ```
33
- cordova plugin add https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview.git
34
-
35
- ionic cordova plugin add https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview.git
36
-
37
- meteor add cordova:cordova-plugin-camera-preview@https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview.git#[latest_commit_id]
38
-
39
- <plugin spec="https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview.git" source="git" />
40
- ``` -->
41
-
42
- <!-- or if you want to use the last released version on npm -->
43
-
44
33
  ```
45
34
  yarn add @capacitor-community/camera-preview
46
35
 
@@ -53,44 +42,19 @@ Then run
53
42
  npx cap sync
54
43
  ```
55
44
 
56
- #### Android Quirks
57
-
58
- On Android remember to add the plugin to `MainActivity`
59
- ```java
60
- import com.ahm.capacitor.camera.preview.CameraPreview;
61
-
62
-
63
- this.init(savedInstanceState, new ArrayList<Class<? extends Plugin>>() {{
64
- // Additional plugins you've installed go here
65
- // Ex: add(TotallyAwesomePlugin.class);
66
- add(CameraPreview.class);
67
- }});
45
+ ## Extra Android installation steps
46
+ Open `android/app/src/main/AndroidManifest.xml` and above the closing `</manifest>` tag add this line to request the CAMERA permission:
47
+ ```xml
48
+ <uses-permission android:name="android.permission.CAMERA" />
68
49
  ```
50
+ For more help consult the [Capacitor docs](https://capacitorjs.com/docs/android/configuration#configuring-androidmanifestxml).
69
51
 
70
- #### Web Quirks
71
- Add `import '@capacitor-community/camera-preview'` to you entry script in ionic on `app.module.ts`, so capacitor can register the web platform from the plugin
72
- <!--
73
- #### iOS Quirks
74
- If you are developing for iOS 10+ you must also add the following to your config.xml
52
+ ## Extra iOS installation steps
53
+ You will need to add two permissions to `Info.plist`. Follow the [Capacitor docs](https://capacitorjs.com/docs/ios/configuration#configuring-infoplist) and add permissions with the raw keys `NSCameraUsageDescription` and `NSMicrophoneUsageDescription`.
75
54
 
76
- ```xml
77
- <config-file platform="ios" target="*-Info.plist" parent="NSCameraUsageDescription" overwrite="true">
78
- <string>Allow the app to use your camera</string>
79
- </config-file> -->
80
-
81
- <!-- or for Phonegap -->
55
+ ## Extra Web installation steps
56
+ Add `import '@capacitor-community/camera-preview'` to you entry script in ionic on `app.module.ts`, so capacitor can register the web platform from the plugin
82
57
 
83
- <!-- <gap:config-file platform="ios" target="*-Info.plist" parent="NSCameraUsageDescription" overwrite="true">
84
- <string>Allow the app to use your camera</string>
85
- </gap:config-file>
86
- ``` -->
87
- <!--
88
- #### Android Quirks (older devices)
89
- When using the plugin for older devices, the camera preview will take the focus inside the app once initialized.
90
- In order to prevent the app from closing when a user presses the back button, the event for the camera view is disabled.
91
- If you still want the user to navigate, you can add a listener for the back event for the preview
92
- (see <code>[onBackButton](#onBackButton)</code>)
93
- -->
94
58
 
95
59
  # Methods
96
60
 
@@ -112,6 +76,7 @@ Starts the camera preview instance.
112
76
  | storeToFile | boolean | (optional) Capture images to a file and return back the file path instead of returning base64 encoded data, default false. |
113
77
  | disableExifHeaderStripping | boolean | (optional) Disable automatic rotation of the image, and let the browser deal with it, default true (applicable to the android and ios platforms only) |
114
78
  | disableAudio | boolean | (optional) Disables audio stream to prevent permission requests, default false. (applicable to web only) |
79
+ | lockAndroidOrientation | boolean | (optional) Locks device orientation when camer is showing, default false. (applicable to Android only) |
115
80
 
116
81
  <!-- <strong>Options:</strong>
117
82
  All options stated are optional and will default to values here
@@ -148,7 +113,7 @@ ion-content {
148
113
  --background: transparent;
149
114
  }
150
115
  ```
151
- Take into account that this will make transparent all ion-content on application, if you want to show camera preview only in one page, just add a cutom class to your ion-content and make it transparent:
116
+ Take into account that this will make transparent all ion-content on application, if you want to show camera preview only in one page, just add a custom class to your ion-content and make it transparent:
152
117
 
153
118
  ```css
154
119
  .my-custom-camera-preview-content {
@@ -205,7 +170,7 @@ CameraPreview.hide();
205
170
  <!-- <info>Take the picture. If width and height are not specified or are 0 it will use the defaults. If width and height are specified, it will choose a supported photo size that is closest to width and height specified and has closest aspect ratio to the preview. The argument `quality` defaults to `85` and specifies the quality/compression value: `0=max compression`, `100=max quality`.</info><br/> -->
206
171
 
207
172
  ```javascript
208
- import { CameraPreviewFlashMode } from 'c@capacitor-community/camera-preview';
173
+ import { CameraPreviewFlashMode } from '@capacitor-community/camera-preview';
209
174
 
210
175
  const cameraPreviewPictureOptions: CameraPreviewPictureOptions = {
211
176
  quality: 50
@@ -218,6 +183,28 @@ const base64PictureData = result.value;
218
183
 
219
184
  ```
220
185
 
186
+ ### captureSample(options)
187
+
188
+ | Option | values | descriptions |
189
+ |----------|---------------|----------------------------------------------------------------------|
190
+ | quality | number | (optional) The picture quality, 0 - 100, default 85 |
191
+
192
+ <info>Captures a sample image from the video stream. Only for Android and iOS, web implementation falls back to `capture` method. This can be used to perform real-time analysis on the current frame in the video. The argument `quality` defaults to `85` and specifies the quality/compression value: `0=max compression`, `100=max quality`.</info><br/>
193
+
194
+ ```javascript
195
+ import { CameraSampleOptions } from '@capacitor-community/camera-preview';
196
+
197
+ const cameraSampleOptions: CameraSampleOptions = {
198
+ quality: 50
199
+ };
200
+
201
+ const result = await CameraPreview.captureSample(cameraSampleOptions);
202
+ const base64PictureData = result.value;
203
+
204
+ // do something with base64PictureData
205
+
206
+ ```
207
+
221
208
  ### getSupportedFlashModes()
222
209
 
223
210
  <info>Get the flash modes supported by the camera device currently started. Returns an array containing supported flash modes. See <code>[FLASH_MODE](#camera_Settings.FlashMode)</code> for possible values that can be returned</info><br/>
@@ -408,3 +395,5 @@ Created by Marcel Barbosa Pinto [@mbppower](https://github.com/mbppower)
408
395
  # Demo
409
396
 
410
397
  A working example can be found at [Demo](https://github.com/capacitor-community/camera-preview/tree/master/demo)
398
+
399
+ To run the demo on your local network and access media devices, a secure context is needed. Add an `.env` file at the root of the demo folder with `HTTPS=true` to start react with HTTPS.
@@ -11,10 +11,10 @@ buildscript {
11
11
  apply plugin: 'com.android.library'
12
12
 
13
13
  android {
14
- compileSdkVersion 28
14
+ compileSdkVersion 30
15
15
  defaultConfig {
16
16
  minSdkVersion 21
17
- targetSdkVersion 28
17
+ targetSdkVersion 30
18
18
  versionCode 1
19
19
  versionName "1.0"
20
20
  testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
@@ -40,8 +40,8 @@ repositories {
40
40
  dependencies {
41
41
  implementation fileTree(dir: 'libs', include: ['*.jar'])
42
42
  implementation project(':capacitor-android')
43
- implementation 'androidx.appcompat:appcompat:1.1.0'
44
- implementation 'androidx.exifinterface:exifinterface:1.0.0'
43
+ implementation 'androidx.appcompat:appcompat:1.3.0'
44
+ implementation 'androidx.exifinterface:exifinterface:1.3.2'
45
45
  testImplementation 'junit:junit:4.12'
46
46
  androidTestImplementation 'com.android.support.test:runner:1.0.2'
47
47
  androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
@@ -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;