1. 常规方法,重写WebChromeClient 的 openFileChooser 方法
private class MyWebChromeClient extends WebChromeClient {
// For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
if (mUploadMessage != null) return;
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*"); startActivityForResult( Intent.createChooser( i, "File Chooser" ), 1 );
}
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser( uploadMsg, "" );
}
// For Android > 4.1.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)
{
openFileChooser(uploadMsg, acceptType);
} }
这个是大家常用的,但是这个openFileChooser不是公开的方法,android4.4 不支持,肿么办?判断版本,如果是4.4就调用系统浏览器是个变通的方法,到时可以用,但是客户不认可,只有自己用app自己实现上传了。
2. 自己实现上传
private String post(String pathToOurFile) throws ClientProtocolException, IOException, JSONException {
HttpClient httpclient = new DefaultHttpClient();
//设置通信协议版本
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); HttpPost httppost = new HttpPost(uploadUrl);
File file = new File(pathToOurFile); MultipartEntity mpEntity = new MultipartEntity(); //文件传输
ContentBody cbFile = new FileBody(file);
mpEntity.addPart("userfile", cbFile); // <input type="file" name="userfile" /> 对应的 httppost.setEntity(mpEntity); HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity(); String json="";
String path="";
if (resEntity != null) {
json=EntityUtils.toString(resEntity,"utf-8");
JSONObject p=null;
try{
p=new JSONObject(json);
path=(String) p.get("path");
}catch(Exception e){
e.printStackTrace();
}
}
if (resEntity != null) {
resEntity.consumeContent();
} httpclient.getConnectionManager().shutdown();
return path;
}
用到了 httpmine包,网上有下载。
如何调用呢?
browser.addJavascriptInterface(this, "android"); browser是webview对象。
在页面<a href="javascrijpt:window.android.uploadFile()">上传文件</a>
uploadFile() 是被调用的Activity的一个方法,主要就是打开选择对话框,流程和第一种方法一样。只是返回文件路径后自己上传。
新版android系统到是可以了,又出现了问题:在android2.3等版本有个bug,从js调用app的方法会崩溃,不兼容,我们只能换一种方法调用这个uploadFile
另外编译的时候最好选择2.2版本,不要选择2.3
3. 过滤url, 重写 WebViewClient的 shouldOverrideUrlLoading方法
private class MyWebViewClient extends WebViewClient{
private Context mContext;
public MyWebViewClient(Context context){
super();
mContext = context;
} public boolean shouldOverrideUrlLoading(WebView view, String url)
{
if (url.equalsIgnoreCase("app:upload")) {
MainActivity.this.uploadFile();
return true;
}
view.loadUrl(url);
return true;
}
}
页面中 <a href="app:upload">上传文件</a>
Android 的兼容性问题真让人头疼啊 --