浅谈关于Android WebView上传文件的解决方案
程序员文章站
2023-12-19 10:38:46
我们在开发需求的时候,难免会接入一下第三方的h5页面,有些h5页面是具有上传照片的功能,android 中的 webview是不能直接打开文件选择弹框的
接下来我讲简...
我们在开发需求的时候,难免会接入一下第三方的h5页面,有些h5页面是具有上传照片的功能,android 中的 webview是不能直接打开文件选择弹框的
接下来我讲简单提供一下解决方案,先说一下思路
1.接收webview打开文件选择器的通知
2.收到通知后,打开文件选择器等待用户选择需要上传的文件
3.在onactivityresult中得到用户选择的文件的uri
4.然后把uri传递给html5
这样就完成了一次h5选择文件的过程,下面我把代码贴出来自习看一下
首先,webview必须要支持js交互,所以要打开js交互
mwebview.getsettings().setjavascriptenabled(true);
当h5在调用上传文件的api的时候,webview会回调 openfilechooser和onshowfilechooser 方法来通知我们,我们这个时候要做的就是重写这个方法
需要注意的是这个方法在不同的api上会回调不同行参方法
mwebview.setwebchromeclient(new webchromeclient() { @override public void onprogresschanged(webview view, int newprogress) { if (newprogress == 100) { mbar.setvisibility(view.gone); } else { mbar.setvisibility(view.visible); mbar.setprogress(newprogress); } super.onprogresschanged(view, newprogress); } //for android api < 11 (3.0 os) public void openfilechooser(valuecallback<uri> valuecallback) { uploadmessage = valuecallback; openimagechooseractivity(); } //for android api >= 11 (3.0 os) public void openfilechooser(valuecallback<uri> valuecallback, string accepttype, string capture) { uploadmessage = valuecallback; openimagechooseractivity(); } //for android api >= 21 (5.0 os) @override public boolean onshowfilechooser(webview webview, valuecallback<uri[]> filepathcallback, webchromeclient.filechooserparams filechooserparams) { uploadmessageabovel = filepathcallback; openimagechooseractivity(); return true; } });
我们在openfilechooser方法中先保存了一下valuecallback的回调对象,这个对象最后用来通知h5文件地址,我们之后在调用openfilechooser方法来打开文件选择器
private void openimagechooseractivity() { intent i = new intent(intent.action_get_content); i.addcategory(intent.category_openable); i.settype("image/*"); startactivityforresult(intent.createchooser(i, "image chooser"), file_chooser_result_code); }
当用户选择完文件后,会调用onactivityresult方法,我们重写并等待回调
@override protected void onactivityresult(int requestcode, int resultcode, intent data) { super.onactivityresult(requestcode, resultcode, data); if (requestcode == file_chooser_result_code) { if (null == uploadmessage && null == uploadmessageabovel) return; uri result = data == null || resultcode != result_ok ? null : data.getdata(); if (uploadmessageabovel != null) { onactivityresultabovel(requestcode, resultcode, data); } else if (uploadmessage != null) { uploadmessage.onreceivevalue(result); uploadmessage = null; } } } @targetapi(build.version_codes.lollipop) private void onactivityresultabovel(int requestcode, int resultcode, intent intent) { if (requestcode != file_chooser_result_code || uploadmessageabovel == null) return; uri[] results = null; if (resultcode == activity.result_ok) { if (intent != null) { string datastring = intent.getdatastring(); clipdata clipdata = intent.getclipdata(); if (clipdata != null) { results = new uri[clipdata.getitemcount()]; for (int i = 0; i < clipdata.getitemcount(); i++) { clipdata.item item = clipdata.getitemat(i); results[i] = item.geturi(); } } if (datastring != null) results = new uri[]{uri.parse(datastring)}; } } uploadmessageabovel.onreceivevalue(results); uploadmessageabovel = null; }
onactivityresult就是用来通知h5用户选择的文件地址,在这个方法里,用我们之前保存的valuecallback对象,调用onreceivevalue方法,h5就可以收到我们传递给它的地址信息了!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。