cordova-plugin-mserviceinterface-2.0 1.0.107 → 1.0.108

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cordova-plugin-mserviceinterface-2.0",
3
- "version": "1.0.107",
3
+ "version": "1.0.108",
4
4
  "description": "This plugin establishes the connection to the native interface and performs the requested task.",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/plugin.xml CHANGED
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
3
- xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-mserviceinterface-2.0" version="1.0.107">
3
+ xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-mserviceinterface-2.0" version="1.0.108">
4
4
  <name>mserviceinterface-2.0</name>
5
5
  <description>This plugin establishes the connection to the native interface and performs the requested task.</description>
6
6
  <author>selfservit@gmail.com</author>
@@ -48,11 +48,15 @@
48
48
  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
49
49
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
50
50
  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
51
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
52
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
51
53
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
52
54
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
53
55
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
54
56
  <uses-permission android:name="android.permission.READ_PHONE_STATE" />
55
57
  <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
58
+ <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
59
+ <uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
56
60
  <queries>
57
61
  <intent>
58
62
  <action android:name="android.media.action.IMAGE_CAPTURE" />
@@ -1,59 +1,59 @@
1
- package com.selfservit.util;
2
-
3
- import java.io.File;
4
- import java.io.FileOutputStream;
5
- import java.io.IOException;
6
- import java.io.InputStream;
7
- import java.io.OutputStream;
8
-
9
- /** Copies a provider stream into an app-owned file without assuming a filesystem URI. */
10
- final class AttachmentFileIO {
11
- private AttachmentFileIO() { }
12
-
13
- static File copy(InputStream input, File directory, String displayName) throws IOException {
14
- File outputFile = null;
15
- boolean complete = false;
16
- try {
17
- try (InputStream source = input) {
18
- if (source == null) {
19
- throw new IOException("The selected file is no longer available");
20
- }
21
- if (!directory.isDirectory() && !directory.mkdirs()) {
22
- throw new IOException("Cannot create attachment directory");
23
- }
24
- String name = displayName == null ? "attachment" : displayName;
25
- // Provider display names are labels, never paths.
26
- name = name.replaceAll("[\\\\/\\p{Cntrl}:*?\"<>|]", "_").trim();
27
- if (name.isEmpty() || name.equals(".") || name.equals("..")) {
28
- name = "attachment";
29
- }
30
- int dot = name.lastIndexOf('.');
31
- String stem = dot > 0 ? name.substring(0, dot) : name;
32
- String suffix = dot > 0 ? name.substring(dot) : "";
33
- // Bound provider-supplied names, retaining normal filename extensions.
34
- stem = stem.substring(0, Math.min(stem.length(), 80));
35
- suffix = suffix.substring(0, Math.min(suffix.length(), 20));
36
- outputFile = File.createTempFile(stem + "_attachment_", suffix, directory);
37
- try (OutputStream output = new FileOutputStream(outputFile)) {
38
- byte[] buffer = new byte[8192];
39
- int count;
40
- while ((count = source.read(buffer)) != -1) {
41
- if (count == 0) {
42
- int next = source.read();
43
- if (next == -1) break;
44
- output.write(next);
45
- } else {
46
- output.write(buffer, 0, count);
47
- }
48
- }
49
- }
50
- }
51
- complete = true;
52
- } finally {
53
- if (!complete && outputFile != null && outputFile.exists()) {
54
- outputFile.delete();
55
- }
56
- }
57
- return outputFile;
58
- }
59
- }
1
+ package com.selfservit.util;
2
+
3
+ import java.io.File;
4
+ import java.io.FileOutputStream;
5
+ import java.io.IOException;
6
+ import java.io.InputStream;
7
+ import java.io.OutputStream;
8
+
9
+ /** Copies a provider stream into an app-owned file without assuming a filesystem URI. */
10
+ final class AttachmentFileIO {
11
+ private AttachmentFileIO() { }
12
+
13
+ static File copy(InputStream input, File directory, String displayName) throws IOException {
14
+ File outputFile = null;
15
+ boolean complete = false;
16
+ try {
17
+ try (InputStream source = input) {
18
+ if (source == null) {
19
+ throw new IOException("The selected file is no longer available");
20
+ }
21
+ if (!directory.isDirectory() && !directory.mkdirs()) {
22
+ throw new IOException("Cannot create attachment directory");
23
+ }
24
+ String name = displayName == null ? "attachment" : displayName;
25
+ // Provider display names are labels, never paths.
26
+ name = name.replaceAll("[\\\\/\\p{Cntrl}:*?\"<>|]", "_").trim();
27
+ if (name.isEmpty() || name.equals(".") || name.equals("..")) {
28
+ name = "attachment";
29
+ }
30
+ int dot = name.lastIndexOf('.');
31
+ String stem = dot > 0 ? name.substring(0, dot) : name;
32
+ String suffix = dot > 0 ? name.substring(dot) : "";
33
+ // Bound provider-supplied names, retaining normal filename extensions.
34
+ stem = stem.substring(0, Math.min(stem.length(), 80));
35
+ suffix = suffix.substring(0, Math.min(suffix.length(), 20));
36
+ outputFile = File.createTempFile(stem + "_attachment_", suffix, directory);
37
+ try (OutputStream output = new FileOutputStream(outputFile)) {
38
+ byte[] buffer = new byte[8192];
39
+ int count;
40
+ while ((count = source.read(buffer)) != -1) {
41
+ if (count == 0) {
42
+ int next = source.read();
43
+ if (next == -1) break;
44
+ output.write(next);
45
+ } else {
46
+ output.write(buffer, 0, count);
47
+ }
48
+ }
49
+ }
50
+ }
51
+ complete = true;
52
+ } finally {
53
+ if (!complete && outputFile != null && outputFile.exists()) {
54
+ outputFile.delete();
55
+ }
56
+ }
57
+ return outputFile;
58
+ }
59
+ }
@@ -2,21 +2,21 @@ package com.selfservit.util;
2
2
 
