From 0f7d55b539704ad51d464a7e2cde14161796c63d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Petr=C3=A9re?= Date: Mon, 4 Sep 2023 13:14:00 -0300 Subject: [PATCH] feat(android)!: Android 13 support (#844) * feat(android)!: Android 13 support * refactor(android): simplify getPermissions logic * feat(android)!: bump cordova-android requirement to >=12.0.0 * feat(android): update saveAlbumPermission to include Android 9 and below use case --------- Co-authored-by: ochakov # Conflicts: # package-lock.json # package.json # plugin.xml # src/android/CameraLauncher.java --- plugin.xml | 4 +- src/android/CameraLauncher.java | 66 ++++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/plugin.xml b/plugin.xml index 687493d37..a9296f5e8 100644 --- a/plugin.xml +++ b/plugin.xml @@ -54,7 +54,9 @@ - + + + permissions = new ArrayList<>(); + + if (android.os.Build.VERSION.SDK_INT >= 33) { + // if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + // Android API 33 and higher + switch (mediaType) { + case PICTURE: + permissions.add("android.permission.READ_MEDIA_IMAGES"); + break; + case VIDEO: + permissions.add("android.permission.READ_MEDIA_VIDEO"); + break; + default: + permissions.add("android.permission.READ_MEDIA_IMAGES"); + permissions.add("android.permission.READ_MEDIA_VIDEO"); + break; + } + } else { + // Android API 32 or lower + permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); + permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); + } + + if (!storageOnly) { + // Add camera permission when not storage. + permissions.add(Manifest.permission.CAMERA); + } + + return permissions.toArray(new String[0]); + } + private String getTempDirectoryPath() { File cache = cordova.getActivity().getCacheDir(); // Create the cache directory if it doesn't exist @@ -241,8 +274,14 @@ private String getTempDirectoryPath() { * @param encodingType Compression quality hint (0-100: 0=low quality & high compression, 100=compress of max quality) */ public void callTakePicture(int returnType, int encodingType) { - boolean saveAlbumPermission = PermissionHelper.hasPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) - && PermissionHelper.hasPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); + String[] storagePermissions = getPermissions(true, mediaType); + boolean saveAlbumPermission; + if (android.os.Build.VERSION.SDK_INT >= 29) { + // if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + saveAlbumPermission = this.saveToPhotoAlbum ? hasPermissions(storagePermissions) : true; + } else { + saveAlbumPermission = hasPermissions(storagePermissions); + } boolean takePicturePermission = PermissionHelper.hasPermission(this, Manifest.permission.CAMERA); // CB-10120: The CAMERA permission does not need to be requested unless it is declared @@ -273,10 +312,9 @@ public void callTakePicture(int returnType, int encodingType) { } else if (saveAlbumPermission && !takePicturePermission) { PermissionHelper.requestPermission(this, TAKE_PIC_SEC, Manifest.permission.CAMERA); } else if (!saveAlbumPermission && takePicturePermission) { - PermissionHelper.requestPermissions(this, TAKE_PIC_SEC, - new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}); + PermissionHelper.requestPermissions(this, TAKE_PIC_SEC, storagePermissions); } else { - PermissionHelper.requestPermissions(this, TAKE_PIC_SEC, permissions); + PermissionHelper.requestPermissions(this, TAKE_PIC_SEC, getPermissions(false, mediaType)); } } @@ -1216,6 +1254,7 @@ private void checkForDuplicateImage(int type) { // delete the duplicate file if the difference is 2 for file URI or 1 for Data URL if ((currentNumOfImages - numPics) == diff) { cursor.moveToLast(); + @SuppressLint("Range") int id = Integer.valueOf(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media._ID))); if (diff == 2) { id--; @@ -1389,4 +1428,13 @@ private String getFileNameFromUri(Uri uri) { String path = external_storage.getAbsolutePath() + partial_path; return path; } + + private boolean hasPermissions(String[] permissions) { + for (String permission: permissions) { + if (!PermissionHelper.hasPermission(this, permission)) { + return false; + } + } + return true; + } }