安卓手机中采用webview访问OA系统,当OA中使用input=file的方式时,点选择文件没有反应,需要在WebChromeClient中增加openFileChooser方法;chrome浏览器input=file文件路径出现c:fakepath,smartUpload上传不成功的解决办法;在WebView通过addView方式打开附件不能关闭的解决办法
在MainActivity中定义ValueCallback变量
//在MainActivity中定义ValueCallback变量
public ValueCallback<Uri> mUploadMessage;
//在MainActivity中增加setUploadMessage方法,提供给WebChromeClient调用
public void setUploadMessage(ValueCallback<Uri> uploadMessage) {
mUploadMessage = uploadMessage;
}
在WebChromeClient实现类MyWebChromeClient中增加MainActivity变量
//在MyWebChromeClient中增加MainActivity变量
public MainActivity mainActivity = null;
//增加MyWebChromeClient构造函数,传入MainActivity
public MyWebChromeClient(MainActivity activity) {
mainActivity = activity;
}
修改MainActivity中新建WebChromeClient的方法
//onCreateView中,新建MyWebChromeClient时,传入MainActivity
webView1.setWebChromeClient(
new MyWebChromeClient((MainActivity)this.getActivity()));
在MyWebChromeClient中实现openFileChooser
//For Android > 4.1.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
//必须要把uploadMsg传给MainActivity,否则无法接收选中的文件
mainActivity.setUploadMessage(uploadMsg);
//打开选择文件的窗口
mainActivity.startActivityForResult(Intent.createChooser(intent, "文件上传"), 1);
}
//For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
mainActivity.setUploadMessage(uploadMsg);
mainActivity.startActivityForResult(Intent.createChooser(intent, "文件上传"), 1);
}
//For Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
mainActivity.setUploadMessage(uploadMsg);
mainActivity.startActivityForResult(Intent.createChooser(intent, "文件上传"), 1);
}
在MainActivity中增加onActivityResult
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == 1) {
if (null == mUploadMessage) {
return;
}
Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData();
//接收选中的文件路径
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
完成以上步骤已经,可以实现选择文件
使用SmartUpload保存文件没有上传到服务器的问题
这个功能采用IE浏览器访问并上传图片是正常的,采用手机webview上传文字可以保存,图片不能保存,在电脑上用chrome浏览器测试也不能保存。
测试发现chrome中使用input=file选择文件时,只显示文件名称,用js获取file的路径是“c:fakepath”开头,没有显示文件的真实路径。虽然没有显示文件的真实路径,其实没有影响文件上传的,问题出在SmartUpload的upload方法。
采用IE时获取的filePath是完整的,smartUpload解析到文件名fileName,如果没有fileName就continue。采用chrome时获取的filePath就是文件名,相同的方法解析fileName就会为空,自然就放弃上传了。
以下是SmartUpload中update的相关部分。虽然SmartUpload原始版本有不少bug,这些年修修补补还是很耐用的。
filePath = fileItem.getName();
if (filePath.equals("")) {
continue;
}
iLastIndex = filePath.lastIndexOf('\');
if (filePath.length() > iLastIndex && iLastIndex > 0) {
fileName = filePath.substring(iLastIndex+1, filePath.length());// 获取到文件的全名
}
if (fileName.equals("")) {
//continue;
//注释掉continue,空时将filePath赋给fileName,修改后支持chrome
fileName = filePath;
}
在WebView中查看附件后关闭的问题
之前在MyWebChromeClient中实现了onCreateWindow方法,用来实现采用WebView的方式实现window.open弹出窗口,我打开附件是用_blank的连接方式,同样被onCreateWindow拦截,并且采用WebView打开。悲剧的是window.open的页面都有window.close的按钮,附件却没有,打开的附件就一直在。
我用setOnLongClickListener方式,当长按时自动关闭。在MyWebChromeClient的onCreateWindow方法里,实现:
newWebView.setOnLongClickListener(new WebView.OnLongClickListener() {
public boolean onLongClick(View v) {
newWebView.setVisibility(View.GONE);
newWebView.clearView();
return true;
}
});
我是用ADT,android4.0环境,测试机是三星Galaxy S4。网上的资料,大家都是抄来抄去,特别是中国的博客,搜索引擎搜出来的技术文章都大同小异。手机APP研究系列从1到8都是我自己经过代码和测试机验证后总结下来的,只是写了一些要点,不过对于相关问题的解决应该能带来一些帮助。