我一直在努力从WebView上传文件。我在谷歌上搜索并实施了所有建议的解决方案(例如这篇SO帖子),但没有一个可行。
我有一个HTML页面与以下代码上传文件。
<form method="POST" enctype="multipart/form-data">
File to upload: <input type="file" name="uploadfile">
<input type="submit" value="Press to Upload..."> to upload the file!
</form>
它在桌面浏览器如Firefox和内置浏览器中运行良好
的模拟器/ AVD,即,当我点击“浏览…”按钮渲染
元素,浏览器打开一个对话框
框,在那里我可以选择一个文件上传。
然而,在android 3.0模拟器/ AVD中,当我点击“选择”
文件”,什么都没有发生,没有文件对话框被打开!
这是一个完整的解决方案,所有的android版本,我有一个艰难的时间与此。
public class MyWb extends Activity {
/** Called when the activity is first created. */
WebView web;
ProgressBar progressBar;
private ValueCallback<Uri> mUploadMessage;
private final static int FILECHOOSER_RESULTCODE=1;
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
if(requestCode==FILECHOOSER_RESULTCODE)
{
if (null == mUploadMessage) return;
Uri result = intent == null || resultCode != RESULT_OK ? null
: intent.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
web = (WebView) findViewById(R.id.webview01);
progressBar = (ProgressBar) findViewById(R.id.progressBar1);
web = new WebView(this);
web.getSettings().setJavaScriptEnabled(true);
web.loadUrl("http://www.script-tutorials.com/demos/199/index.html");
web.setWebViewClient(new myWebClient());
web.setWebChromeClient(new WebChromeClient()
{
//The undocumented magic method override
//Eclipse will swear at you if you try to put @Override here
// For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
MyWb.this.startActivityForResult(Intent.createChooser(i,"File Chooser"), FILECHOOSER_RESULTCODE);
}
// For Android 3.0+
public void openFileChooser( ValueCallback uploadMsg, String acceptType ) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
MyWb.this.startActivityForResult(
Intent.createChooser(i, "File Browser"),
FILECHOOSER_RESULTCODE);
}
//For Android 4.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
MyWb.this.startActivityForResult( Intent.createChooser( i, "File Chooser" ), MyWb.FILECHOOSER_RESULTCODE );
}
});
setContentView(web);
}
public class myWebClient extends WebViewClient
{
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
view.loadUrl(url);
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
}
}
//flipscreen not loading again
@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
}
// To handle "Back" key press event for WebView to go back to previous screen.
/*@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK) && web.canGoBack()) {
web.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}*/
}
我还想补充一点,像这个例子中的“上传页面”,不会在< 4个版本上工作,因为它有一个图像预览功能,如果你想让它工作,使用一个简单的php上传没有预览。
更新:
请在这里找到棒棒糖装置的解决方案,感谢gauntface
更新2:
完整的解决方案,所有android设备,直到奥利奥这里,这是更高级的版本,你应该看看,也许它可以帮助。
我发现我需要3个接口定义,以处理不同版本的android。
public void openFileChooser(ValueCallback < Uri > uploadMsg) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
FreeHealthTrack.this.startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILECHOOSER_RESULTCODE);
}
public void openFileChooser(ValueCallback < Uri > uploadMsg, String acceptType) {
openFileChooser(uploadMsg);
}
public void openFileChooser(ValueCallback < Uri > uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg);
}
2019:这段代码对我有效(在android 5 - 9上测试)。
package com.example.filechooser;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Bundle;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends Activity {
// variables para manejar la subida de archivos
private final static int FILECHOOSER_RESULTCODE = 1;
private ValueCallback<Uri[]> mUploadMessage;
// variable para manejar el navegador empotrado
WebView mainWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// instanciamos el webview
mainWebView = findViewById(R.id.main_web_view);
// establecemos el cliente interno para que la navegacion no se salga de la aplicacion
mainWebView.setWebViewClient(new MyWebViewClient());
// establecemos el cliente chrome para seleccionar archivos
mainWebView.setWebChromeClient(new MyWebChromeClient());
// configuracion del webview
mainWebView.getSettings().setJavaScriptEnabled(true);
// cargamos la pagina
mainWebView.loadUrl("https://example.com");
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
// manejo de seleccion de archivo
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == mUploadMessage || intent == null || resultCode != RESULT_OK) {
return;
}
Uri[] result = null;
String dataString = intent.getDataString();
if (dataString != null) {
result = new Uri[]{ Uri.parse(dataString) };
}
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
// ====================
// Web clients classes
// ====================
/**
* Clase para configurar el webview
*/
private class MyWebViewClient extends WebViewClient {
// permite la navegacion dentro del webview
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
/**
* Clase para configurar el chrome client para que nos permita seleccionar archivos
*/
private class MyWebChromeClient extends WebChromeClient {
// maneja la accion de seleccionar archivos
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
// asegurar que no existan callbacks
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(null);
}
mUploadMessage = filePathCallback;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*"); // set MIME type to filter
MainActivity.this.startActivityForResult(Intent.createChooser(i, "File Chooser"), MainActivity.FILECHOOSER_RESULTCODE );
return true;
}
}
}
希望能帮到你。