• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

Android

WebView-Android与H5交互

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/Android/2019/0727/584.html

配置cookie、post要求、滑动监听、点击监听、关闭音频视频
 
 
mWbRealize.loadUrl("http://www.homeqin.com/s/vknb0n8W?eqrcode=1&from=singlemessage&isappinstalled=0");
 
//支持javascript
 
web.getSettings().setJavaScriptEnabled(true);
 
// 配置可以支持缩放
 
web.getSettings().setSupportZoom(true);
 
// 配置出现缩下班具
 
web.getSettings().setBuiltInZoomControls(true);
 
//扩大比例的缩放
 
web.getSettings().setUseWideViewPort(true);//让webview读取网页配置的viewport,pc版网页
 
//自适应屏幕
 
web.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);//适应屏幕,内容将自动缩放 
 
webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);//适应内容大小 
 
web.getSettings().setLoadWithOverviewMode(true);
 
settings.setDomStorageEnabled(true);//翻开DOM储存API
 
settings.setBlockNetworkImage(true);//阻挡图片的加载
 
web.setInitialScale(25);//为25%,非常小缩放品级
 
 
 
// 配置缓存模式:不应用缓存
 
 mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
 
// 配置启动缓存 
 
 webView.getSettings().setDefaultTextEncodingName("utf-8"); 
 
 webView.getSettings().setAppCacheEnabled(true);
 
 webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 
 
postUrl
 
//必要走访的网址 
 
String url = "http://www.cqjg.gov.cn/netcar/FindThree.aspx"; 
 
//post走访必要提交的参数 
 
String postDate = "txtName=zzz&QueryTypeLst=1&CertificateTxt=dsds"; 
 
//因为webView.postUrl(url, postData)中 postData范例为byte[] , 
 
//通过EncodingUtils.getBytes(data, charset)要领进行转换 
 
webView.postUrl(url, EncodingUtils.getBytes(postDate, "UTF-8")); 
 
 
 
EncodingUtils是 HttpCore内部的,要加依附
 
compile 'org.apache.httpcomponents:httpcore:4.4.4'
 
网页只加载出一片面,下面就不加载了?
 
  ● I/chromium(27693): [INFO:CONSOLE(8)] “Uncaught TypeError: Cannot call method ‘getItem’ of null”, source: url
 
网页加载不实现并报出如上错误时,有不妨你的DOM储存API没有翻开,在代码中加上一行:
 
mWebView.getSettings().setDomStorageEnabled(true);
 
要是有望点击链接由本人处分,而不是新开Android的体系browser中相应该链接。给WebView加一个事件监听工具(WebViewClient)并重写此中的少许要领:shouldOverrideUrlLoading:对网页中超链接按钮的相应。当按下某个持续时WebViewClient会挪用这个要领,并传递参数:按下的url。
 
webView.setWebViewClient(new WebViewClient(){
 
         @Override
 
         public boolean shouldOverrideUrlLoading(WebView view, String url) {
 
 
 
          view.loadUrl(url);   //在目前的webview中跳转到新的url
 
 //要是不必要其余对点击链赴任件的处分回笼true,否则回笼false
 
          return true;
 
         }
 
   @Override
 
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
 
 
 
            if (url.startsWith("http") || url.startsWith("https")) { //http和https和谈开首的执行平常的流程
 
                return super.shouldInterceptRequest(view, url);
 
            } else {  //其余的URL则会开启一个Acitity而后去挪用原生APP
 
 
 
                if (url.contains("mqqwpa")){
 
 
 
 
 
                    if (OthersUtil.isQQClientAvailable(mContext)){
 
 
 
                        Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
 
                        startActivity(in);
 
                        return null;
 
                    }else {
 
 
 
//                        Toast.makeText(mContext, "您的手机未安置手机QQ", Toast.LENGTH_SHORT).show();
 
//                        return super.shouldInterceptRequest(view, url);
 
                        return null;
 
                    }
 
                }
 
 
 
                Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
 
                startActivity(in);
 
                return null;
 
            }
 
        }
 
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
 
//            showErrorPage();//显示错误页面
 
            hideErrorPage();
 
        };
 
        public void onPageFinished(WebView view, String url) {//处分网页加载胜利时
 
//            loading_over.setVisibility(View.GONE);
 
//            hideErrorPage();
 
        }
 
//监听webview界面切换
 
@Override
 
public void onPageStarted(WebView view, String url, Bitmap favicon) {
 
    super.onPageStarted(view, url, favicon);
 
    if (url.contains("https://www.hzjr.com/Mobile/Index/customer?token=")){
 
        mCloseService.setVisibility(View.GONE);
 
    }
 
}
 
        });
 
加载html标签
 
