Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>Update 6/18:</strong> This doesn't seem to work on Samsung Galaxy S2 with Android 4.2.1. This worked fine on HTC One X+ with 4.1.2. Be cautioned.</p> <hr> <p>I faced the same problem. Here's the problem and how I solved it.</p> <p><strong>Problem:</strong></p> <p>When <code>openFileChooser</code> is called, the call back object <code>ValueCallback&lt;Uri&gt;</code> is being passed. This is the actual call back to web view when we have a file ready for it. We save this object to <code>mUploadMessage</code> and use <code>mUploadMessage.onReceiveValue()</code> function in <code>onActivityResult</code> to return the file to Webview. While you choose camera, click a picture, save it and return to the webview activity, our activity <strong>might</strong> get recycled, which means we actually lose the call back object <code>mUploadMessage</code>. And hence, the file cannot be passed back to webview for upload.</p> <p><strong>Fix:</strong></p> <p>Fix involves executing some javascript, so enable javascript on webview. Basically, we will get another call back object if we lost the previous one.</p> <p>We need to create a boolean field '<code>mUploadFileOnLoad</code>' and three fields.</p> <pre><code> private int mReturnCode; private int mResultCode; private Intent mResultIntent; private boolean mUploadFileOnLoad = false; </code></pre> <p>When we return to our activity from camera, <code>onActivityResult</code> will be called. If activity is reconstructed, mUploadMessage is null. So, we will save the parameters to fields and set <code>mUploadFileOnLoad</code> to true and return. The else part is very important.</p> <pre><code> @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { //if the callback object has been recycled if(null==mUploadMessage) { //Save the result mReturnCode = requestCode; mResultCode = resultCode; mResultIntent = intent; //remember to invoke file upload using Javascript mUploadFileOnLoad = true; return; }else mUploadFileOnLoad = false; //rest of the code } </code></pre> <p>The important parts of this solution are in <code>WebViewClient</code> and <code>WebChromeClient</code></p> <pre><code> new WebChromeClient() { //Other overloaded functions //See http://stackoverflow.com/a/15423907/375093 for full explanation //The undocumented magic method override //Eclipse will swear at you if you try to put @Override here // For Android &lt; 3.0 public void openFileChooser(ValueCallback&lt;Uri&gt; uploadMsg) { //If we lost the callback object if(mUploadFileOnLoad) { mUploadMessage = uploadMsg; //use the saved result objects to invoke onActivityResult onActivityResult(mReturnCode, mResultCode, mResultIntent); return; } //Rest of the code.... } </code></pre> <p>and</p> <pre><code> new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { if(mUploadFileOnLoad) { webview.loadUrl("javascript:document.getElementById('my_file').click()"); } } </code></pre> <p>In the above, <code>my_file</code> is the id of the <code>&lt;input&gt;</code> element in the web page.</p> <pre><code>&lt;input type="file" id="my_file"&gt; </code></pre> <p>So, in summary, what we did is - When we don't have a callback object, we save the data received from other activity and set <code>mUploadFileOnLoad</code> to true and wait for page to load. When page loads, we use Javascript to invoke the file chooser so we get a callback object. Since we already have results, we invoke <code>onActivityResult</code> and return. onActivityResult now has a callback from the webview.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload