zoukankan      html  css  js  c++  java
  • 安卓开发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都是我自己经过代码和测试机验证后总结下来的,只是写了一些要点,不过对于相关问题的解决应该能带来一些帮助。

  • 相关阅读:
    JS事件冒泡
    iis设置Gzip后,无后缀的url无法压缩解决 MVC iis GZIP
    SQL中的循环、for循环、游标
    采用CDN加速后,如何在程序里获取用户IP地址
    Resharper 的快捷键
    JS防后退跳转
    ASP.NET MVC如何实现自定义验证(服务端验证+客户端验证)
    Log4net创建日志及简单扩展
    统治世界的十大算法
    ffmpeg save rtsp stream
  • 原文地址:https://www.cnblogs.com/soarwell/p/3788463.html
Copyright © 2011-2022 走看看