diff options
author | Michael Weghorn <m.weghorn@posteo.de> | 2022-04-21 17:01:55 +0200 |
---|---|---|
committer | Michael Weghorn <m.weghorn@posteo.de> | 2022-04-21 21:01:37 +0200 |
commit | b68821acc77c774c09ebca8be157a768ea417e04 (patch) | |
tree | e50d0491fd22a13adccb2cb803245cd0ff2ed324 | |
parent | b68362b178f732f90fdc99073aaa5940bee409bb (diff) |
android: Show file chooser despite package visibility filtering in API 30
While it was working just fine in my x86_64 AVD with API level 31,
opening the the file chooser on a real HW aarch64 device running
Android 12 no longer worked by tapping on the TextView in
`LibreOfficeUIActivity` after updating target API from 28
to 31 in
commit 2ab389b251744fa7f3f6b060c09746e59d87f3b1
Date: Tue Apr 19 10:33:27 2022 +0200
android: Update compileSdkVersion/targetSdkVersion to 31
The
intent.resolveActivity(getPackageManager()) != null
check was failing there, so the Activity with
`Intent.ACTION_OPEN_DOCUMENT` wasn't started there.
This looks like an issue due to package visibility filtering
introduced in target API level 30. Quoting from [1]:
> When an app targets Android 11 (API level 30) or higher and queries for
> information about the other apps that are installed on a device, the
> system filters this information by default. The limited package
> visibility reduces the number of apps that appear to be installed on a
> device, from your app's perspective.
>
> [...]
>
> The limited app visibility affects the return results of methods that
> give information about other apps, such as queryIntentActivities(),
> getPackageInfo(), and getInstalledApplications(). The limited
> visibility also affects explicit interactions with other apps, such
> as starting another app's service.
From how I understand it, the check is used to make sure that
there is an app that can handle the Intent, as e.g. the
"Android fundamentals 02.3: Implicit intents" tutorial [2]
mentions it for the example using an `Intent.ACTION_VIEW`:
> Use the resolveActivity() method and the Android package manager to find
> an Activity that can handle your implicit Intent. Make sure that the
> request resolved successfully.
>
> if (intent.resolveActivity(getPackageManager()) != null) {
> }
>
> This request matches your Intent action and data with the Intent filters
> for installed apps on the device. You use it to make sure there is at
> least one Activity that can handle your requests.
While that sounds reasonable to make sure there is an app that can
view specific data passed *from* the app (and [3] describes how to add
a corresponding `<queries>` element to make this use case work),
it seems to be unnecessary for `Intent.ACTION_OPEN_DOCUMENT`,
since that causes the system to "display the various DocumentsProvider
instances installed on the device, letting the user navigate through
them" and Android presumably at least provides a provider for
handling local files by itself in any case.
The `Intent.ACTION_GET_CONTENT` case used instead of
`Intent.ACTION_OPEN_DOCUMENT` for API level < 19 should
presumably be similar.
Anyway, in case there should still be any case where the
Intent cannot be handled:
`startActivityForResult` "throws ActivityNotFoundException if there was
no Activity found to run the given Intent." [4], so add
a try-catch block handling that exception instead of the previous
check.
[1] https://developer.android.com/training/package-visibility
[2] https://developer.android.com/codelabs/android-training-activity-with-implicit-intent?index=..%2F..android-training#3
[3] https://developer.android.com/training/package-visibility/use-cases#open-a-file
[4] https://developer.android.com/reference/android/app/Activity#startActivityForResult(android.content.Intent,%20int)
Change-Id: I7702b100d71333be2d78df1bc81ef2e5a7e016bd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133272
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
-rw-r--r-- | android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java index 16e0fe8af2cd..965639e6e2ba 100644 --- a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java +++ b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java @@ -10,6 +10,7 @@ package org.libreoffice.ui; import android.Manifest; +import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -268,8 +269,10 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings intent.setType("*/*"); intent.putExtra(Intent.EXTRA_MIME_TYPES, SUPPORTED_MIME_TYPES); - if (intent.resolveActivity(getPackageManager()) != null) { + try { startActivityForResult(intent, REQUEST_CODE_OPEN_FILECHOOSER); + } catch (ActivityNotFoundException e) { + Log.w(LOGTAG, "No activity available that can handle the intent to open a document."); } } |