3
3
  import android.Manifest;
4
4
  import android.annotation.SuppressLint;
5
- import android.app.Activity;
6
- import android.content.Context;
7
- import android.content.Intent;
8
- import android.content.pm.PackageManager;
9
- import android.content.res.Configuration;
10
- import android.hardware.display.DisplayManager;
11
- import android.os.Bundle;
12
- import android.os.Handler;
13
- import android.os.Looper;
14
- import android.util.Log;
15
- import android.view.Display;
16
- import android.view.MotionEvent;
17
- import android.view.ScaleGestureDetector;
18
- import android.view.Surface;
19
- import android.view.View;
5
+ import android.app.Activity;
6
+ import android.content.Context;
7
+ import android.content.Intent;
8
+ import android.content.pm.PackageManager;
9
+ import android.content.res.Configuration;
10
+ import android.hardware.display.DisplayManager;
11
+ import android.os.Bundle;
12
+ import android.os.Handler;
13
+ import android.os.Looper;
14
+ import android.util.Log;
15
+ import android.view.Display;
16
+ import android.view.MotionEvent;
17
+ import android.view.ScaleGestureDetector;
18
+ import android.view.Surface;
19
+ import android.view.View;
20
20
  import android.widget.ImageButton;
21
21
  import android.widget.Toast;
22
22
 
@@ -32,11 +32,11 @@ import androidx.camera.core.Preview;
32
32
  import androidx.camera.lifecycle.ProcessCameraProvider;
33
33
  import androidx.camera.view.PreviewView;
34
34
  import androidx.core.app.ActivityCompat;
35
- import androidx.core.content.ContextCompat;
36
- import androidx.core.graphics.Insets;
37
- import androidx.core.view.ViewCompat;
38
- import androidx.core.view.WindowCompat;
39
- import androidx.core.view.WindowInsetsCompat;
35
+ import androidx.core.content.ContextCompat;
36
+ import androidx.core.graphics.Insets;
37
+ import androidx.core.view.ViewCompat;
38
+ import androidx.core.view.WindowCompat;
39
+ import androidx.core.view.WindowInsetsCompat;
40
40
 
41
41
  import com.google.common.util.concurrent.ListenableFuture;
42
42
 
