欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android中webview的使用

程序员文章站 2022-03-28 12:24:50
一、问题:在顶部或者底部反复快速滑动界面,会出现自动向反方向滚动,或者视频有声音没有画面。 解决:在AndroidManifest.xml中给webview所在的activity添加硬件加速的属性:android:hardwareAccelerated="true"。 说明:1、view控件不能开启 ......

一、问题:在顶部或者底部反复快速滑动界面,会出现自动向反方向滚动,或者视频有声音没有画面。

  解决:在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,即要更新好每个节点。