android/source/AndroidManifest.xml | 1 android/source/src/java/org/libreoffice/FormattingController.java | 38 +++------- 2 files changed, 13 insertions(+), 26 deletions(-)
New commits: commit e99991216e47751b80238825aaeb21702d46dc34 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Mon May 13 15:36:20 2024 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Tue May 14 08:37:49 2024 +0200 android: Fix taking photos by dropping permission At least on recent devices (seen e.g. on an AVD with API level 34 and a Fairphone 3 with LineageOS 20 (based on Android 13)), inserting a picture by taking a photo using the camera didn't work, "nothing was happening" when choosing the corresponding option from the formatting toolbar with experimental editing mode enabled. This is due to the system filtering information about other apps/packages with target API level >= 30 for privacy reasons, see [1] for more details. As described at [2], requesting the `CAMERA` permission is not required: > Users might take pictures in your app, using the pre-installed > system camera app. > > In this situation, don't declare the CAMERA permission. Instead, > invoke the ACTION_IMAGE_CAPTURE intent action. In fact, specifying the permission is even counter-productive and would cause this to not work, as also described at [2]: > Note: If your app declares Manifest.permission.CAMERA > permission and is not granted, then the action results in > a SecurityException. Rather than explicitly requesting the permission, just drop it from the AndroidManifest, as it's not needed. Also drop the additional code interacting with the package manager, as that doesn't work with newer API versions as described above. With these changes in place, inserting a photo works fine in tests in API 21 and API 34 AVDs and on the above-mentioned Fairphone 3. [1] https://developer.android.com/training/package-visibility [2] https://developer.android.com/privacy-and-security/minimize-permission-requests#take-photo Change-Id: Ia1ee4e4de577a269e2b79bf5460d08b1bf2bee56 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167603 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/android/source/AndroidManifest.xml b/android/source/AndroidManifest.xml index 3ece77d62bfd..ba71fdddb197 100644 --- a/android/source/AndroidManifest.xml +++ b/android/source/AndroidManifest.xml @@ -6,7 +6,6 @@ <uses-feature android:glEsVersion="0x00020000" android:required="true" /> <!-- App wants to know if device supports USB host capability(not mandatory) --> <uses-feature android:name="android.hardware.usb.host" android:required="false"/> - <uses-feature android:name="android.hardware.camera.any" android:required="false"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application diff --git a/android/source/src/java/org/libreoffice/FormattingController.java b/android/source/src/java/org/libreoffice/FormattingController.java index 1d72c10a2ac7..378a3ecb87bc 100644 --- a/android/source/src/java/org/libreoffice/FormattingController.java +++ b/android/source/src/java/org/libreoffice/FormattingController.java @@ -366,31 +366,19 @@ class FormattingController implements View.OnClickListener { return; } Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - // Ensure that there's a camera activity to handle the intent - if (takePictureIntent.resolveActivity(mContext.getPackageManager()) != null) { - // Create the File where the photo should go - File photoFile = null; - try { - photoFile = createImageFile(); - } catch (IOException ex) { - ex.printStackTrace(); - } - // Continue only if the File was successfully created - if (photoFile != null) { - Uri photoURI = FileProvider.getUriForFile(mContext, - mContext.getPackageName() + ".fileprovider", - photoFile); - takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); - // Grant permissions to potential photo/camera apps (for some Android versions) - List<ResolveInfo> resInfoList = mContext.getPackageManager() - .queryIntentActivities(takePictureIntent, PackageManager.MATCH_DEFAULT_ONLY); - for (ResolveInfo resolveInfo : resInfoList) { - String packageName = resolveInfo.activityInfo.packageName; - mContext.grantUriPermission(packageName, photoURI, Intent.FLAG_GRANT_WRITE_URI_PERMISSION - | Intent.FLAG_GRANT_READ_URI_PERMISSION); - } - mContext.startActivityForResult(takePictureIntent, TAKE_PHOTO); - } + // Create the File where the photo should go + File photoFile = null; + try { + photoFile = createImageFile(); + } catch (IOException ex) { + ex.printStackTrace(); + } + // Continue only if the File was successfully created + if (photoFile != null) { + Uri photoURI = FileProvider.getUriForFile(mContext, + mContext.getPackageName() + ".fileprovider", photoFile); + takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); + mContext.startActivityForResult(takePictureIntent, TAKE_PHOTO); } }