@@ -55,27 +55,27 @@ public class CameraActivity extends AppCompatActivity {
55
55
  private ImageCapture imageCapture;
56
56
  private ImageButton torchButton;
57
57
  private ProcessCameraProvider cameraProvider;
58
- private Camera camera;
59
- private View cameraControls;
60
- private DisplayManager displayManager;
61
- private int torchOnDrawable;
62
- private int torchOffDrawable;
63
-
64
- private final DisplayManager.DisplayListener displayListener = new DisplayManager.DisplayListener() {
65
- @Override
66
- public void onDisplayAdded(int displayId) {}
67
-
68
- @Override
69
- public void onDisplayRemoved(int displayId) {}
70
-
71
- @Override
72
- public void onDisplayChanged(int displayId) {
73
- Display display = previewView == null ? null : previewView.getDisplay();
74
- if (display != null && display.getDisplayId() == displayId) {
75
- updateCaptureRotation();
76
- }
77
- }
78
- };
58
+ private Camera camera;
59
+ private View cameraControls;
60
+ private DisplayManager displayManager;
61
+ private int torchOnDrawable;
62
+ private int torchOffDrawable;
63
+
64
+ private final DisplayManager.DisplayListener displayListener = new DisplayManager.DisplayListener() {
65
+ @Override
66
+ public void onDisplayAdded(int displayId) {}
67
+
68
+ @Override
69
+ public void onDisplayRemoved(int displayId) {}
70
+
71
+ @Override
72
+ public void onDisplayChanged(int displayId) {
73
+ Display display = previewView == null ? null : previewView.getDisplay();
74
+ if (display != null && display.getDisplayId() == displayId) {
75
+ updateCaptureRotation();
76
+ }
77
+ }
78
+ };
79
79
 
80
80
  private int lensFacing = CameraSelector.LENS_FACING_BACK;
81
81
  private boolean isTorchOn = false;
@@ -85,18 +85,18 @@ public class CameraActivity extends AppCompatActivity {
85
85
  @SuppressLint("ClickableViewAccessibility")
86
86
  @Override
87
87
  protected void onCreate(Bundle savedInstanceState) {
88
- super.onCreate(savedInstanceState);
89
-
90
- // Let the system handle predictive Back while preserving the plugin's cancellation result.
91
- Intent cancelled = new Intent();
92
- cancelled.putExtra("result", "cancelled");
93
- setResult(Activity.RESULT_CANCELED, cancelled);
94
- if (savedInstanceState != null) {
95
- lensFacing = savedInstanceState.getInt("lensFacing", CameraSelector.LENS_FACING_BACK);
96
- isTorchOn = savedInstanceState.getBoolean("isTorchOn", false);
97
- }
98
- displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
99
- WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
88
+ super.onCreate(savedInstanceState);
89
+
90
+ // Let the system handle predictive Back while preserving the plugin's cancellation result.
91
+ Intent cancelled = new Intent();
92
+ cancelled.putExtra("result", "cancelled");
93
+ setResult(Activity.RESULT_CANCELED, cancelled);
94
+ if (savedInstanceState != null) {
95
+ lensFacing = savedInstanceState.getInt("lensFacing", CameraSelector.LENS_FACING_BACK);
96
+ isTorchOn = savedInstanceState.getBoolean("isTorchOn", false);
97
+ }
98
+ displayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
99
+ WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
100
100
 
101
101
  // Dynamically inflate layout
102
102
  String pkg = getPackageName();
@@ -108,22 +108,22 @@ public class CameraActivity extends AppCompatActivity {
108
108
  int captureId = getResources().getIdentifier("captureButton", "id", pkg);
109
109
  int switchId = getResources().getIdentifier("switchCamera", "id", pkg);
110
110
  int torchId = getResources().getIdentifier("torchButton", "id", pkg);
111
- int focusViewId = getResources().getIdentifier("focusView", "id", pkg);
112
- int controlsId = getResources().getIdentifier("cameraControls", "id", pkg);
111
+ int focusViewId = getResources().getIdentifier("focusView", "id", pkg);
112
+ int controlsId = getResources().getIdentifier("cameraControls", "id", pkg);
113
113
 
114
114
  // Resolve drawable IDs
115
- torchOnDrawable = getResources().getIdentifier("ic_flashlight_on", "drawable", pkg);
116
- torchOffDrawable = getResources().getIdentifier("ic_flashlight_off", "drawable", pkg);
115
+ torchOnDrawable = getResources().getIdentifier("ic_flashlight_on", "drawable", pkg);
116
+ torchOffDrawable = getResources().getIdentifier("ic_flashlight_off", "drawable", pkg);
117
117
 
118
118
  // Bind views to fields
119
119
  previewView = findViewById(previewId);
120
120
  ImageButton captureButton = findViewById(captureId);
121
121
  ImageButton switchButton = findViewById(switchId);
122
122
  torchButton = findViewById(torchId);
123
- focusView = findViewById(focusViewId);
124
- cameraControls = findViewById(controlsId);
125
- applyControlInsets();
126
- previewView.post(this::updateCaptureRotation);
123
+ focusView = findViewById(focusViewId);
124
+ cameraControls = findViewById(controlsId);
125
+ applyControlInsets();
126
+ previewView.post(this::updateCaptureRotation);
127
127
 
128
128
  // Utility to add press animation to any view
129
129
  View.OnTouchListener pressAnim = (v, e) -> {
@@ -227,11 +227,11 @@ public class CameraActivity extends AppCompatActivity {
227
227
 
228
228
  // Switch front/back
229
229
  switchButton.setOnClickListener(v -> {
230
- lensFacing = (lensFacing == CameraSelector.LENS_FACING_BACK)
231
- ? CameraSelector.LENS_FACING_FRONT
232
- : CameraSelector.LENS_FACING_BACK;
233
- isTorchOn = false;
234
- bindUseCases();
230
+ lensFacing = (lensFacing == CameraSelector.LENS_FACING_BACK)
231
+ ? CameraSelector.LENS_FACING_FRONT
232
+ : CameraSelector.LENS_FACING_BACK;
233
+ isTorchOn = false;
234
+ bindUseCases();
235
235
  });
236
236
 
237
237
  // Torch toggle
@@ -242,72 +242,72 @@ public class CameraActivity extends AppCompatActivity {
242
242
  torchButton.setImageResource(isTorchOn ? torchOnDrawable : torchOffDrawable);
243
243
  }
244
244
  });
245
- }
246
-
247
- private void applyControlInsets() {
248
- final int left = cameraControls.getPaddingLeft();
249
- final int top = cameraControls.getPaddingTop();
250
- final int right = cameraControls.getPaddingRight();
251
- final int bottom = cameraControls.getPaddingBottom();
252
- ViewCompat.setOnApplyWindowInsetsListener(cameraControls, (view, windowInsets) -> {
253
- Insets safeInsets = windowInsets.getInsets(
254
- WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout());
255
- view.setPadding(left + safeInsets.left, top + safeInsets.top,
256
- right + safeInsets.right, bottom + safeInsets.bottom);
257
- return windowInsets;
258
- });
259
- cameraControls.post(() -> ViewCompat.requestApplyInsets(cameraControls));
260
- }
261
-
262
- @Override
263
- protected void onStart() {
264
- super.onStart();
265
- if (displayManager != null) {
266
- displayManager.registerDisplayListener(displayListener, new Handler(Looper.getMainLooper()));
267
- }
268
- previewView.post(this::updateCaptureRotation);
269
- }
270
-
271
- @Override
272
- protected void onStop() {
273
- if (displayManager != null) {
274
- displayManager.unregisterDisplayListener(displayListener);
275
- }
276
- super.onStop();
277
- }
278
-
279
- @Override
280
- public void onConfigurationChanged(@NonNull Configuration newConfig) {
281
- super.onConfigurationChanged(newConfig);
282
- previewView.post(this::updateCaptureRotation);
283
- ViewCompat.requestApplyInsets(cameraControls);
284
- }
285
-
286
- @Override
287
- protected void onSaveInstanceState(@NonNull Bundle outState) {
288
- outState.putInt("lensFacing", lensFacing);
289
- outState.putBoolean("isTorchOn", isTorchOn);
290
- super.onSaveInstanceState(outState);
291
- }
292
-
293
- private int getCaptureRotation() {
294
- Display display = previewView == null ? null : previewView.getDisplay();
295
- return display == null ? Surface.ROTATION_0 : display.getRotation();
296
- }
297
-
298
- private void updateCaptureRotation() {
299
- if (imageCapture != null && previewView.getDisplay() != null) {
300
- imageCapture.setTargetRotation(getCaptureRotation());
301
- }
302
- }
245
+ }
246
+
247
+ private void applyControlInsets() {
248
+ final int left = cameraControls.getPaddingLeft();
249
+ final int top = cameraControls.getPaddingTop();
250
+ final int right = cameraControls.getPaddingRight();
251
+ final int bottom = cameraControls.getPaddingBottom();
252
+ ViewCompat.setOnApplyWindowInsetsListener(cameraControls, (view, windowInsets) -> {
253
+ Insets safeInsets = windowInsets.getInsets(
254
+ WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout());
255
+ view.setPadding(left + safeInsets.left, top + safeInsets.top,
256
+ right + safeInsets.right, bottom + safeInsets.bottom);
257
+ return windowInsets;
258
+ });
259
+ cameraControls.post(() -> ViewCompat.requestApplyInsets(cameraControls));
260
+ }
261
+
262
+ @Override
263
+ protected void onStart() {
264
+ super.onStart();
265
+ if (displayManager != null) {
266
+ displayManager.registerDisplayListener(displayListener, new Handler(Looper.getMainLooper()));
267
+ }
268
+ previewView.post(this::updateCaptureRotation);
269
+ }
270
+
271
+ @Override
272
+ protected void onStop() {
273
+ if (displayManager != null) {
274
+ displayManager.unregisterDisplayListener(displayListener);
275
+ }
276
+ super.onStop();
277
+ }
278
+
279
+ @Override
280
+ public void onConfigurationChanged(@NonNull Configuration newConfig) {
281
+ super.onConfigurationChanged(newConfig);
282
+ previewView.post(this::updateCaptureRotation);
283
+ ViewCompat.requestApplyInsets(cameraControls);
284
+ }
285
+
286
+ @Override
287
+ protected void onSaveInstanceState(@NonNull Bundle outState) {
288
+ outState.putInt("lensFacing", lensFacing);
289
+ outState.putBoolean("isTorchOn", isTorchOn);
290
+ super.onSaveInstanceState(outState);
291
+ }
292
+
293
+ private int getCaptureRotation() {
294
+ Display display = previewView == null ? null : previewView.getDisplay();
295
+ return display == null ? Surface.ROTATION_0 : display.getRotation();
296
+ }
297
+
298
+ private void updateCaptureRotation() {
299
+ if (imageCapture != null && previewView.getDisplay() != null) {
300
+ imageCapture.setTargetRotation(getCaptureRotation());
301
+ }
302
+ }
303
303
 
304
304
  private void startCamera() {
305
305
  ListenableFuture<ProcessCameraProvider> future =
306
306
  ProcessCameraProvider.getInstance(this);
307
- future.addListener(() -> {
308
- try {
309
- if (isFinishing() || isDestroyed()) return;
310
- cameraProvider = future.get();
307
+ future.addListener(() -> {
308
+ try {
309
+ if (isFinishing() || isDestroyed()) return;
310
+ cameraProvider = future.get();
311
311
  bindUseCases();
312
312
  } catch (ExecutionException | InterruptedException e) {
313
313
  Log.e("CameraActivity", "CameraProvider init failed", e);
@@ -326,10 +326,10 @@ public class CameraActivity extends AppCompatActivity {
326
326
  preview.setSurfaceProvider(previewView.getSurfaceProvider());
327
327
 
328
328
  // Image capture use-case
329
- imageCapture = new ImageCapture.Builder()
330
- .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
331
- .setTargetRotation(getCaptureRotation())
332
- .build();
329
+ imageCapture = new ImageCapture.Builder()
330
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
331
+ .setTargetRotation(getCaptureRotation())
332
+ .build();
333
333
 
334
334
  // Select camera
335
335
  CameraSelector selector = new CameraSelector.Builder()
@@ -341,19 +341,19 @@ public class CameraActivity extends AppCompatActivity {
341
341
  this, selector, preview, imageCapture
342
342
  );
343
343
  boolean hasFlash = camera.getCameraInfo().hasFlashUnit();
344
- if (hasFlash) {
345
- torchButton.setVisibility(View.VISIBLE);
346
- camera.getCameraControl().enableTorch(isTorchOn);
344
+ if (hasFlash) {
345
+ torchButton.setVisibility(View.VISIBLE);
346
+ camera.getCameraControl().enableTorch(isTorchOn);
347
347
  } else {
348
348
  torchButton.setVisibility(View.GONE);
349
349
  // reset state in case you were mid-toggle
350
- isTorchOn = false;
351
- }
352
- torchButton.setImageResource(isTorchOn ? torchOnDrawable : torchOffDrawable);
353
- }
354
- private void takePhoto() {
355
- if (imageCapture == null) return;
356
- updateCaptureRotation();
350
+ isTorchOn = false;
351
+ }
352
+ torchButton.setImageResource(isTorchOn ? torchOnDrawable : torchOffDrawable);
353
+ }
354
+ private void takePhoto() {
355
+ if (imageCapture == null) return;
356
+ updateCaptureRotation();
357
357
 
358
358
  // Prepare output file
359
359
  File photoFile = new File(getCacheDir(),