android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java |    5 
++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

New commits:
commit b68821acc77c774c09ebca8be157a768ea417e04
Author:     Michael Weghorn <[email protected]>
AuthorDate: Thu Apr 21 17:01:55 2022 +0200
Commit:     Michael Weghorn <[email protected]>
CommitDate: Thu Apr 21 21:01:37 2022 +0200

    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 <[email protected]>

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.");
         }
     }
 

Reply via email to