[Libreoffice-commits] core.git: android/.gitignore android/source

Michael Weghorn (via logerrit) logerrit at kemper.freedesktop.org
Mon Apr 12 05:21:00 UTC 2021


 android/.gitignore                                                   |    1 
 android/source/build.gradle                                          |   26 ++-
 android/source/src/java/org/libreoffice/AboutDialogFragment.java     |   13 -
 android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java |   75 ++++------
 4 files changed, 52 insertions(+), 63 deletions(-)

New commits:
commit d3f8f4b1663214ebe29e49e109b1ae704b680b9e
Author:     Michael Weghorn <m.weghorn at posteo.de>
AuthorDate: Fri Apr 9 10:08:19 2021 +0200
Commit:     Michael Weghorn <m.weghorn at posteo.de>
CommitDate: Mon Apr 12 07:20:14 2021 +0200

    android: Turn 3 "internal" docs into raw resources
    
    Make 'example.odt', 'license.txt' and 'notice.txt'
    (which can be opened via the "About" dialog)
    resources of the app by copying them to a new directory
    'res_generated' instead of into assets, and include
    'res_generated' into resources, then use an
    'android.resource://' URI instead of a 'file:///assets/'
    one in AboutDialogFragment.
    The latter does not work with when passed as a parameter
    to 'ContentResolver.openInputStream'.
    
    Adapt/Simplify 'LibreOfficeMainActivity#copyFileToTemp' to
    make loading those docs using the 'android.resource://'
    URI work and use the existing 'copyStream' method for copying from
    the input to the output stream.
    
    This is in preparation for upcoming commit with Change-Id
    I7731ef81a4242fa0ce3b3fd8ced1683a6a6bee8c,
    "android: Always create a temporary local copy of the doc".
    
    Change-Id: I7731ef81a4242fa0ce3b3fd8ced1683a6a6bee8c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113881
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>

diff --git a/android/.gitignore b/android/.gitignore
index 163145dd63fa..de608fea3c14 100644
--- a/android/.gitignore
+++ b/android/.gitignore
@@ -6,6 +6,7 @@
 /source/build/
 /source/captures/
 /source/jni/Application.mk
+/source/res_generated
 /jniLibs/
 /source/liboSettings.gradle
 /source/local.properties
