android WebView上传文件到服务器[android+server代码]
来源:互联网 发布:苹果如何清理游戏数据 编辑:程序博客网 时间:2024/05/18 00:59
最近比较坑爹,公司app部分页面要转H5,美其名曰称之为节约人力成本,无奈,我们就从后台PHP,JQuery从零开始学起。项目中遇到这么一个问题:要从android的WebView中上传用户头像到服务器,当初感觉蛮简单的,就没怎么注意,没想到一道道大坑摆在我面前,特此记录一下。
前端界面蛮丑的,这么就不说,基本上就像下图一样:
这里的加号图片,主要是美化上传用的,它还有一个作用就是图片预览功能,基本上代码如下:
$("#img").on("click", function () { $("#file").click(); });
就是讲img的点击事件,强制转化给file的点击事件,就是我们选择文件的事件,还是比较聪明的。
页面我就先不做优化了,采用的是ajax后台上传的,部分代码如下【全部代码将会最后给出】:
$("#upload").on("click",function () { var form = new FormData(document.getElementById("form")) ; $.ajax({ url: $("#upload").attr("data_url"), data: form, type: "post", cache:false, contentType:false, processData:false, dataType: "json", success: function (data) { console.log("-->>" + data.code + "...." + data.message); $("#id_msg").html(data.code + "------" + data.message); }, error: function () { console.log("error--------->>"); $("#id_msg").html("upload error"); } }); });
我们采用了FormData元素作为上传对象,具体参数意义,可参见这篇文章,基本上写得非常清楚了,这也解释了我第一次将表单序列化上传时,为什么会失败的原因了。
再就是服务器代码了,我采用的是thinkPHP3.2.3的方式,没有放开扯,毕竟这个还是比较简单的,不要问我为啥用java去写,当然我也是可以的,原因是我的Tomcat有些启动问题,这里不就扯多了,部分关键代码如下:
$upload = new Upload(); // 实例化上传类 $upload->maxSize = 5242880; // 设置附件上传大小 $upload->exts = array('jpg', 'gif', 'png', 'jpeg'); // 设置附件上传类型 $upload->rootPath = "./"; // 设置附件上传根目录 $upload->savePath = ''; // 设置附件上传(子)目录 $upload->saveName = array('date', '_ymdHis' . rand(100, 999)); $upload->subName = array('date', 'Ymd'); //子目录创建方式,[0]-函数名,[1]-参数,多个参数使用数组 $info = $upload->upload(); $arr = array(); if ($info) { $arr["code"] = 200; $arr["message"] = "success"; } else { $arr["code"] = -1; $arr["message"] = "error"; } exit(json_encode($arr));
当我屁颠屁颠的写完了这些代码,android直接写个webView加载我的本地网页,我想这不会这么简单吧,话刚说话,webview进入加载页面之后,效果出现了,我点添加的页面不动了,使用IOS测试,看下图:
IOS是有效果的,看来使我们的andorid中的webView存在问题啊,好吧,查查哪里出了问题吧,google之后,发现我们的webView对应的webChromeClient中有个这个方法:
告诉我们的client,来展示一个图片选择器,返回值如果是false,就执行默认操作;如果返回值是true,那么ValueCallback将会被调用,那好吧,那只有自己重写这个onShowFileChooser方法了,先设置一个回调,然后返回值设置为true:
@Override public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) { if (webCall != null) webCall.fileChose5(filePathCallback); return true ; } public interface WebCall { //android version < 5.0 void fileChose(ValueCallback<Uri> uploadMsg); //android version > 5.0 void fileChose5(ValueCallback<Uri[]> uploadMsg); }
设置webView的Client方法:
MyWebChromeClient client = new MyWebChromeClient(); client.setWebCall(this); mWebView.setWebChromeClient(client);
在Android代码中回调该方法:
@Override public void fileChose(ValueCallback<Uri> uploadMsg) { openFileChooserImpl(uploadMsg); } @Override public void fileChose5(ValueCallback<Uri[]> uploadMsg) { openFileChooserImplForAndroid5(uploadMsg); } //andoird版本小于5.0的实现 private void openFileChooserImpl(ValueCallback<Uri> uploadMsg) { mUploadMessage = uploadMsg; Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("image/*"); startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE); } //android版本大约5.0的实现 private void openFileChooserImplForAndroid5(ValueCallback<Uri[]> uploadMsg) { mUploadMessageForAndroid5 = uploadMsg; Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT); contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE); contentSelectionIntent.setType("image/*"); Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER); chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent); chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser"); startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE_FOR_ANDROID_5); }
然后设置其onActivityForResult方法:
@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; } else if (requestCode == FILECHOOSER_RESULTCODE_FOR_ANDROID_5) { if (null == mUploadMessageForAndroid5) return; Uri result = (intent == null || resultCode != RESULT_OK) ? null : intent.getData(); if (result != null) { mUploadMessageForAndroid5.onReceiveValue(new Uri[]{result}); } else { mUploadMessageForAndroid5.onReceiveValue(new Uri[]{}); } mUploadMessageForAndroid5 = null; } }
设置之后,编译运行代码,点击图片,我们想要的file chooser就出现了:
选择一张图片,然后上传:
200表示上传成功了,我们可以上服务器看一下图片:
嗯,我看到了我们上传的图片了,是的,android通过webview上传图片成功了,我特么搞了好几天你懂么??太多的问题不是很懂啊,不是很懂啊,中间遇到很多坑,刚开始以为是h5代码兼容性问题,一直在h5那里找错误,可是没想到居然是webview的client问题,好吧,再次记录一下。
感谢:
http://blog.csdn.net/qq_33556185/article/details/51086114
http://blog.csdn.net/atangsir/article/details/51388662
代码地址
- android WebView上传文件到服务器[android+server代码]
- Android上传文件到服务器的代码
- android 上传文件到服务器代码实例
- android 上传文件到服务器代码实例
- android WebView上传文件代码
- android文件上传到服务器
- android上传文件到服务器
- android文件上传到服务器
- android 上传文件到服务器
- android 文件上传到服务器
- Android上传文件到服务器
- Android上传文件到服务器
- android上传文件到服务器
- android上传文件到服务器
- android上传文件到服务器
- [android] 文件上传到服务器
- android -上传文件到服务器
- android上传文件到服务器
- Android文件操作工具类
- Java中的LinkedList
- linux命令dd
- python中的raw_input() 与 input()
- shiro教程(4)-shiro与项目集成开发
- android WebView上传文件到服务器[android+server代码]
- Image Pre-compensation: Balancing Contrast and Ringing
- C++中cin.clear()的用法
- LinearLayout的showDividers在小米上不管用的解决办法
- 静态代码块、非静态代码块、构造方法执行顺序
- Java学习----day7——(3)匿名内部类
- Js读取check的几种方法
- 历届试题 最大子阵
- iOS 在Unit Testing 里面使用第三方库