@capacitor/camera 1.2.4 → 1.3.0

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/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [1.3.0](https://github.com/ionic-team/capacitor-plugins/compare/@capacitor/camera@1.2.4...@capacitor/camera@1.3.0) (2022-02-10)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **camera:** process picked image only once ([#782](https://github.com/ionic-team/capacitor-plugins/issues/782)) ([897dcaf](https://github.com/ionic-team/capacitor-plugins/commit/897dcaf839a6cb83256485c32df2ca0e7b439124))
12
+ * **camera:** return single picture on pickImages ([#783](https://github.com/ionic-team/capacitor-plugins/issues/783)) ([9d65db1](https://github.com/ionic-team/capacitor-plugins/commit/9d65db1e74117fd1c1e7cd9bbba7efaeb4c13e0c))
13
+ * **camera:** Use Locale.ROOT on toUpperCase ([#812](https://github.com/ionic-team/capacitor-plugins/issues/812)) ([6d689ac](https://github.com/ionic-team/capacitor-plugins/commit/6d689acc48e3746ddd35bd5e1e8d7f239cb7f8df))
14
+
15
+
16
+ ### Features
17
+
18
+ * **camera:** Support for 1 Gallery app ([#791](https://github.com/ionic-team/capacitor-plugins/issues/791)) ([77e8c97](https://github.com/ionic-team/capacitor-plugins/commit/77e8c979394d5fb1804fc097ecaeee46a973e640))
19
+ * **camera:** Support for Samsung Gallery app on pickImages ([#706](https://github.com/ionic-team/capacitor-plugins/issues/706)) ([fd059fc](https://github.com/ionic-team/capacitor-plugins/commit/fd059fcd2e53661e95e230f684a6d32408db6787))
20
+
21
+
22
+
23
+
24
+
6
25
  ## [1.2.4](https://github.com/ionic-team/capacitor-plugins/compare/@capacitor/camera@1.2.3...@capacitor/camera@1.2.4) (2022-01-19)
7
26
 
8
27
 
@@ -10,6 +10,7 @@ import android.graphics.Bitmap;
10
10
  import android.graphics.BitmapFactory;
11
11
  import android.net.Uri;
12
12
  import android.os.Bundle;
13
+ import android.os.Parcelable;
13
14
  import android.provider.MediaStore;
14
15
  import android.util.Base64;
15
16
  import androidx.activity.result.ActivityResult;
@@ -35,6 +36,7 @@ import java.io.IOException;
35
36
  import java.io.InputStream;
36
37
  import java.util.ArrayList;
37
38
  import java.util.List;
39
+ import java.util.Locale;
38
40
  import java.util.Map;
39
41
  import java.util.concurrent.Executor;
40
42
  import java.util.concurrent.Executors;
@@ -97,7 +99,7 @@ public class CameraPlugin extends Plugin {
97
99
  @PluginMethod
98
100
  public void pickImages(PluginCall call) {
99
101
  settings = getSettings(call);
100
- openPhotos(call, true);
102
+ openPhotos(call, true, false);
101
103
  }
102
104
 
103
105
  private void doShow(PluginCall call) {
@@ -192,17 +194,20 @@ public class CameraPlugin extends Plugin {
192
194
  */
193
195
  @PermissionCallback
194
196
  private void cameraPermissionsCallback(PluginCall call) {
195
- if (settings.getSource() == CameraSource.CAMERA && getPermissionState(CAMERA) != PermissionState.GRANTED) {
196
- Logger.debug(getLogTag(), "User denied camera permission: " + getPermissionState(CAMERA).toString());
197
- call.reject(PERMISSION_DENIED_ERROR_CAMERA);
198
- return;
199
- } else if (settings.getSource() == CameraSource.PHOTOS && getPermissionState(PHOTOS) != PermissionState.GRANTED) {
200
- Logger.debug(getLogTag(), "User denied photos permission: " + getPermissionState(PHOTOS).toString());
201
- call.reject(PERMISSION_DENIED_ERROR_PHOTOS);
202
- return;
197
+ if (call.getMethodName().equals("pickImages")) {
198
+ openPhotos(call, true, true);
199
+ } else {
200
+ if (settings.getSource() == CameraSource.CAMERA && getPermissionState(CAMERA) != PermissionState.GRANTED) {
201
+ Logger.debug(getLogTag(), "User denied camera permission: " + getPermissionState(CAMERA).toString());
202
+ call.reject(PERMISSION_DENIED_ERROR_CAMERA);
203
+ return;
204
+ } else if (settings.getSource() == CameraSource.PHOTOS && getPermissionState(PHOTOS) != PermissionState.GRANTED) {
205
+ Logger.debug(getLogTag(), "User denied photos permission: " + getPermissionState(PHOTOS).toString());
206
+ call.reject(PERMISSION_DENIED_ERROR_PHOTOS);
207
+ return;
208
+ }
209
+ doShow(call);
203
210
  }
204
-
205
- doShow(call);
206
211
  }
207
212
 
208
213
  private CameraSettings getSettings(PluginCall call) {
@@ -228,7 +233,7 @@ public class CameraPlugin extends Plugin {
228
233
  return null;
229
234
  }
230
235
  try {
231
- return CameraResultType.valueOf(resultType.toUpperCase());
236
+ return CameraResultType.valueOf(resultType.toUpperCase(Locale.ROOT));
232
237
  } catch (IllegalArgumentException ex) {
233
238
  Logger.debug(getLogTag(), "Invalid result type \"" + resultType + "\", defaulting to base64");
234
239
  return CameraResultType.BASE64;
@@ -260,16 +265,18 @@ public class CameraPlugin extends Plugin {
260
265
  }
261
266
 
262
267
  public void openPhotos(final PluginCall call) {
263
- openPhotos(call, false);
268
+ openPhotos(call, false, false);
264
269
  }
265
270
 
266
- private void openPhotos(final PluginCall call, boolean multiple) {
267
- if (multiple || checkPhotosPermissions(call)) {
271
+ private void openPhotos(final PluginCall call, boolean multiple, boolean skipPermission) {
272
+ if (skipPermission || checkPhotosPermissions(call)) {
268
273
  Intent intent = new Intent(Intent.ACTION_PICK);
269
274
  intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, multiple);
270
275
  intent.setType("image/*");
271
276
  try {
272
277
  if (multiple) {
278
+ intent.putExtra("multi-pick", multiple);
279
+ intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] { "image/*" });
273
280
  startActivityForResult(call, intent, "processPickedImages");
274
281
  } else {
275
282
  startActivityForResult(call, intent, "processPickedImage");
@@ -320,21 +327,55 @@ public class CameraPlugin extends Plugin {
320
327
  @ActivityCallback
321
328
  public void processPickedImages(PluginCall call, ActivityResult result) {
322
329
  Intent data = result.getData();
323
- if (data != null && data.getClipData() != null) {
330
+ if (data != null) {
324
331
  Executor executor = Executors.newSingleThreadExecutor();
325
332
  executor.execute(
326
333
  () -> {
327
334
  JSObject ret = new JSObject();
328
335
  JSArray photos = new JSArray();
329
- int count = data.getClipData().getItemCount();
330
- for (int i = 0; i < count; i++) {
331
- Uri imageUri = data.getClipData().getItemAt(i).getUri();
336
+ if (data.getClipData() != null) {
337
+ int count = data.getClipData().getItemCount();
338
+ for (int i = 0; i < count; i++) {
339
+ Uri imageUri = data.getClipData().getItemAt(i).getUri();
340
+ JSObject processResult = processPickedImages(imageUri);
341
+ if (processResult.getString("error") != null && !processResult.getString("error").isEmpty()) {
342
+ call.reject(processResult.getString("error"));
343
+ return;
344
+ } else {
345
+ photos.put(processResult);
346
+ }
347
+ }
348
+ } else if (data.getData() != null) {
349
+ Uri imageUri = data.getData();
332
350
  JSObject processResult = processPickedImages(imageUri);
333
351
  if (processResult.getString("error") != null && !processResult.getString("error").isEmpty()) {
334
352
  call.reject(processResult.getString("error"));
335
353
  return;
336
354
  } else {
337
- photos.put(processPickedImages(imageUri));
355
+ photos.put(processResult);
356
+ }
357
+ } else if (data.getExtras() != null) {
358
+ Bundle bundle = data.getExtras();
359
+ if (bundle.keySet().contains("selectedItems")) {
360
+ ArrayList<Parcelable> fileUris = bundle.getParcelableArrayList("selectedItems");
361
+ if (fileUris != null) {
362
+ for (Parcelable fileUri : fileUris) {
363
+ if (fileUri instanceof Uri) {
364
+ Uri imageUri = (Uri) fileUri;
365
+ try {
366
+ JSObject processResult = processPickedImages(imageUri);
367
+ if (processResult.getString("error") != null && !processResult.getString("error").isEmpty()) {
368
+ call.reject(processResult.getString("error"));
369
+ return;
370
+ } else {
371
+ photos.put(processResult);
372
+ }
373
+ } catch (SecurityException ex) {
374
+ call.reject("SecurityException");
375
+ }
376
+ }
377
+ }
378
+ }
338
379
  }
339
380
  }
340
381
  ret.put("photos", photos);
@@ -453,15 +494,21 @@ public class CameraPlugin extends Plugin {
453
494
  private Uri saveImage(Uri uri, InputStream is) throws IOException {
454
495
  File outFile = null;
455
496
  if (uri.getScheme().equals("content")) {
456
- String filename = Uri.parse(Uri.decode(uri.toString())).getLastPathSegment();
457
- if (!filename.contains(".jpg") && !filename.contains(".jpeg")) {
458
- filename += "." + (new java.util.Date()).getTime() + ".jpeg";
459
- }
460
- File cacheDir = getContext().getCacheDir();
461
- outFile = new File(cacheDir, filename);
497
+ outFile = getTempFile(uri);
462
498
  } else {
463
499
  outFile = new File(uri.getPath());
464
500
  }
501
+ try {
502
+ writePhoto(outFile, is);
503
+ } catch (FileNotFoundException ex) {
504
+ // Some gallery apps return read only file url, create a temporary file for modifications
505
+ outFile = getTempFile(uri);
506
+ writePhoto(outFile, is);
507
+ }
508
+ return Uri.fromFile(outFile);
509
+ }
510
+
511
+ private void writePhoto(File outFile, InputStream is) throws IOException {
465
512
  FileOutputStream fos = new FileOutputStream(outFile);
466
513
  byte[] buffer = new byte[1024];
467
514
  int len;
@@ -469,7 +516,15 @@ public class CameraPlugin extends Plugin {
469
516
  fos.write(buffer, 0, len);
470
517
  }
471
518
  fos.close();
472
- return Uri.fromFile(outFile);
519
+ }
520
+
521
+ private File getTempFile(Uri uri) {
522
+ String filename = Uri.parse(Uri.decode(uri.toString())).getLastPathSegment();
523
+ if (!filename.contains(".jpg") && !filename.contains(".jpeg")) {
524
+ filename += "." + (new java.util.Date()).getTime() + ".jpeg";
525
+ }
526
+ File cacheDir = getContext().getCacheDir();
527
+ return new File(cacheDir, filename);
473
528
  }
474
529
 
475
530
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/camera",
3
- "version": "1.2.4",
3
+ "version": "1.3.0",
4
4
  "description": "The Camera API provides the ability to take a photo with the camera or choose an existing one from the photo album.",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
@@ -79,5 +79,5 @@
79
79
  "publishConfig": {
80
80
  "access": "public"
81
81
  },
82
- "gitHead": "f18ee6482e1ec8e5fb0290d51f598397133af990"
82
+ "gitHead": "5bebfefe9bdca4d49f0e02dab74b02a692d3ed86"
83
83
  }