mWebView.loadDataWithBaseURL(null, stringHtml, "text/html", "utf-8", null);
 
onReceivedError 不行捕获腐朽的回调???
 
onReceivedError 有两个重载的要领,要重写第二个
 
 
 
1、public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
 
 
 
2、 public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
 
setWebChromeClient
 
setWebChromeClient主要处分剖判,渲染网页等涉猎器做的工作
 
 
 
WebChromeClient是辅助WebView处分Javascript的对话框,网站图标,网站title,加载进度等
 
 
 
onCloseWindow(关闭WebView)
 
 
 
onCreateWindow()
 
 
 
onJsAlert (WebView上alert不行弹出来的,要WebChromeClient处分)
 
 
 
onJsPrompt
 
 
 
onJsConfirm
 
 
 
onProgressChanged
 
 
 
onReceivedIcon
 
 
 
onReceivedTitle
 
setWebViewClient
 
WebViewClient是赞助WebView处分种种关照、要求事件的
 
 
 
onLoadResource
 
 
 
onPageStart
 
 
 
onPageFinish
 
 
 
onReceiveError
 
 
 
onReceivedHttpAuthRequest
 
点击超链接启动QQ
 
mWebView = (ProgressWebView) findViewById(R.id.baseweb_webview); mWebView.getSettings().setJavaScriptEnabled(true); String url ="http://wpa.qq.com/msgrd?v=3&uin=748895431&site=qq&menu=yes"; mWebView.loadUrl(url); mWebView.setWebViewClient(new WebViewClient() {
 
public boolean shouldOverrideUrlLoading(WebView view, String url) {
 
 view.loadUrl(url); return true;
 
 }
 
@Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
 
 if (url.startsWith("http") || url.startsWith("https")) {
 
 //http和https和谈开首的执行平常的流程 return super.shouldInterceptRequest(view, url);
 
} else {
 
//其余的URL则会开启一个Acitity而后去挪用原生APP Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); startActivity(in); return null;
 
 }
 
 }
 
 });
 
滑动监听
 
自定义webview重写onScrollChanged要领,行使接口回调
 
public class HzjrWebView extends WebView {
 
    private OnScrollChangedCallback mOnScrollChangedCallback;
 
    public HzjrWebView(Context context) {
 
        super(context);
 
    }
 
 
 
    public HzjrWebView(Context context, AttributeSet attrs) {
 
        super(context, attrs);
 
    }
 
 
 
    public HzjrWebView(Context context, AttributeSet attrs, int defStyleAttr) {
 
        super(context, attrs, defStyleAttr);
 
    }
 
 
 
    @Override
 
    protected void onScrollChanged(final int l, final int t, final int oldl,
 
                                   final int oldt) {
 
        super.onScrollChanged(l, t, oldl, oldt);
 
 
 
        if (mOnScrollChangedCallback != null) {
 
            mOnScrollChangedCallback.onScroll(l , oldl, t , oldt);
 
 
 
        }
 
    }
 
 
 
//    public OnScrollChangedCallback getOnScrollChangedCallback() {
 
//        return mOnScrollChangedCallback;
 
//    }
 
 
 
    public void setOnScrollChangedCallback(
 
            final OnScrollChangedCallback onScrollChangedCallback) {
 
        mOnScrollChangedCallback = onScrollChangedCallback;
 
    }
 
 
 
    /**
 
     * Impliment in the activity/fragment/view that you want to listen to the webview
 
     */
 
    public interface OnScrollChangedCallback {
 
         void onScroll(int l,int oldl,int t, int oldt);
 
    }
 
}
 
页面关闭以后,视频大概音频还在播放的题目
 
要领1:
 
挪用
 
 webView.loadUrl("about:blank");
 
这个要领会 销毁所有的video和audio 包含js的所有正在运转的function
 
要领2:
 
@Override
 
public void onPause() {
 
    super.onPause();
 
    myWebView.onPause();
 
    myWebView.pauseTimers();
 
}
 
 
 
@Override
 
public void onResume() {
 
    super.onResume();
 
    myWebView.resumeTimers();
 
    myWebView.onResume();
 
}
 
 
 
 
 
@Override
 
protected void onDestroy() {
 
    myWebView.destroy();
 
    myWebView = null;
 
    super.onDestroy();
 
}
 
 
 
复写性命周期的要领;非常好的要领;(偶然会挂 java.lang.IllegalArgumentException: Receiver not registered: android.widget.ZoomButtonsController$1@3ed4bcc7)
 
要在销毁以前把根结构的所有子结构remove
 
mLlH5.removeAllViews();
 
回退时回到上一个页面,而不是退出WebView
 
mWebView.goBack(); //后退
 
mWebView.goForward();//进步
 
