android/source/AndroidManifest.xml | 4 -- android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java | 4 -- android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java | 18 ---------- 3 files changed, 26 deletions(-)
New commits: commit 269480e5f5c058556d18f67a845fb1dd227cf65a Author: Michael Weghorn <[email protected]> AuthorDate: Wed Nov 19 16:36:25 2025 +0100 Commit: Michael Weghorn <[email protected]> CommitDate: Thu Nov 20 00:09:11 2025 +0100 tdf#164082 android: Drop storage permission and support for file:// URIs In the past, LibreOffice Viewer for Android was directly accessing storage in order to open/save files and when exporting to PDF. However, that was switched to using Android's Storage Access Framework [1], available since Android 4.4 (API level 19), i.e. it is available in all Android versions supported by the app. In the past, in order to directly access storage, permission android.permission.WRITE_EXTERNAL_STORAGE was needed. That permission no longer has any effect in Android 11 (API level 30) or higher, quoting from [2]: > More recent versions of Android rely more on a file's purpose than its > location for determining an app's ability to access, and write to, a > given file. In particular, if your app targets Android 11 (API level 30) > or higher, the WRITE_EXTERNAL_STORAGE permission doesn't have any > effect on your app's access to storage. This purpose-based storage > model improves user privacy because apps are given access only to > the areas of the device's file system that they actually use. > > Android 11 introduces the MANAGE_EXTERNAL_STORAGE permission, which > provides write access to files outside the app-specific directory and > MediaStore. To learn more about this permission, and why most apps don't > need to declare it to fulfill their use cases, see the guide on how to > manage all files [3] on a storage device. Since PDF export was also switched to use the Android Storage Framework mechanism in commit 9ebcb80e2e4335fca1e137d015fe4d84631e282a Author: Michael Weghorn Date: Thu Apr 15 11:22:46 2021 +0200 android: Ask where to save PDF file on export , eventually drop the permission now. As mentioned in commit 7d9db806d65cb814af1e99a1e79c3db5aa7c17d5 Author: Michael Weghorn <[email protected]> Date: Fri Apr 9 11:24:16 2021 +0200 android: Request PERMISSION_WRITE_EXTERNAL_STORAGE again which re-requested the permission before PDF export was ported to use the Android Storage Framework, the case of applications passing documents via a file:// URI would also require storage permission in order to access the file. However, apps that properly pass the file should pass a content:// URL instead. Quoting from the Android 7.0 Behavior changes documentation [4]: > Passing file:// URIs outside the package domain may leave the receiver > with an unaccessible path. Therefore, attempts to pass a file:// URI > trigger a FileUriExposedException. The recommended way to share the > content of a private file is using the FileProvider. (Using content:// URIs has been possible long before Android 7.0, however.) Therefore, drop support for file:// URIs as well, which will prevent apps that would otherwise try to pass file:// URIs from trying to do that for Android Viewer. If this results in any app no longer being able to open documents in LibreOffice Viewer, that app most likely needs to be adjusted to pass a content:// URI instead, which will also make it work for newer Android versions. (Total Commander is one case that apparently doesn't do that yet, previously resulting in a crash when storage permissions were not granted, see tdf#164082. That is reproducible in an Android 7.0 AVD, while opening the file fromm other apps, e.g. from Material Files [5], works perfectly fine, using content:// URIs.) Eventually dropping the permission makes clear that the app does not need direct storage access, which is also relevant for security reviews, and addresses this lint issue from android/source/lint-baseline.xml: <issue id="ScopedStorage" message="WRITE_EXTERNAL_STORAGE is deprecated (and is not granted) when targeting Android 13+. If you need to write to shared storage, use the `MediaStore.createWriteRequest` intent." errorLine1=" <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>" errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> <location file="AndroidManifest.xml" line="9" column="36"/> </issue> That file will be updated/regenerated in a separate commit. [1] https://developer.android.com/training/data-storage/shared/documents-files [2] https://developer.android.com/training/data-storage#permissions [3] https://developer.android.com/training/data-storage/manage-all-files [4] https://developer.android.com/about/versions/nougat/android-7.0-changes [5] https://f-droid.org/en/packages/me.zhanghai.android.files/ Change-Id: Iafb7a32668718afc638b8273a05a9d0618f85550 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194215 Reviewed-by: Michael Weghorn <[email protected]> Tested-by: Jenkins diff --git a/android/source/AndroidManifest.xml b/android/source/AndroidManifest.xml index 6c82f826113d..69319072ceca 100644 --- a/android/source/AndroidManifest.xml +++ b/android/source/AndroidManifest.xml @@ -4,7 +4,6 @@ <!-- App requires OpenGL ES 2.0 --> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:name=".LibreOfficeApplication" @@ -29,7 +28,6 @@ <action android:name="android.intent.action.PICK" /> <category android:name="android.intent.category.DEFAULT" /> - <data android:scheme="file"/> <data android:scheme="content"/> <!-- Please keep this in sync with FileUtilities.java. --> diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java index 3b8f693b3494..215515a207e9 100644 --- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java +++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java @@ -179,10 +179,6 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Shared String displayName = FileUtilities.retrieveDisplayNameForDocumentUri(getContentResolver(), docUri); toolbarTop.setTitle(displayName); - } else if (docUri.getScheme().equals(ContentResolver.SCHEME_FILE)) { - mbReadOnlyDoc = true; - Log.d(LOGTAG, "SCHEME_FILE: getPath(): " + docUri.getPath()); - toolbarTop.setTitle(docUri.getLastPathSegment()); } // create a temporary local copy to work with boolean copyOK = copyFileToTemp(docUri) && mTempFile != null; diff --git a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java index 69bf430dd6b0..0a7fa5e7178b 100644 --- a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java +++ b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java @@ -9,13 +9,10 @@ package org.libreoffice.ui; -import android.Manifest; import android.content.ActivityNotFoundException; import android.content.ComponentName; -import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; -import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutManager; import android.graphics.drawable.Icon; @@ -24,8 +21,6 @@ import android.os.Bundle; import com.google.android.material.floatingactionbutton.FloatingActionButton; import androidx.activity.OnBackPressedCallback; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; import androidx.core.view.ViewCompat; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; @@ -121,8 +116,6 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements View.OnC private static final int REQUEST_CODE_OPEN_FILECHOOSER = 12345; - private static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 0; - private Animation fabOpenAnimation; private Animation fabCloseAnimation; private boolean isFabMenuOpen = false; @@ -160,17 +153,6 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements View.OnC }); } - @Override - protected void onStart() { - super.onStart(); - if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - Log.i(LOGTAG, "no permission to read external storage - asking for permission"); - ActivityCompat.requestPermissions(this, - new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSION_WRITE_EXTERNAL_STORAGE); - } - } - public void createUI() { setContentView(R.layout.activity_document_browser); commit 531babd18f66605c20850fcf4fc718c5f6593588 Author: Michael Weghorn <[email protected]> AuthorDate: Wed Nov 19 14:40:37 2025 +0100 Commit: Michael Weghorn <[email protected]> CommitDate: Thu Nov 20 00:09:01 2025 +0100 android: Drop USB feature from Android manifest This android.hardware.usb.host feature element was added in commit 5ada20b3588f76cad5b7f39442147fca3d63bec7 Author: brainbreaker <[email protected]> Date: Sun Feb 26 02:27:43 2017 +0530 Improve the Document Provider UX , when it was still used for the file/document access logic implemented in the app that was also explicitly handling USB device support. That one was dropped in commit a23bd42e9b2f6401c710ac95afcc3aa8f360d65c Author: Michael Weghorn Date: Tue Apr 6 14:26:06 2021 +0200 android: Drop custom file abstraction + UI , so also drop this from the Android manifest. Change-Id: Icbd8fa86d1a9a4d8dfb8fccd90846a432a329b90 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/194214 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/android/source/AndroidManifest.xml b/android/source/AndroidManifest.xml index 93eae60f97d8..6c82f826113d 100644 --- a/android/source/AndroidManifest.xml +++ b/android/source/AndroidManifest.xml @@ -4,8 +4,6 @@ <!-- App requires OpenGL ES 2.0 --> <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-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application
