安卓开发8-WebView支持文件上传

安卓手机中采用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都是我自己经过代码和测试机验证后总结下来的,只是写了一些要点,不过对于相关问题的解决应该能带来一些帮助。

原文地址:https://www.cnblogs.com/soarwell/p/3788463.html