Android中webview的使用
一、问题:在顶部或者底部反复快速滑动界面,会出现自动向反方向滚动,或者视频有声音没有画面。
解决:在androidmanifest.xml中给webview所在的activity添加硬件加速的属性:android:hardwareaccelerated="true"。
说明:1、view控件不能开启硬件加速(webview.setlayertype(view.layer_type_hardware,null);这个设置无效),但是view控件可以关闭该view的硬件加速:webview.setlayertype(view.layer_type_software,null);
2、setlayertype方法只有在api>11才有。
3、参考网址:
二、webview的设置
websettings websettings=webview.getsettings();
websettings.setusewideviewport(true);//设置webview是应该启用对“viewport”html元标记的支持还是应该使用宽视口。true:支持<meta>标签的viewport属性
if (build.version.sdk_int >= build.version_codes.jelly_bean_mr1) {
websettings.setmediaplaybackrequiresusergesture(false);
}
websettings.setblocknetworkloads(false);
websettings.setallowcontentaccess(true);
websettings.setloadwithoverviewmode(true);
websettings.setlayoutalgorithm(websettings.layoutalgorithm.single_column);
websettings.setjavascriptenabled(true);
if (build.version.sdk_int >= build.version_codes.lollipop) {
websettings.setmixedcontentmode(websettings.mixed_content_always_allow);
}
websettings.setdomstorageenabled(true);//设置是否启用dom存储api。默认false。
if (build.version.sdk_int >= build.version_codes.jelly_bean) {
websettings.setallowuniversalaccessfromfileurls(true);//可以解决有声音没图像得问题。设置是否允许在文件方案url上下文中运行的javascript访问来自任何来源的内容。同上。
}
websettings.setsupportzoom(true);
websettings.setallowfileaccess(true); //设置可以访问文件
websettings.setjavascriptcanopenwindowsautomatically(true); //支持通过js打开新窗口 websettings.setloadsimagesautomatically(true); //支持自动加载websettings.setpluginstate(websettings.pluginstate.on);
说明:参考网址:https://blog.csdn.net/zhanwubus/article/details/80340025
三、webview长按下载图片。
webview.setonlongclicklistener(new onlongclicklistener(){
@override
public boolean onlongclick(view view) {
int clicktype=webview.gethittestresult().gettype();
if (clicktype==webview.hittestresult.image_type||clicktype==webview.hittestresult.src_image_anchor_type){
log.d("webveiw","图片url="+wv.gethittestresult().getextra());
}
return false;
}
});
拓展:webview.hittestresult.edit_text_type:选中的文字类型;webview.hittestresult.phone_type:处理拨号;webview.hittestresult.email_type:处理email;webview.hittestresult.geo_type:地图类型;
webview.hittestresult.src_anchor_type:超链接;webview.hittestresult.src_image_anchor_type:带有链接的图片类型;webview.hittestresult.image_type:图片类型;
webview.hittestresult.unknown_type:未知类型。
四、webview调用原生上传图片,视频,文件等。
全局变量:
private valuecallback<uri> muploadmessage;
private string accepttypesstr;
private valuecallback<uri[]> uploadmessageabovel;
private static final int file_camera_result_code = 129;
private file fileupfile;
第一步:
webview.setwebchromeclient(new webchromeclient(){
// for android < 3.0
public void openfilechooser(valuecallback<uri> uploadmsg) {
muploadmessage = uploadmsg;
showimgseclect();
}
// for android > 4.1.1
public void openfilechooser(valuecallback<uri> uploadmsg,
string accepttype, string capture) {
accepttypesstr=accepttype;
muploadmessage = uploadmsg;
log.d("qtest",accepttypesstr);
showimgseclect();
}
// for android > 5.0支持多张上传
@targetapi(build.version_codes.lollipop)
public boolean onshowfilechooser(webview webview,
valuecallback<uri[]> uploadmsg,
webchromeclient.filechooserparams filechooserparams) {
accepttypesstr="";
for (string str:filechooserparams.getaccepttypes()){
accepttypesstr+=(textutils.isempty(accepttypesstr)?"":";")+str;
}
log.d("qtest",accepttypesstr);
uploadmessageabovel = uploadmsg;
showimgseclect();
return true;
}
});
第二步:
/**
* 显示相机和相册选择
*/
public void showimgseclect() {
//注意申请权限:manifest.permission.camera,manifest.permission.write_external_storage,manifest.permission.read_external_storage
if (textutils.isempty(accepttypesstr))return;
intent captureintent=new intent(mediastore.action_image_capture);
if (accepttypesstr.contains("image")){
captureintent = new intent(mediastore.action_image_capture);
fileupfile=new file(environment.getexternalstoragepublicdirectory(environment.directory_pictures).getabsolutepath()
+file.separator+"linan"+file.separator+"linan-"+system.currenttimemillis()+".jpg");
}else if (accepttypesstr.contains("video")){
captureintent = new intent(mediastore.action_video_capture);
fileupfile=new file(environment.getexternalstoragepublicdirectory(environment.directory_pictures).getabsolutepath()
+file.separator+"linan"+file.separator+"linan-"+system.currenttimemillis()+".mp4");
}
uri muri = null;
if (!fileupfile.getparentfile().exists()) {
fileupfile.getparentfile().mkdirs();
}
if (build.version.sdk_int >= build.version_codes.n) {
// 临时允许
captureintent.addflags(intent.flag_grant_read_uri_permission);
muri = fileprovider.geturiforfile(getcontext(), getpackagename() + ".fileprovider", fileupfile);
} else {
muri = uri.fromfile(fileupfile);
}
//需要显示应用的意图列表,这个list的顺序和选择菜单上的图标顺序是相关的,请注意。
list<intent> cameraintents = new arraylist<intent>();
packagemanager packagemanager = getcontext().getpackagemanager();
//获取手机里所有注册相机接收意图的应用程序,放到意图列表里(无他相机,美颜相机等第三方相机)
list<resolveinfo> listcam = packagemanager.queryintentactivities(captureintent, 0);
for (resolveinfo res : listcam) {
string packagename = res.activityinfo.packagename;
intent i = new intent(captureintent);
i.setcomponent(new componentname(res.activityinfo.packagename, res.activityinfo.name));
i.setpackage(packagename);
i.putextra(mediastore.extra_output, muri);
cameraintents.add(i);
}
//相册选择器
intent i = new intent(intent.action_get_content);
i.addcategory(intent.category_openable);
i.settype(accepttypesstr.contains("video")?"video/*":accepttypesstr);
//intent选择器
intent chooserintent = intent.createchooser(i, "choose");
chooserintent.putextra(intent.extra_initial_intents, cameraintents.toarray(new parcelable[]{}));
((commonweexactivity)getcontext()).startactivityforresult(chooserintent, file_camera_result_code);
}
第三步:
@override
public void onactivityresult(int requestcode, int resultcode, intent data) {
super.onactivityresult(requestcode, resultcode, data);
umshareapi.get(getcontext()).onactivityresult(requestcode, resultcode, data);//qq和新浪的回调
if (null == muploadmessage && null == uploadmessageabovel) {
return;
}
//没有返回值时的处理
if (resultcode != result_ok) {
//需要回调onreceivevalue方法防止下次无法响应js方法
if (uploadmessageabovel != null) {
uploadmessageabovel.onreceivevalue(null);
uploadmessageabovel = null;
}
if (muploadmessage != null) {
muploadmessage.onreceivevalue(null);
muploadmessage = null;
}
return;
}
uri result = null;
if (requestcode == file_camera_result_code) {
if (null != data && null != data.getdata()) {
result = data.getdata();
}
if (result == null) {
if (build.version.sdk_int >= build.version_codes.n) {
// 临时允许
result = fileprovider.geturiforfile(getcontext(), getpackagename() + ".fileprovider", fileupfile);
} else {
result = uri.fromfile(fileupfile);
}
}
//5.0以上设备的数据处理
if (uploadmessageabovel != null) {
uploadmessageabovel.onreceivevalue(new uri[]{result});
uploadmessageabovel = null;
} else if (muploadmessage != null) {
//5.0以下设备的数据处理
muploadmessage.onreceivevalue(result);
muploadmessage = null;
}
}
}
五、webview中的video标签,视频全屏处理。
fl_video_full是该界面布局文件中的占满布局的一个framelayout控件。
ll_webview是该界面布局文件中占满布局,包含webview。
gethostview().setwebchromeclient(new webchromeclient(){
@override
public void onhidecustomview() {
try {
if (webview.fl_video_full==null)return;
webview.ll_webview.setvisibility(view.visible);
webview.fl_video_full.setvisibility(view.gone);
webview.fl_video_full.removeallviews();
webview.setrequestedorientation(activityinfo.screen_orientation_portrait);webview.getwindow().clearflags(windowmanager.layoutparams.flag_fullscreen);
}catch (exception e){
log.d("qtest",e.tostring());
}
super.onhidecustomview();
}
@override
public void onshowcustomview(view view, customviewcallback callback) {
try{
videofull=view;
webview.ll_webview.setvisibility(view.gone);
webview.fl_video_full.setvisibility(view.visible);
webview.fl_video_full.addview(videofull);
webview.setrequestedorientation(activityinfo.screen_orientation_landscape);
webview.getwindow().setflags(windowmanager.layoutparams.flag_fullscreen,windowmanager.layoutparams.flag_fullscreen); }catch (exception e){
log.d("qtest",e.tostring());
}
super.onshowcustomview(view, callback);
}
});
六、销毁webveiw
if (webveiw!= null) {
webveiw.loaddatawithbaseurl(null, "", "text/html", "utf-8", null);
webveiw.clearhistory();
((viewgroup)webveiw.getparent()).removeview(wv);
webveiw.destroy();
webveiw= null;
}
七、问题:webview加载https链接会出现空白页。
解决方法:
webviewclient webviewclient = new webviewclient() {
@override
public void onreceivedsslerror(webview view, sslerrorhandler handler, sslerror error) {
// super.onreceivedsslerror(view, handler, error);
try {
handler.proceed();
}catch (exception e){}
}
};
说明:ssl证书过期的话,更新证书需要注意除了服务器端,可能还需要更新dns,即要更新好每个节点。