这是indexloc提供的服务,不要输入任何密码
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
android:exported="false"/>
<activity android:name=".StorageGetAPI$StorageActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:excludeFromRecents="true"
android:excludeFromRecents="false"
android:exported="false"/>
<activity android:name=".SAFAPI$SAFActivity"
android:theme="@style/TransparentTheme"
Expand Down
167 changes: 140 additions & 27 deletions app/src/main/java/com/termux/api/StorageGetAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.JsonWriter;

import androidx.annotation.Nullable;

import com.termux.api.util.ResultReturner;
import com.termux.api.util.TermuxApiLogger;
Expand All @@ -16,52 +20,128 @@

public class StorageGetAPI {

private static final String FILE_EXTRA = "com.termux.api.storage.file";
private static final String INTENT_EXTRA = "com.termux.api.storage.intent";
private static final int ERROR_COPY_FILE = 1;
private static final int ERROR_INITIATE_INTENT = 2;

static void onReceive(TermuxApiReceiver apiReceiver, final Context context, final Intent intent) {
ResultReturner.returnData(apiReceiver, intent, out -> {
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("wait", false)) {
ResultReturner.returnData(apiReceiver, intent, out -> { });
}
}

public static class StorageActivity extends Activity {

private String outputFile;
private Intent mIntent;
private boolean wait;
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");
wait = mIntent.getBooleanExtra("wait", 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);
Expand All @@ -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 (wait) {
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();
}

}

}