[ 
https://issues.apache.org/jira/browse/CB-5294?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13839160#comment-13839160
 ] 

Marcel Kinard commented on CB-5294:
-----------------------------------

I've looked at this a bit, to see if there is a workaround, especially a 
workaround that could be transparent to app developers. Here is what I've found 
thus far.

Prior to Android 4.4, Android's WebChromeClient class had an undocumented 
public openFileChooser() method that had a default implementation to ignore 
what was passed to it. CordovaChromeClient.java would override that method to 
grab a reference to the ValueCallback, start a file picker activity and get the 
result, and pass the value back by invoking 
ValueCallback.onReceiveValue(filePickerResult). I think that is basically the 
callback which allows us to take the result from the file picker and set the 
value of the form's input object. There has been chatter that this undocumented 
public method has disappeared in 4.4, but I think that is a red herring, it 
should still be there: see 
https://android.googlesource.com/platform/frameworks/base/+/android-4.4_r1/core/java/android/webkit/WebChromeClient.java
 - it is still there and unchanged from 4.3. But note that the javadoc for that 
method has always had a "@hide" tag, which keeps it out of the generated 
javadoc and appears to also remove that method from the android.jar in the SDK 
on the workstation (which is why Eclipse complains if @Override is used in 
CordovaChromeClient.java - android.jar on the workstation has only the 
non-hidden public methods). That's fine, because the android.jar from the 
workstation doesn't go into the apk, I'm assuming that the full class with 
public-hidden and private methods (in dex format) gets resolved at runtime on 
the device, which includes the openFileChooser() method in WebChromeClient. So 
I think it is safe to ignore the "openFileChooser() method was removed in 4.4" 
discussion, though it is hard to explicitly prove it other than looking at the 
Android source.

So then that means that our openFileChooser() probably isn't getting called. 
https://code.google.com/p/android/issues/detail?id=62220 fits right on that, 
and reading comment #24 there indicates there is a Chromium bug that was fixed 
in the Chromium source on Nov 19, which will be shippable in a later version of 
Chromium. So the hope is that fixes it, assuming there is a way to get that 
newer Chromium on the device ( see 
https://plus.google.com/+GoogleChromeDevelopers/posts/4QYG9AE589M )

So on to looking for any viable workarounds...

The type="file" input button does generate an onClick event. So anyone can 
write js to respond to that event. But the value property of the type="file" 
input object in the DOM is read-only in js, so it isn't possible to set it from 
js. That is for security reasons.

So if it is not possible to set the input value via js, and openFileChooser() 
in CordovaChromeClient no longer gets called so we never get a handle to the 
ValueCallback, I'm not seeing any way that we could set the value of the file 
input button, even if we were to provide our own picker activity. This means 
there is no way for a type="file" input to be used to store the result from a 
picker.

So then that leaves the us with having to use some other type of input object 
to store the filename. And the expected issue with that is the browser's form 
processing wouldn't know to send the file's contents instead of the filename. 
Perhaps we could take over the submit action and do an xhr2.send(FormData) 
using a transient form we constructed ourselves from the original HTML one, 
with the same action and method. But this sounds like a bad idea, similar to 
our earlier effort to recreate a camera app to keep our suspended activity from 
getting killed when RAM runs short.

So now it sounds like there is no viable way to workaround this in a way that 
is transparent to an app developer. The only workaround is for them to modify 
their app to use the FileTransfer plugin in the case of Android 4.4, assuming 
their server's service endpoint can deal with that input/upload.

Does anyone have other ideas on a viable workaround? Anything I've gotten wrong?

> File input element not opening file picker in Android 4.4
> ---------------------------------------------------------
>
>                 Key: CB-5294
>                 URL: https://issues.apache.org/jira/browse/CB-5294
>             Project: Apache Cordova
>          Issue Type: Bug
>          Components: Android
>    Affects Versions: 3.1.0
>         Environment: Android 4.4 (emulator and Nexus 5)
>            Reporter: Paul Kane
>            Assignee: Joe Bowser
>
> The file input field doesn't respond when clicked/tapped in Android 4.4. 
> Works fine in previous Android versions. This is regardless of whether the 
> Target Level is set to 18 or 19.
> To reproduce, I created a fresh Cordova 3.1.0 project for Android. The only 
> modification I made to the default (placeholder) index.html file was adding a 
> <form> element with a single <input type="file"> element inside. Clicking the 
> "Choose File" button does nothing. No Logcat output or errors. Normally at 
> this point a dialogue would open allowing me to select an image from the 
> gallery or take a picture, which is what happens in older Android versions.



--
This message was sent by Atlassian JIRA
(v6.1#6144)

Reply via email to