summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Weghorn <m.weghorn@posteo.de>2021-03-19 14:29:36 +0100
committerMichael Weghorn <m.weghorn@posteo.de>2021-03-22 08:45:41 +0100
commit45c1efea0e31caf3f9484479a8f63ba4b9b4a294 (patch)
tree63d385b34ccfcd9cf534a22bcfbc5f1012ce8a08
parentb7e7f3aaf3618f29a40876823c0cfda47a9c11e3 (diff)
tdf#129833 android: Allow opening files using system file picker
Extend Android Viewer with the possibility to select a file to open using the "system file picker", which can be opened by an Intent that has the action 'Intent.ACTION_OPEN_DOCUMENT' (or 'Intent.ACTION_GET_CONTENT' for API level < 19) set. This way, all locations supported by currently installed and set up DocumentsProviders [1] are generally supported. In a test, opening local files worked just fine, but trying to open a file located in a NextCloud share failed (with the corresponding app [2] installed), showing this in ADB log: I DownloadFileOperation: Download of /Documents/five_pages.odt to /storage/emulated/0/Android/media/com.nextcloud.client/nextcloud/<USERNAME>@demo2.nextcloud.com/Documents/five_pages.odt: Unexpected exception E DocumentsStorageProvider: RemoteOperationResult(mSuccess=false, mHttpCode=-1, mHttpPhrase=null, mException=android.os.NetworkOnMainThreadException, mCode=HOST_NOT_AVAILABLE, message=null, getLogMessage=Unexpected exception) This will be dealt with in a separate commit. For now, this way to open files (and a corresponding menu entry) is added in addition to the existing ones, but since that method should in general be able to cover all of the other use cases as well, the other options may be dropped in the future. [1] https://developer.android.com/reference/android/provider/DocumentsProvider [2] https://github.com/nextcloud/android Change-Id: I684a4aa770c0df7cc9fc35ff92445230405885f5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112768 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> (cherry picked from commit d678ee309b02b4cc8af29a097bf5053b8b1b4e06)
-rw-r--r--android/source/res/drawable-hdpi/ic_folder_grey_144dp.xml5
-rw-r--r--android/source/res/layout/activity_document_browser.xml20
-rw-r--r--android/source/res/menu/navigation_menu.xml5
-rw-r--r--android/source/res/values-de/strings.xml3
-rw-r--r--android/source/res/values/strings.xml3
-rw-r--r--android/source/src/java/org/libreoffice/ui/FileUtilities.java1
-rw-r--r--android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java102
7 files changed, 139 insertions, 0 deletions
diff --git a/android/source/res/drawable-hdpi/ic_folder_grey_144dp.xml b/android/source/res/drawable-hdpi/ic_folder_grey_144dp.xml
new file mode 100644
index 000000000000..4ba799e20ef1
--- /dev/null
+++ b/android/source/res/drawable-hdpi/ic_folder_grey_144dp.xml
@@ -0,0 +1,5 @@
+<vector android:autoMirrored="true" android:height="144dp"
+ android:viewportHeight="24.0" android:viewportWidth="24.0"
+ android:width="144dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#FF606060" android:pathData="M10,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8c0,-1.1 -0.9,-2 -2,-2h-8l-2,-2z"/>
+</vector>
diff --git a/android/source/res/layout/activity_document_browser.xml b/android/source/res/layout/activity_document_browser.xml
index 8e17a3e1624f..b3b4ace2a465 100644
--- a/android/source/res/layout/activity_document_browser.xml
+++ b/android/source/res/layout/activity_document_browser.xml
@@ -104,6 +104,26 @@
android:background="@color/background_normal"
android:orientation="vertical" />
+ <!--Icon and text to open system file picker via Intent -->
+ <LinearLayout
+ android:id="@+id/system_file_picker_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="?attr/colorButtonNormal"
+ android:orientation="horizontal"
+ app:layout_constraintTop_toBottomOf="@id/toolbar">
+
+ <TextView
+ android:id="@+id/open_file_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:drawableLeft="@drawable/ic_folder_grey_144dp"
+ android:gravity="center_vertical"
+ android:text="@string/select_file_to_open"
+ android:textSize="24dp" />
+ </LinearLayout>
+
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
diff --git a/android/source/res/menu/navigation_menu.xml b/android/source/res/menu/navigation_menu.xml
index 4098b27b8cac..ef6354b5dcff 100644
--- a/android/source/res/menu/navigation_menu.xml
+++ b/android/source/res/menu/navigation_menu.xml
@@ -19,6 +19,11 @@
<item android:id="@+id/menu_provider_otg"
android:title="@string/otg_file_system"
android:icon="@drawable/ic_usb_black_24dp"/>
+
+ <item android:id="@+id/menu_system_file_dialog"
+ android:title="@string/system_file_selector"
+ android:icon="@drawable/ic_folder_black_24dp" />
+
</group>
<group android:orderInCategory="100">
diff --git a/android/source/res/values-de/strings.xml b/android/source/res/values-de/strings.xml
index 64eaa844a754..4c6e25342ef7 100644
--- a/android/source/res/values-de/strings.xml
+++ b/android/source/res/values-de/strings.xml
@@ -22,6 +22,9 @@
<string name="new_drawing">Neue Zeichnung</string>
<string name="default_document_name">unbenannt</string>
+ <string name="system_file_selector">System-Dateidialog</string>
+ <string name="select_file_to_open">Datei zum Öffnen auswählen</string>
+
<string name="browser_app_name">LibreOffice Browser</string>
<string name="menu_search">Suchen</string>
<string name="list_view">Liste</string>
diff --git a/android/source/res/values/strings.xml b/android/source/res/values/strings.xml
index a44d81ee5faf..8205176df685 100644
--- a/android/source/res/values/strings.xml
+++ b/android/source/res/values/strings.xml
@@ -22,6 +22,9 @@
<string name="new_drawing">New Drawing</string>
<string name="default_document_name">untitled</string>
+ <string name="system_file_selector">System File Dialog</string>
+ <string name="select_file_to_open">Select file to open</string>
+
<string name="browser_app_name">LibreOffice Browser</string>
<string name="menu_search">Search</string>
<string name="list_view">List</string>
diff --git a/android/source/src/java/org/libreoffice/ui/FileUtilities.java b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
index 7a58486004cd..28f1906a6369 100644
--- a/android/source/src/java/org/libreoffice/ui/FileUtilities.java
+++ b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
@@ -56,6 +56,7 @@ public class FileUtilities {
private static final Map<String, String> extensionToMimeTypeMap = new HashMap<String, String>();
static {
// Please keep this in sync with AndroidManifest.xml
+ // and 'SUPPORTED_MIME_TYPES' in LibreOfficeUIActivity.java
// ODF
mExtnMap.put(".odt", DOC);
diff --git a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
index f52972b86f26..8e84868dbda5 100644
--- a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
+++ b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
@@ -12,6 +12,7 @@ package org.libreoffice.ui;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -127,9 +128,51 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
public static final String NEW_CALC_STRING_KEY = "private:factory/scalc";
public static final String NEW_DRAW_STRING_KEY = "private:factory/sdraw";
+ // keep this in sync with 'AndroidManifext.xml'
+ private static final String[] SUPPORTED_MIME_TYPES = {
+ "application/vnd.oasis.opendocument.text",
+ "application/vnd.oasis.opendocument.graphics",
+ "application/vnd.oasis.opendocument.presentation",
+ "application/vnd.oasis.opendocument.spreadsheet",
+ "application/vnd.oasis.opendocument.text-flat-xml",
+ "application/vnd.oasis.opendocument.graphics-flat-xml",
+ "application/vnd.oasis.opendocument.presentation-flat-xml",
+ "application/vnd.oasis.opendocument.spreadsheet-flat-xml",
+ "application/vnd.oasis.opendocument.text-template",
+ "application/vnd.oasis.opendocument.spreadsheet-template",
+ "application/vnd.oasis.opendocument.graphics-template",
+ "application/vnd.oasis.opendocument.presentation-template",
+ "application/rtf",
+ "text/rtf",
+ "application/msword",
+ "application/vnd.ms-powerpoint",
+ "application/vnd.ms-excel",
+ "application/vnd.visio",
+ "application/vnd.visio.xml",
+ "application/x-mspublisher",
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
+ "application/vnd.openxmlformats-officedocument.presentationml.template",
+ "text/csv",
+ "text/comma-separated-values",
+ "application/vnd.ms-works",
+ "application/vnd.apple.keynote",
+ "application/x-abiword",
+ "application/x-pagemaker",
+ "image/x-emf",
+ "image/x-svm",
+ "image/x-wmf",
+ "image/svg+xml",
+ };
+
public static final int GRID_VIEW = 0;
public static final int LIST_VIEW = 1;
+ private static final int REQUEST_CODE_OPEN_FILECHOOSER = 12345;
+
private DrawerLayout drawerLayout;
private NavigationView navigationDrawer;
private ActionBar actionBar;
@@ -151,6 +194,8 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
private LinearLayout writerLayout;
private LinearLayout impressLayout;
private LinearLayout calcLayout;
+ private LinearLayout systemFilePickerLayout;
+ private TextView openFileView;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -207,6 +252,8 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
impressLayout = findViewById(R.id.impressLayout);
calcLayout = findViewById(R.id.calcLayout);
drawLayout = findViewById(R.id.drawLayout);
+ openFileView = findViewById(R.id.open_file_view);
+ openFileView.setOnClickListener(this);
recentRecyclerView = findViewById(R.id.list_recent);
@@ -228,6 +275,7 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
recentRecyclerView.setAdapter(new RecentFilesAdapter(this, recentFiles));
fileRecyclerView = findViewById(R.id.file_recycler_view);
+ systemFilePickerLayout = findViewById(R.id.system_file_picker_layout);
//This should be tested because it possibly disables view recycling
fileRecyclerView.setNestedScrollingEnabled(false);
openDirectory(currentDirectory);
@@ -277,6 +325,11 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
return true;
}
+ case R.id.menu_system_file_dialog: {
+ switchToSystemFileDialogLayout();
+ return true;
+ }
+
default:
return false;
}
@@ -306,6 +359,9 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
drawerToggle.setDrawerIndicatorEnabled(true);
drawerLayout.addDrawerListener(drawerToggle);
drawerToggle.syncState();
+
+ // initially show layout with item to open system file picker
+ switchToSystemFileDialogLayout();
}
private void expandFabMenu() {
@@ -418,7 +474,43 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
return viewMode == LIST_VIEW;
}
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_CODE_OPEN_FILECHOOSER && resultCode == RESULT_OK) {
+ final Uri fileUri = data.getData();
+
+ // "forward" to LibreOfficeMainActivity to open the file
+ Intent intent = new Intent(Intent.ACTION_VIEW, fileUri);
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ String packageName = getApplicationContext().getPackageName();
+ ComponentName componentName = new ComponentName(packageName,
+ LibreOfficeMainActivity.class.getName());
+ intent.setComponent(componentName);
+ startActivity(intent);
+ }
+ }
+
+ private void showSystemFilePickerAndOpenFile() {
+ Intent intent = new Intent();
+ try {
+ intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
+ } catch (ActivityNotFoundException exception) {
+ // Intent.ACTION_OPEN_DOCUMENT added in API level 19, but minSdkVersion is currently 16
+ intent.setAction(Intent.ACTION_GET_CONTENT);
+ }
+
+ intent.setType("*/*");
+ intent.putExtra(Intent.EXTRA_MIME_TYPES, SUPPORTED_MIME_TYPES);;
+
+ if (intent.resolveActivity(getPackageManager()) != null) {
+ startActivityForResult(intent, REQUEST_CODE_OPEN_FILECHOOSER);
+ }
+ }
+
+
private void switchToDocumentProvider(IDocumentProvider provider) {
+ fileRecyclerView.setVisibility(View.VISIBLE);
+ systemFilePickerLayout.setVisibility(View.GONE);
new AsyncTask<IDocumentProvider, Void, Void>() {
@Override
@@ -467,6 +559,13 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
}.execute(provider);
}
+ private void switchToSystemFileDialogLayout() {
+ fileRecyclerView.setVisibility(View.GONE);
+ findViewById(R.id.text_directory_path).setVisibility(View.GONE);
+ systemFilePickerLayout.setVisibility(View.VISIBLE);
+ refreshView();
+ }
+
public void openDirectory(IFile dir) {
if (dir == null)
return;
@@ -1065,6 +1164,9 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
expandFabMenu();
}
break;
+ case R.id.open_file_view:
+ showSystemFilePickerAndOpenFile();
+ break;
case R.id.newWriterFAB:
createNewFileInputDialog(getString(R.string.default_document_name) + FileUtilities.DEFAULT_WRITER_EXTENSION, NEW_WRITER_STRING_KEY);
break;