the data field of getFile() return is always an empty Uint8Array (Android SDK 28)
zxtxin opened this issue · comments
Yes, looks like data binding is wrong,
u added base64 value to the data property in android, can you please
JSONObject result = new JSONObject();
result.put("data", base64);
result.put("mediaType", mediaType);
result.put("name", name);
result.put("uri", uri.toString());
I tried using the plugin in an Ionic 3 project, running on Android 10.
The plugin usage in the project is extremely basic:
const filters = 'image/*,document/pdf,document/doc,document/docx,document/ppt,document/pptx,document/xls,document/xlsx';
window.chooser.getFile(filters, (file: any) => {
// success callback code goes here
}
By doing some analysis and adding some custom logs to the native Android code, it seems like is that this code below, at line 123 from Chooser.java, always returns false
.
data.getBooleanExtra(Chooser.INCLUDE_DATA, false)
Even if includeData
has the value true
in the code below at line 72, inside the execute()
method:
intent.putExtra(Chooser.INCLUDE_DATA, includeData);
According to some logs I added, I found the following:
// this is logged inside the "execute()" method, "args[1]" is supposed to be the boolean that decides if the base64 data should be returned
2020-07-08 03:33:54.545 16315-16768/<package.name> I/args[1]: true
// this is logged right before the extras are put into the intent for
2020-07-08 03:33:54.546 16315-16768/<package.name> I/chooseFile includeData: true
// This is logged inside the "onActivityResult()" method.
// The log is exactly this: Log.i("data getBooleanExtra", data.getBooleanExtra(Chooser.INCLUDE_DATA, false).toString());
// Even if "includeData" is set as true, this always results to false.
2020-07-08 03:19:31.960 16315-16315/<package.name> I/data getBooleanExtra: false /
Apparently, for some reason, it seems like the getBooleanExtra()
is not finding the value for the key Chooser.INCLUDE_DATA
in the Intent's extras, so it always uses the default value, false
.
I honestly don't know why this happens or if it's API-level specific, and I honestly can't put much more time and effort into understanding and solving this, right now. I'm also not acquainted with native Android development, so there's also that.
So, as a workaround, I'll simply change the default value for the Chooser.INCLUDE_EXTRA
to true
, like this:
data.getBooleanExtra(Chooser.INCLUDE_DATA, true)
I'll always need the Base64 string, anyways.
@CaioMelo8 is right,the Intent provided to the onActivityResult
method seems not to be the intent that is created with the extra data, thus intent.getExtras()
always returns null
.
I'm not an experienced Android developer so I changed the code to this, not sure if this is a proper solution.
private CallbackContext callback;
private Boolean includeData;
public void chooseFile (CallbackContext callbackContext, String accept, Boolean includeData) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
if (!accept.equals("*/*")) {
intent.putExtra(Intent.EXTRA_MIME_TYPES, accept.split(","));
}
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false);
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
this.includeData = includeData; // store in instance variable instead of extra
and then this:
@Override
public void onActivityResult (int requestCode, int resultCode, Intent data) {
try {
if (requestCode == Chooser.PICK_FILE_REQUEST && this.callback != null) {
if (resultCode == Activity.RESULT_OK) {
Uri uri = data.getData();
if (uri != null) {
ContentResolver contentResolver =
this.cordova.getActivity().getContentResolver()
;
String name = Chooser.getDisplayName(contentResolver, uri);
String mediaType = contentResolver.getType(uri);
if (mediaType == null || mediaType.isEmpty()) {
mediaType = "application/octet-stream";
}
String base64 = "";
if (this.includeData) {
byte[] bytes = Chooser.getBytesFromInputStream(
contentResolver.openInputStream(uri)
);
base64 = Base64.encodeToString(bytes, Base64.DEFAULT);
}
Sorry about the late response on this, and thanks a lot for the PR @se-schwarz! Your PR looks good to me and works in my testing.