diff --git a/android/source/build.gradle b/android/source/build.gradle
index f6f781b0e407..a690749ff0ee 100644
--- a/android/source/build.gradle
+++ b/android/source/build.gradle
@@ -42,7 +42,7 @@ android {
     sourceSets {
         main.manifest.srcFile 'AndroidManifest.xml'
         main.assets.srcDirs = ['assets']
-        main.res.srcDirs = ['res']
+        main.res.srcDirs = ['res', 'res_generated']
         main.java.srcDirs = ['../Bootstrap/src', 'src/java']
         main.jniLibs.srcDirs = ["${liboJniLibsdir}"]
         main.jni.srcDirs = [] // don't attempt to build native-lib via gradle
@@ -144,14 +144,6 @@ task copyUnpackAssets(type: Copy) {
 task copyAssets(type: Copy) {
     description "copies assets that can be accessed within the installed apk"
     into 'assets'
-    from("${liboInstdir}") {
-        includes = ["LICENSE", "NOTICE"]
-        rename "LICENSE", "license.txt"
-        rename "NOTICE", "notice.txt"
-    }
-    from("${liboExampleDocument}") {
-        rename ".*", "example.odt"
-    }
 
     // include icons
     into ('share') {
@@ -193,6 +185,19 @@ task copyAssets(type: Copy) {
     }
 }
 
+task copyAppResources(type: Copy) {
+    description "copies documents to make them available as app resources"
+    into 'res_generated/raw'
+    from("${liboInstdir}") {
+        includes = ["LICENSE", "NOTICE"]
+        rename "LICENSE", "license.txt"
+        rename "NOTICE", "notice.txt"
+    }
+    from("${liboExampleDocument}") {
+        rename ".*", "example.odt"
+    }
+}
+
 task createFullConfig(type: Copy) {
     // grab dir to clear whole hierarchy on clean target
     outputs.dir "assets_fullUI"
@@ -290,7 +295,8 @@ task createRCfiles {
 preBuild.dependsOn 'createRCfiles',
         'createStrippedConfigMain',
         'createStrippedConfigRegistry',
-        'createFullConfig'
+        'createFullConfig',
+        'copyAppResources'
 
 clean.dependsOn 'cleanCopyAssets',
         'cleanCreateStrippedConfig',
diff --git a/android/source/src/java/org/libreoffice/AboutDialogFragment.java b/android/source/src/java/org/libreoffice/AboutDialogFragment.java
index 6c944bae7ef1..8e4ddf0ae08c 100644
--- a/android/source/src/java/org/libreoffice/AboutDialogFragment.java
+++ b/android/source/src/java/org/libreoffice/AboutDialogFragment.java
@@ -30,9 +30,6 @@ import java.io.File;
 
 public class AboutDialogFragment extends DialogFragment {
 
-    private static final String DEFAULT_DOC_PATH = "/assets/example.odt";
-
-
     @NonNull @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
 
@@ -81,21 +78,21 @@ public class AboutDialogFragment extends DialogFragment {
                 .setNegativeButton(R.string.about_license, new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int id) {
-                        loadFromAbout("/assets/license.txt");
+                        loadFromAbout(R.raw.license);
                         dialog.dismiss();
                     }
                 })
                 .setPositiveButton(R.string.about_notice, new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int id) {
-                        loadFromAbout("/assets/notice.txt");
+                        loadFromAbout(R.raw.notice);
                         dialog.dismiss();
                     }
                 })
                 .setNeutralButton(R.string.about_moreinfo, new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int id) {
-                        loadFromAbout(DEFAULT_DOC_PATH);
+                        loadFromAbout(R.raw.example);
                         dialog.dismiss();
                     }
                 });
@@ -103,8 +100,8 @@ public class AboutDialogFragment extends DialogFragment {
         return builder.create();
     }
 
-    private void loadFromAbout(String input) {
-        Intent i = new Intent(Intent.ACTION_VIEW, Uri.fromFile(new File(input)));
+    private void loadFromAbout(int resourceId) {
+        Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("android.resource://" + BuildConfig.APPLICATION_ID + "/" + resourceId));
         String packageName = getActivity().getApplicationContext().getPackageName();
         ComponentName componentName = new ComponentName(packageName, LibreOfficeMainActivity.class.getName());
         i.setComponent(componentName);
diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 022965e65052..0048bad50fd7 100644
--- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -175,7 +175,8 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
 
         mDocumentUri = getIntent().getData();
         if (mDocumentUri != null) {
-            if (mDocumentUri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
+            if (mDocumentUri.getScheme().equals(ContentResolver.SCHEME_CONTENT)
+                    || mDocumentUri.getScheme().equals(ContentResolver.SCHEME_ANDROID_RESOURCE)) {
                 final boolean isReadOnlyDoc;
                 if (getIntent().getStringExtra(LibreOfficeUIActivity.NEW_DOC_TYPE_KEY) != null) {
                     // New document type string is not null, meaning we want to open a new document
@@ -296,53 +297,37 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
 
         try {
             mTempFile = File.createTempFile("LibreOffice", suffix, this.getCacheDir());
-            final FileChannel outputChannel = new FileOutputStream(mTempFile).getChannel();
-            try {
-                // need to run copy operation in a separate thread, since network access is not
-                // allowed from main thread, but that may happen here when underlying
-                // DocumentsProvider (like the NextCloud one) does that
-                class CopyThread extends Thread {
-                    /** Whether copy operation was successful. */
-                    private boolean result = false;
-
-                    @Override
-                    public void run() {
-                        result = false;
-                        try {
-                            final AssetFileDescriptor assetFD = contentResolver.openAssetFileDescriptor(mDocumentUri, "r");
-                            if (assetFD == null) {
-                                Log.e(LOGTAG, "couldn't create assetfiledescriptor from " + mDocumentUri);
-                                return;
-                            }
-                            FileChannel inputChannel = assetFD.createInputStream().getChannel();
-                            long bytesTransferred = 0;
-                            // might not  copy all at once, so make sure everything gets copied...
-                            while (bytesTransferred < inputChannel.size()) {
-                                bytesTransferred += outputChannel.transferFrom(inputChannel, bytesTransferred, inputChannel.size());
-                            }
-                            Log.e(LOGTAG, "Success copying " + bytesTransferred + " bytes");
-                            inputChannel.close();
-                        } catch (IOException e) {
-                            e.printStackTrace();
-                            return;
-                        }
-                        result = true;
+            final FileOutputStream outputStream = new FileOutputStream(mTempFile);
+            // need to run copy operation in a separate thread, since network access is not
+            // allowed from main thread, but that may happen here when underlying
+            // DocumentsProvider (like the NextCloud one) does that
+            class CopyThread extends Thread {
+                /** Whether copy operation was successful. */
+                private boolean result = false;
+
+                @Override
+                public void run() {
+                    result = false;
+                    try {
+                        InputStream inputStream = contentResolver.openInputStream(mDocumentUri);
+                        result = copyStream(inputStream, outputStream);
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                        return;
                     }
-                };
-                CopyThread copyThread = new CopyThread();
-                copyThread.start();
-                try {
-                    // wait for copy operation to finish
-                    // NOTE: might be useful to add some indicator in UI for long copy operations involving network...
-                    copyThread.join();
-                } catch (InterruptedException e) {
-                    e.printStackTrace();
                 }
-
-                return copyThread.result;
-            } finally {
-                outputChannel.close();
+            };
+            CopyThread copyThread = new CopyThread();
+            copyThread.start();
+            try {
+                // wait for copy operation to finish
+                // NOTE: might be useful to add some indicator in UI for long copy operations involving network...
+                copyThread.join();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
             }
+
+            return copyThread.result;
         } catch (FileNotFoundException e) {
             return false;
         } catch (IOException e) {


More information about the Libreoffice-commits mailing list