It's more work, but you could bundle an activity that lists the files in the ASD and presents them in a list. Then, when people trigger the picker, ask if they want content from this app or shared data and take the appropriate branch.
Actually, you may not even have to write the activity. The ListPickerActivity App Inventor uses for the ListPicker component is technically bundled with every app (it just isn't in the manifest if the ListPicker isn't used). You would activate it in the manifest using the @UsesActivities annotation as you can see at line 57 of ListPicker.java:
You need to register your extension as an ActivityResultListener interface to receive the selection and launch the activity when needed:
Then it's just a matter of listing the files in the ASD and providing that in the Intent. Nested directories might be harder if that's a use case you are considering.
I have applied the changes and all errors gone (not tested yet because...)
Final piece of the puzzle, should I generate the list in the app then pass it to the extension, or do something (more code) in the extension to generate the list?
Would probably need help with the latter...
I guess this would need to be a method so that it could be run at initalisation and after files have updated.
@SimpleFunction
public void AstAction(YailList fileNames) {
String[] items = fileNames.toStringArray();
for (int i = 0, len = items.length; i < len; i++) {
String item = items[i];
// what do you want to do now? append the full ASD Path?
// you can do:
// item = YOUR_ASD_PATH + '/' + item;
// then update the item
items[i] = item;
}
... some code
lpi.putExtra("com.google.appinventor.components.runtime.ListPickerActivity.list", items);
...
}
Now then, nothing happens after I make a selection from the listpicker. No filename is returned to the web page (not being picked up by the input tag) - I tested with a full path as well.
Need to return the file path from the listpicker selection ?
Here is the relevant java code
public class ChromeClient extends WebChromeClient {
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePath;
click();
return true;
}
}
public void click() {
BeforePicking(fileType);
if (requestCode == 0) {
requestCode = container.$form().registerForActivityResult(this);
}
if ( defaultDirectory == false ) {
container.$context().startActivityForResult(getIntent(), requestCode);
} else {
container.$context().startActivityForResult(getIntentLPI(), requestCode);
}
}
protected Intent getIntentLPI () {
Intent lpi = new Intent();
lpi.setClassName(container.$context(), "com.google.appinventor.components.runtime.ListPickerActivity");
lpi.putExtra("com.google.appinventor.components.runtime.ListPickerActivity.list", asdFiles);
return lpi;
}
protected Intent getIntent() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType(fileType);
return Intent.createChooser(i, "File Chooser");
}
public void resultReturned(int requestCode, int resultCode, Intent data) {
Uri[] results = null;
if (resultCode == Activity.RESULT_OK) {
String dataString = data.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
AfterPicking(getFileName(Uri.parse(dataString)));
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
}
public String getFileName(Uri uri) {
String result = null;
if (uri.getScheme().equals("content")) {
try (Cursor cursor = context.getContentResolver().query(uri, null, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
}
}
if (result == null) {
result = uri.getPath();
int cut = result.lastIndexOf('/');
if (cut != -1) {
result = result.substring(cut + 1);
}
}
return result;
}
I am guessing work needs to be done in the resultReturned / getFileName areas ?
Looking at the implementation of resultReturned in the ListPicker class, it looks like you will need to call data.getStringExtra("com.google.appinventor.components.runtime.ListPickerActivity.selection") to extract the selection value returned from the ListPickerActivity. It's not returned in the data URI portion of the Intent.