mWebView.reload(); //革新
 
public class MainActivity extends Activity {
 
    private WebView webview;
 
 
 
    @Override
 
    public void onCreate(Bundle savedInstanceState) {
 
        super.onCreate(savedInstanceState);
 
        //2、在Activity中实例化WebView
 
        setContentView(R.layout.activity_main);
 
        webview = (WebView) findViewById(R.id.webview);
 
 
 
        //第2步也能够替代为下面这两句,就不要R.layout.activity_main结构文件了
 
        //mwebview = new WebView(this);                       //实例化WebView工具 
 
        //setContentView(mwebview);
 
 
 
        // 配置WebView属性,能够执行Javascript剧本
 
        webview.getSettings().setJavaScriptEnabled(true);
 
        //3、 加载必要显示的网页
 
        webview.loadUrl("http://www.baidu.com/");
 
        ///4、配置相应超链接,在安卓5.0体系,不应用下面语句超链接也是平常的,但在MIUI中安卓4.4.4中必要应用下面这条语句,才气相应超链接
 
        webview.setWebViewClient(new HelloWebViewClient());
 
    }
 
 
 
    @Override
 
    // 配置回退
 
    // 5、笼盖Activity类的onKeyDown(int keyCoder,KeyEvent event)要领
 
    public boolean onKeyDown(int keyCode, KeyEvent event) {
 
           //按下回笼键而且webview界面可以回笼
 
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
 
 
 
            webview.goBack(); // goBack()表示回笼WebView的上一页面
 
            return true;
 
        }
 
        return super.onKeyDown(keyCode,event);
 
    }
 
 
 
    // Web视图
 
    private class HelloWebViewClient extends WebViewClient {
 
        @Override
 
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
 
            view.loadUrl(url);
 
            return true;
 
        }
 
    }
 
}
 
配置cookie
 
ATTENTION:
 
    要在webView配置setting以后,loadUrl以前挪用此要领,否则失效
 
   
 
    对于配置cookie失效的题目,在5.0以下可能会有失效的环境,sync是异步操纵。
 
    失效的缘故是在removeSessionCookie以后立马setCookie可能会是配置以后又被清除了,可以加个延迟。
 
    在5.0以上官方回调了同步要领。
 
    具体先容参考博客:https://blog.csdn.net/b275518834/article/details/51004237
 
    /**
 
     * 给WebView同步Cookie
 
     *
 
     * @param context 高低文
 
     * @param url     可以应用[domain][host]
 
     */
 
    private void syncCookie(Context context, String url) {
 
        CookieSyncManager.createInstance(context);
 
        CookieManager cookieManager = CookieManager.getInstance();
 
        cookieManager.setAcceptCookie(true);
 
//        cookieManager.removeSessionCookie();// 移除旧的[可以不祥]
 
        cookieManager.setCookie(url,cookie);
 
        CookieSyncManager.getInstance().sync();// To get instant sync instead of waiting for the timer to trigger, the host can call this.
 
    }
 
 
 
另有权限:
 
<uses-permission android:name="android.permission.INTERNET" />
 
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
 
H5与Android交互
 
开始非常紧张非常轻易纰漏的网页权限
 
public class MainActivity extends AppCompatActivity {
 
 
 
/***************************************************************
 
 * H5和Android通讯三种体例
 
 * 1.android主动挪用js:javascript:要领名(参数)
 
 * 2.js主动挪用Android
 
 * 3.js callback式挪用Android,来源(解耦H5只关心H5,客户端只关心android)
 
 * ***************************************************************
 
 */
 
 
 
private WebView mWebview;
 
 
 
@Override
 
protected void onCreate(Bundle savedInstanceState) {
 
    super.onCreate(savedInstanceState);
 
    setContentView(R.layout.activity_main);
 
    initView();
 
 
 
    //配置webview
 
    WebSettings settings = mWebview.getSettings();
 
    settings.setJavaScriptEnabled(true);
 
 
 
    //页面加载实现挪用js要领
 
    //从新涉猎器内核工具
 
    initWebClient();
 
 
 
    //js和Android两种差别开发说话,不认识
 
    //焦点要领:配置js和Android通讯桥梁接口(简而言之,即是配置通讯桥梁类)
 
    JavascriptMethos jsMethos = new JavascriptMethos(this, mWebview);
 
    //参数1:提供给js挪用的要领的工具, 参数2:参数1的映射字符串(第一个参数的又名),因为字符串再所有开发同样通用
 
    mWebview.addJavascriptInterface(jsMethos, JavascriptMethos.JSINTERFACE);
 
 
 
    //显示
 
    mWebview.loadUrl("http:/10.0.3.2:8080/html35/index.html");
 
}
 
 
 
private void initWebClient() {
 
    mWebview.setWebChromeClient(new WebChromeClient());
 
 
 
 
 
    mWebview.setWebViewClient(new WebViewClient() {
 
        @Override
 
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
 
            super.onPageStarted(view, url, favicon);
 
        }
 
 
 
        //页面加载实现挪用该要领
 
        @Override
 
        public void onPageFinished(WebView view, String url) {
 
            super.onPageFinished(view, url);
 
            //挪用js 要领
 
            //WebView.loadUrl("javascript:要领名(参数)")
 
            JSONObject json = new JSONObject();
 
            try {
 
                json.put("name", "android");
 
                json.put("msg", "您好,我是Android,加个蚝友");
 
                mWebview.loadUrl("javascript:receiveMessage("+json.toString()+")");
 
            } catch (JSONException e) {
 
                e.printStackTrace();
 
            }
 
        }
 
    });
 
}
 
 
 
    private void initView() {
 
        mWebview = (WebView) findViewById(R.id.webview);
 
    }
 
}
 
 
 
 
 
 
 
