From 4b41c0070e197022ebe13b9ab27a15b0e825c672 Mon Sep 17 00:00:00 2001
From: knyipab <46513942+knyipab@users.noreply.github.com>
Date: Sun, 13 Mar 2022 19:26:54 +0800
Subject: [PATCH 1/2] more features for StorageGetAPI: print URI, async,
folder, persistable, multiple, mimetype, etc.
---
app/src/main/AndroidManifest.xml | 2 +-
.../java/com/termux/api/StorageGetAPI.java | 167 +++++++++++++++---
2 files changed, 141 insertions(+), 28 deletions(-)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index cea78e993..1322d2d04 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -80,7 +80,7 @@
android:exported="false"/>
{
- final String fileExtra = intent.getStringExtra("file");
- if (fileExtra == null || !new File(fileExtra).getParentFile().canWrite()) {
- out.println("ERROR: Not a writable folder: " + fileExtra);
- return;
- }
-
+ try {
Intent intent1 = new Intent(context, StorageActivity.class);
- intent1.putExtra(FILE_EXTRA, fileExtra);
+ intent1.putExtra(INTENT_EXTRA, intent);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);
- });
+ } catch (Exception e) {
+ if (intent.getBooleanExtra("json", true)) {
+ ResultReturner.returnData(apiReceiver, intent, new ResultReturner.ResultJsonWriter() {
+ @Override
+ public void writeJson(JsonWriter out) throws Exception {
+ out.beginObject();
+ out.name("error").value(ERROR_INITIATE_INTENT);
+ out.name("uri").beginArray();
+ out.endArray();
+ out.endObject();
+ }
+ });
+ }
+ return;
+ }
+ if (!intent.getBooleanExtra("async", false)) {
+ ResultReturner.returnData(apiReceiver, intent, out -> { });
+ }
}
public static class StorageActivity extends Activity {
private String outputFile;
+ private Intent mIntent;
+ private boolean async;
+ private boolean folder;
+ private boolean persist;
+ private boolean multiple;
+ private boolean json;
+ private String mimeType;
+ private Uri[] data;
+ private int error;
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Intent intent = this.getIntent();
+ mIntent = intent.getParcelableExtra(INTENT_EXTRA);
+ outputFile = mIntent.getStringExtra("file");
+ mimeType = mIntent.getStringExtra("type");
+ async = mIntent.getBooleanExtra("async", false);
+ folder = mIntent.getBooleanExtra("folder", false);
+ persist = mIntent.getBooleanExtra("persist", false);
+ multiple = mIntent.getBooleanExtra("multiple", false);
+ json = mIntent.getBooleanExtra("json", true);
+ data = null;
+ error = 0;
+ }
@Override
public void onResume() {
super.onResume();
- outputFile = getIntent().getStringExtra(FILE_EXTRA);
-
- // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file browser.
- Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
-
- // Filter to only show results that can be "opened", such as a
- // file (as opposed to a list of contacts or timezones)
- intent.addCategory(Intent.CATEGORY_OPENABLE);
+ try {
+ // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file browser.
+ Intent intent = new Intent(folder ? Intent.ACTION_OPEN_DOCUMENT_TREE : Intent.ACTION_OPEN_DOCUMENT);
- intent.setType("*/*");
+ if (multiple && !folder) {
+ intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
+ }
- startActivityForResult(intent, 42);
+ // Filter to only show results that can be "opened", such as a
+ // file (as opposed to a list of contacts or timezones)
+ if (!folder) {
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setType("*/*");
+ if (mimeType != null) {
+ intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeType.split(","));
+ }
+ }
+ int flags = folder ? Intent.FLAG_GRANT_PREFIX_URI_PERMISSION : 0;
+ if (persist) {
+ flags |= Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
+ }
+ intent.setFlags(flags);
+
+ startActivityForResult(intent, 42);
+ } catch (Exception e) {
+ if (json) {
+ ResultReturner.returnData(this, mIntent, new ResultReturner.ResultJsonWriter() {
+ @Override
+ public void writeJson(JsonWriter out) throws Exception {
+ out.beginObject();
+ out.name("error").value(ERROR_INITIATE_INTENT);
+ out.name("uri").beginArray();
+ out.endArray();
+ out.endObject();
+ }
+ });
+ }
+ }
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent resultData) {
+ InputStream in = null;
+ OutputStream out = null;
super.onActivityResult(requestCode, resultCode, resultData);
if (resultCode == RESULT_OK) {
- Uri data = resultData.getData();
try {
- try (InputStream in = getContentResolver().openInputStream(data)) {
- try (OutputStream out = new FileOutputStream(outputFile)) {
+ if(resultData.getClipData() != null) { // checking multiple selection or not
+ data = new Uri[resultData.getClipData().getItemCount()];
+ for(int i = 0; i < resultData.getClipData().getItemCount(); i++) {
+ data[i] = resultData.getClipData().getItemAt(i).getUri();
+ }
+ } else {
+ data = new Uri[1];
+ data[0] = resultData.getData();
+ }
+ if (!folder && outputFile != null) {
+ for (int i = 0; i < data.length; i++) {
+ in = getContentResolver().openInputStream(data[i]);
+ out = new FileOutputStream(multiple ? String.format(outputFile, i) : outputFile);
byte[] buffer = new byte[8192];
while (true) {
int read = in.read(buffer);
@@ -71,15 +151,48 @@ protected void onActivityResult(int requestCode, int resultCode, Intent resultDa
out.write(buffer, 0, read);
}
}
+ in.close();
+ out.close();
}
}
- } catch (IOException e) {
- TermuxApiLogger.error("Error copying " + data + " to " + outputFile);
+
+ } catch (Exception e) {
+ TermuxApiLogger.error("Error copying file(s). ");
+ error = ERROR_COPY_FILE;
+ } finally {
+ try { if (in != null) { in.close(); } } catch (Exception e) { }
+ try { if (out != null) { out.close(); } } catch (Exception e) { }
}
}
- finish();
+ if (async) {
+ if (json) {
+ ResultReturner.returnData(this, mIntent, new ResultReturner.ResultJsonWriter() {
+ @Override
+ public void writeJson(JsonWriter out) throws Exception {
+ out.beginObject();
+ out.name("error").value(error);
+ out.name("uri").beginArray();
+ if (data != null) {
+ for (int i = 0; i < data.length; i++) {
+ out.value(data[i].toString());
+ }
+ }
+ out.endArray();
+ out.endObject();
+ }
+ });
+ } else {
+ ResultReturner.returnData(this, mIntent, output -> {
+ if (data != null) {
+ for (int i = 0; i < data.length; i++) {
+ output.println(data[i].toString());
+ }
+ }
+ });
+ }
+ }
+ finishAndRemoveTask();
}
-
}
}
From bae72acdee297e692c5ca29a91c2f7b6a3dae82e Mon Sep 17 00:00:00 2001
From: knyipab <46513942+knyipab@users.noreply.github.com>
Date: Sun, 13 Mar 2022 22:11:39 +0800
Subject: [PATCH 2/2] fix wording
---
app/src/main/java/com/termux/api/StorageGetAPI.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/app/src/main/java/com/termux/api/StorageGetAPI.java b/app/src/main/java/com/termux/api/StorageGetAPI.java
index 539ae7ea9..4a171d3df 100644
--- a/app/src/main/java/com/termux/api/StorageGetAPI.java
+++ b/app/src/main/java/com/termux/api/StorageGetAPI.java
@@ -45,7 +45,7 @@ public void writeJson(JsonWriter out) throws Exception {
}
return;
}
- if (!intent.getBooleanExtra("async", false)) {
+ if (!intent.getBooleanExtra("wait", false)) {
ResultReturner.returnData(apiReceiver, intent, out -> { });
}
}
@@ -54,7 +54,7 @@ public static class StorageActivity extends Activity {
private String outputFile;
private Intent mIntent;
- private boolean async;
+ private boolean wait;
private boolean folder;
private boolean persist;
private boolean multiple;
@@ -70,7 +70,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
mIntent = intent.getParcelableExtra(INTENT_EXTRA);
outputFile = mIntent.getStringExtra("file");
mimeType = mIntent.getStringExtra("type");
- async = mIntent.getBooleanExtra("async", false);
+ wait = mIntent.getBooleanExtra("wait", false);
folder = mIntent.getBooleanExtra("folder", false);
persist = mIntent.getBooleanExtra("persist", false);
multiple = mIntent.getBooleanExtra("multiple", false);
@@ -164,7 +164,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent resultDa
try { if (out != null) { out.close(); } } catch (Exception e) { }
}
}
- if (async) {
+ if (wait) {
if (json) {
ResultReturner.returnData(this, mIntent, new ResultReturner.ResultJsonWriter() {
@Override