I am supposed to display a web page in a webview in an app. The page contains a html form where one of the fields is file. So it goes something like...
<input type="file" name="file">
If I open the page in the browser and press the Choose File button, file chooser pops up and everything is good, but when I press the Choose File button in the webview nothing happens :/
Any ideas how to make this work?
WebView by default doesn't open file chooser. However it is possible to make this work. WebChromeClient
has hidden method openFileChooser
, which needs to be overridden to pop up a file chooser and then return the result to WebView. According to gurus one should never use hidden methods of Android SDK so this is not a good solution, and probably shouldn't be used in enterprise apps. However Android's stock Browser does exactly this way. Little more information how I overrode this method is in my this question. If anyone needs the source let me know Ill post it somewhere.
Is it possible to upload files via webview?
This feature is available in version 1.3.0 and newer. For older versions of the app, yes it is possible, but you need to add some extra code to make it work. Add following code into your AndroidManifest.xml file. Place it below other uses-permission elements:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Copy/paste this java class MediaUtility.java into the project. Place it into com/robotemplates/webviewapp/utility directory.
Open MainFragment.java in fragment package. Find renderView() method and replace “webView.setWebChromeClient(new WebChromeClient());” by following code:
webView.setWebChromeClient(new WebChromeClient()
{
public void openFileChooser(ValueCallback<Uri> filePathCallback)
{
mFilePathCallback4 = filePathCallback;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
startActivityForResult(Intent.createChooser(intent, "File Chooser"), REQUEST_FILE_PICKER);
}
public void openFileChooser(ValueCallback filePathCallback, String acceptType)
{
mFilePathCallback4 = filePathCallback;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
startActivityForResult(Intent.createChooser(intent, "File Chooser"), REQUEST_FILE_PICKER);
}
public void openFileChooser(ValueCallback<Uri> filePathCallback, String acceptType, String capture)
{
mFilePathCallback4 = filePathCallback;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
startActivityForResult(Intent.createChooser(intent, "File Chooser"), REQUEST_FILE_PICKER);
}
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
{
mFilePathCallback5 = filePathCallback;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
startActivityForResult(Intent.createChooser(intent, "File Chooser"), REQUEST_FILE_PICKER);
return true;
}
});
Finally add following code somewhere inside the MainFragment object (for instance below this line “private boolean mLocal = false;”):
private static final int REQUEST_FILE_PICKER = 1;
private ValueCallback<Uri> mFilePathCallback4;
private ValueCallback<Uri[]> mFilePathCallback5;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
if(requestCode==REQUEST_FILE_PICKER)
{
if(mFilePathCallback4!=null)
{
Uri result = intent==null || resultCode!=Activity.RESULT_OK ? null : intent.getData();
if(result!=null)
{
String path = MediaUtility.getPath(getActivity(), result);
Uri uri = Uri.fromFile(new File(path));
mFilePathCallback4.onReceiveValue(uri);
}
else
{
mFilePathCallback4.onReceiveValue(null);
}
}
if(mFilePathCallback5!=null)
{
Uri result = intent==null || resultCode!=Activity.RESULT_OK ? null : intent.getData();
if(result!=null)
{
String path = MediaUtility.getPath(getActivity(), result);
Uri uri = Uri.fromFile(new File(path));
mFilePathCallback5.onReceiveValue(new Uri[]{ uri });
}
else
{
mFilePathCallback5.onReceiveValue(null);
}
}
mFilePathCallback4 = null;
mFilePathCallback5 = null;
}
}
Don’t forget to add necessary imports: “import android.webkit.ValueCallback;”, “import com.robotemplates.webviewapp.utility.MediaUtility;”, “import java.io.File;”. If you still have a problem, try to add a rule in Proguard script: https://code.google.com/p/android/issues/detail?id=62220#c120.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With