/**
 
 * 同一经管所有js和Android通讯
 
 *
 
 */
 
 
 
public class JavascriptMethos {
 
 
 
    public static String JSINTERFACE = "jsInterface";
 
    private Context mContext;
 
    private WebView mWebView;
 
 
 
    public JavascriptMethos(Context mContext, WebView mWebView) {
 
        this.mContext = mContext;
 
        this.mWebView = mWebView;
 
}
 
 
 
/**
 
 * 给js挪用的弹出toast要领
 
 * 为何要增加注解:android4.2以上(包含),要是不加注解,
 
 * js无法挪用Android要领,因为4.2以前js和android通讯有安全题目,要是不加上该注解,4.2以上js无法挪用Android要领
 
 *
 
 * @param json
 
 */
 
@JavascriptInterface
 
public void showToast(String json) {
 
    Toast.makeText(mContext, json, Toast.LENGTH_SHORT).show();
 
}
 
 
 
@JavascriptInterface
 
public void getHotelData(String json) throws JSONException {
 
 
 
    //剖判callbak要领名
 
    JSONObject jsJson = new JSONObject(json);
 
    final String callback = jsJson.optString("callback");
 
 
 
    System.out.println("汲取到js传递callback参数=" + json);
 
    //模拟走访网页
 
    //回笼json
 
    final JSONObject callbackJson = new JSONObject();
 
    try {
 
        callbackJson.put("name", "8天连锁旅店");
 
        callbackJson.put("hotel", "99");
 
        callbackJson.put("phone", "075588888888");
 
 
 
        //挪用js要领
 
        //mWebView.loadUrl("javascript:要领名(参数)");默认Android挪用js自力运转在一个历程WebViewCoreThread
 
        mHandler.post(new Runnable() {
 
            @Override
 
            public void run() {
 
                //mWebView.loadUrl("javascript:receiveHotelData(" + callbackJson.toString() + ")");
 
                mWebView.loadUrl("javascript:"+callback+"(" + callbackJson.toString() + ")");
 
            }
 
        });
 
    } catch (JSONException e) {
 
        e.printStackTrace();
 
    }
 
}
 
 
 
    private Handler mHandler = new Handler();
 
}
 
demo
 
https://github.com/jiaweizeng/H5AndAndroid
 
control是java工具称号,toastMessage是要领称号,两边约定俗成,写死。
 
<body>
 
    <button type="button" id="button" onclick="toastMessage('js挪用了android要领')">js走访android中要领</button>
 
    <script>
 
        function toastMessage(message) {
 
            window.control.toastMessage(message)
 
        } 
 
    </script>
 
</body>
 
 
 
 
 
public class MainActivity extends AppCompatActivity {
 
 
 
    @SuppressLint({"JavascriptInterface", "AddJavascriptInterface", "SetJavaScriptEnabled"})
 
    @Override
 
    protected void onCreate(Bundle savedInstanceState) {
 
        super.onCreate(savedInstanceState);
 
        setContentView(R.layout.activity_main);
 
        WebView webView = findViewById(R.id.wv);
 
 
 
        WebSettings webSettings = webView.getSettings();
 
 
 
        webSettings.setJavaScriptEnabled(true);
 
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
 
        webView.loadUrl("http://192.168.1.38/hzjrH5/jiaohu.html");
 
        //js走访android,定义接口
 
        webView.addJavascriptInterface(this, "control");
 
    }
 
 
 
    @JavascriptInterface
 
    public void toastMessage(String s){
 
        Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
 
        finish();
 
    }
 
}
 

上篇:上一篇:Android WebView应用
下篇:下一篇:让你监控Android手机的notify栏