diff options
author | Michael Weghorn <m.weghorn@posteo.de> | 2021-03-19 13:07:41 +0100 |
---|---|---|
committer | Michael Weghorn <m.weghorn@posteo.de> | 2021-03-22 08:45:29 +0100 |
commit | b7e7f3aaf3618f29a40876823c0cfda47a9c11e3 (patch) | |
tree | 931f1aeb20d87bc37378a3f28d00a9d73d2c82e6 | |
parent | d8d7bc8c834beef0e03e652f3cef6b40ea509b87 (diff) |
tdf#129833 android: Allow editing writable docs passed by Intent
When a document is passed by an Intent in Android
Viewer, allow editing if the Intent has flag
'Intent.FLAG_GRANT_WRITE_URI_PERMISSION' set.
Since LibreOffice operates on a temporary copy
in this case, write the content of the
temporary file back to the original URI
when saving.
This in particular allows editing documents
passed from third-party apps, e.g. opened from
Android's "Files" app or the NextCloud app.
The online-based Android app already does
something similar.
Change-Id: Icf252a95dd9a8089ca8610ccf3edfbeee2682e1a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112767
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
(cherry picked from commit 2df8b776e635efc5e59aaf6c8a5a7f4c218d74d0)
4 files changed, 62 insertions, 2 deletions
diff --git a/android/source/res/values-de/strings.xml b/android/source/res/values-de/strings.xml index ff58b14babc5..64eaa844a754 100644 --- a/android/source/res/values-de/strings.xml +++ b/android/source/res/values-de/strings.xml @@ -96,6 +96,7 @@ <string name="message_saved">Speichern beendet</string> <string name="message_saving">Dokument wird gespeichert…</string> <string name="message_save_incomplete">Speichern unvollständig. Gab es Änderungen?</string> + <string name="message_saving_failed">Speichern des Dokuments ist fehlgeschlagen.</string> <string name="create_new_file_success">"Neue Datei angelegt - "</string> <string name="create_new_file_error">Neue Datei konnte nicht angelegt weden, bitte Prüfen Sie den eingegeben Dateinamen.</string> diff --git a/android/source/res/values/strings.xml b/android/source/res/values/strings.xml index aa32497862f6..a44d81ee5faf 100644 --- a/android/source/res/values/strings.xml +++ b/android/source/res/values/strings.xml @@ -95,6 +95,7 @@ <!-- Feedback messages --> <string name="message_saved">Save complete</string> <string name="message_saving">Saving the document…</string> + <string name="message_saving_failed">Saving the document failed.</string> <string name="message_save_incomplete">Save incomplete. Were there any changes?</string> <string name="create_new_file_success">"Created new file - "</string> <string name="create_new_file_error">Unable to create new file, please check entered file name.</string> diff --git a/android/source/src/java/org/libreoffice/InvalidationHandler.java b/android/source/src/java/org/libreoffice/InvalidationHandler.java index 32e9b56656dd..588fec9f5372 100644 --- a/android/source/src/java/org/libreoffice/InvalidationHandler.java +++ b/android/source/src/java/org/libreoffice/InvalidationHandler.java @@ -139,7 +139,7 @@ public class InvalidationHandler implements Document.MessageCallback, Office.Mes JSONObject payloadObject = new JSONObject(payload); if (payloadObject.getString("commandName").equals(".uno:Save")) { if (payloadObject.getString("success").equals("true")) { - mContext.saveFilesToCloud(); + mContext.saveFileToOriginalSource(); } }else if(payloadObject.getString("commandName").equals(".uno:Name") || payloadObject.getString("commandName").equals(".uno:RenamePage")){ diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java index b640fa404973..bf6108edc8af 100644 --- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java +++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java @@ -46,9 +46,11 @@ import org.mozilla.gecko.gfx.GeckoLayerClient; import org.mozilla.gecko.gfx.LayerView; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.net.URI; import java.nio.ByteBuffer; import java.nio.channels.Channels; @@ -191,7 +193,8 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin if (getIntent().getData().getScheme().equals(ContentResolver.SCHEME_CONTENT)) { if (copyFileToTemp() && mTempFile != null) { mInputFile = mTempFile; - mbISReadOnlyMode = true; + boolean isReadOnlyDoc = (getIntent().getFlags() & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; + mbISReadOnlyMode = !isExperimentalMode() || isReadOnlyDoc; Log.d(LOGTAG, "SCHEME_CONTENT: getPath(): " + getIntent().getData().getPath()); String displayName = extractDisplayNameFromIntent(); @@ -355,6 +358,61 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND_NOTIFY, ".uno:Save", true)); } + public void saveFileToOriginalSource() { + if (documentUri != null) { + // case where file was opened using IDocumentProvider from within LO app + saveFilesToCloud(); + } else { + // case where file was passed via Intent + if (isReadOnlyMode() || mInputFile == null || getIntent().getData() == null || !getIntent().getData().getScheme().equals(ContentResolver.SCHEME_CONTENT)) + return; + + Uri uri = getIntent().getData(); + FileInputStream inputStream = null; + OutputStream outputStream = null; + + try { + inputStream = new FileInputStream(mInputFile); + // OutputStream for the actual (original) location + outputStream = getContentResolver().openOutputStream(uri); + + byte[] buffer = new byte[4096]; + int readBytes = inputStream.read(buffer); + while (readBytes != -1) { + outputStream.write(buffer, 0, readBytes); + readBytes = inputStream.read(buffer); + } + + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(LibreOfficeMainActivity.this, R.string.message_saved, + Toast.LENGTH_SHORT).show(); + } + }); + setDocumentChanged(false); + } catch (Exception e) { + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(LibreOfficeMainActivity.this, R.string.message_saving_failed, + Toast.LENGTH_SHORT).show(); + } + }); + e.printStackTrace(); + } finally { + try { + if (inputStream != null) + inputStream.close(); + if (outputStream != null) + outputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + public void saveFilesToCloud(){ final Activity activity = LibreOfficeMainActivity.this; final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() { |