Android-WebView支持input file启用相机/选取照片
程序员文章站
2023-01-22 19:23:24
webview要调起input file拍照或者选取文件功能,可以在webview.setWebChromeClient方法中重写指定的方法,来拦截webview的input事件,并做我们相应的操作。 Android代码 这里的java代码是来拦截input事件的,里面做了很多api版本的判断,不同 ......
webview要调起input-file拍照或者选取文件功能,可以在webview.setwebchromeclient方法中重写指定的方法,来拦截webview的input事件,并做我们相应的操作。
android代码
webview.setwebchromeclient(new webchromeclient() { @override public void onprogresschanged(webview view, int newprogress) { if (newprogress == 100) { progressbar.setvisibility(view.gone);//加载完网页进度条消失 } else { progressbar.setprogress(newprogress);//设置进度值 progressbar.setvisibility(view.visible);//开始加载网页时显示进度条 } } /** * 8(android 2.2) <= api <= 10(android 2.3)回调此方法 */ private void openfilechooser(android.webkit.valuecallback<uri> uploadmsg) { log.e("wangj", "运行方法 openfilechooser-1"); // (2)该方法回调时说明版本api < 21,此时将结果赋值给 muploadcallbackbelow,使之 != null muploadcallbackbelow = uploadmsg; takephoto(); } /** * 11(android 3.0) <= api <= 15(android 4.0.3)回调此方法 */ public void openfilechooser(android.webkit.valuecallback<uri> uploadmsg, string accepttype) { log.e("wangj", "运行方法 openfilechooser-2 (accepttype: " + accepttype + ")"); // 这里我们就不区分input的参数了,直接用拍照 openfilechooser(uploadmsg); } /** * 16(android 4.1.2) <= api <= 20(android 4.4w.2)回调此方法 */ public void openfilechooser(android.webkit.valuecallback<uri> uploadmsg, string accepttype, string capture) { log.e("wangj", "运行方法 openfilechooser-3 (accepttype: " + accepttype + "; capture: " + capture + ")"); // 这里我们就不区分input的参数了,直接用拍照 openfilechooser(uploadmsg); } /** * api >= 21(android 5.0.1)回调此方法 */ @override public boolean onshowfilechooser(webview webview, valuecallback<uri[]> valuecallback, filechooserparams filechooserparams) { log.e("wangj", "运行方法 onshowfilechooser"); // (1)该方法回调时说明版本api >= 21,此时将结果赋值给 muploadcallbackabovel,使之 != null muploadcallbackabovel = valuecallback; takephoto(); return true; } });
这里的java代码是来拦截input事件的,里面做了很多api版本的判断,不同版本的api调用不同的方法,下面是一些其他方法:
调起相机/选择文件的方法:takephoto();
/** * 调用相机 */ private void takephoto() { // 指定拍照存储位置的方式调起相机 string filepath = environment.getexternalstoragedirectory() + file.separator + environment.directory_pictures + file.separator; string filename = "img_" + dateformat.format("yyyymmdd_hhmmss", calendar.getinstance(locale.china)) + ".jpg"; imageuri = uri.fromfile(new file(filepath + filename)); // intent intent = new intent(mediastore.action_image_capture); // intent.putextra(mediastore.extra_output, imageuri); // startactivityforresult(intent, request_code); // 选择图片(不包括相机拍照),则不用成功后发刷新图库的广播 // intent i = new intent(intent.action_get_content); // i.addcategory(intent.category_openable); // i.settype("image/*"); // startactivityforresult(intent.createchooser(i, "image chooser"), request_code); intent captureintent = new intent(android.provider.mediastore.action_image_capture); captureintent.putextra(mediastore.extra_output, imageuri); intent photo = new intent(intent.action_pick, android.provider.mediastore.images.media.external_content_uri); intent chooserintent = intent.createchooser(photo, "image chooser"); chooserintent.putextra(intent.extra_initial_intents, new parcelable[]{captureintent}); startactivityforresult(chooserintent, request_code); }
onactivityresult回调:
@override protected void onactivityresult(int requestcode, int resultcode, intent data) { super.onactivityresult(requestcode, resultcode, data); if (requestcode == request_code) { // 经过上边(1)、(2)两个赋值操作,此处即可根据其值是否为空来决定采用哪种处理方法 if (muploadcallbackbelow != null) { choosebelow(resultcode, data); } else if (muploadcallbackabovel != null) { chooseabove(resultcode, data); } else { toast.maketext(this, "发生错误", toast.length_short).show(); } } }
其他一些方法:
/** * android api < 21(android 5.0)版本的回调处理 * @param resultcode 选取文件或拍照的返回码 * @param data 选取文件或拍照的返回结果 */ private void choosebelow(int resultcode, intent data) { log.e("wangj", "返回调用方法--choosebelow"); if (result_ok == resultcode) { updatephotos(); if (data != null) { // 这里是针对文件路径处理 uri uri = data.getdata(); if (uri != null) { log.e("wangj", "系统返回uri:" + uri.tostring()); muploadcallbackbelow.onreceivevalue(uri); } else { muploadcallbackbelow.onreceivevalue(null); } } else { // 以指定图像存储路径的方式调起相机,成功后返回data为空 log.e("wangj", "自定义结果:" + imageuri.tostring()); muploadcallbackbelow.onreceivevalue(imageuri); } } else { muploadcallbackbelow.onreceivevalue(null); } muploadcallbackbelow = null; } /** * android api >= 21(android 5.0) 版本的回调处理 * @param resultcode 选取文件或拍照的返回码 * @param data 选取文件或拍照的返回结果 */ private void chooseabove(int resultcode, intent data) { log.e("wangj", "返回调用方法--chooseabove"); if (result_ok == resultcode) { updatephotos(); if (data != null) { // 这里是针对从文件中选图片的处理 uri[] results; uri uridata = data.getdata(); if (uridata != null) { results = new uri[]{uridata}; for (uri uri : results) { log.e("wangj", "系统返回uri:" + uri.tostring()); } muploadcallbackabovel.onreceivevalue(results); } else { muploadcallbackabovel.onreceivevalue(null); } } else { log.e("wangj", "自定义结果:" + imageuri.tostring()); muploadcallbackabovel.onreceivevalue(new uri[]{imageuri}); } } else { muploadcallbackabovel.onreceivevalue(null); } muploadcallbackabovel = null; } private void updatephotos() { // 该广播即使多发(即选取照片成功时也发送)也没有关系,只是唤醒系统刷新媒体文件 intent intent = new intent(intent.action_media_scanner_scan_file); intent.setdata(imageuri); sendbroadcast(intent); }
相关的全局变量:
private android.webkit.valuecallback<uri[]> muploadcallbackabovel; private android.webkit.valuecallback<uri> muploadcallbackbelow; private uri imageuri; private int request_code = 1234;
原文: