package com.example.webclient; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.KeyEvent; import android.view.Menu; import android.view.View; import android.view.View.OnKeyListener; import android.view.ViewGroup; import android.webkit.DownloadListener; import android.webkit.HttpAuthHandler; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.RelativeLayout; import android.widget.Toast; /** * webview知识 * http://blog.csdn.net/chenshijun0101/article/details/7045394 * http://blog.csdn.net/kingsollyu/article/details/6656865(与JS进行交互) * @author chenxiaojian * */ public class MainActivity extends Activity { private WebView mWebView ; private Handler mHandler = new Handler(); private static final String TAG = MainActivity.class.getName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initView(); } @SuppressLint("JavascriptInterface") private void initView(){ mWebView = new WebView(this); mWebView.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); setContentView(mWebView); mWebView.requestFocus();//获取焦点 WebSettings webSettings = mWebView.getSettings(); mWebView.setVerticalScrollBarEnabled(false); mWebView.setHorizontalScrollBarEnabled(false); //如果访问的页面中有Javascript,则webview必须设置支持Javascript。 webSettings.setJavaScriptEnabled(true); //使用localStorage则必须打开 这个主要是用在html5中的本地存储。 webSettings.setDomStorageEnabled(true); webSettings.setSaveFormData(false); //Webview与js的双向交互才是android的webview强大所在(因为安全问题在API17之后以取消) ,可以暂不关心 mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "chen"); // 如果希望点击链接由自己处理,而不是新开Android的系统browser中响应该链接。 // 给WebView添加一个事件监听对象(WebViewClient)并重写其中的一些方法: // shouldOverrideUrlLoading:对网页中超链接按钮的响应。当按下某个连接时WebViewClient会调用这个方法, // 并传递参数:按下的url。比如当webview内嵌网页的某个数字被点击时,它会自动认为这是一个电话请求, // 会传递url:tel:123,如果你不希望如此可通过重写shouldOverrideUrlLoading函数解决: //也就是说如果我们没有重写shouldOverrideUrlLoading会弹出一个系统浏览器,多么扯淡。 // @Override // public boolean shouldOverrideUrlLoading(WebView view, String url) { // mWebView.loadUrl(url); // return true; // } mWebView.setWebViewClient(new MyWebClient()); mWebView.setWebChromeClient(new MyWebChromeClient()); mWebView.setDownloadListener(new WebViewDownloadListener()); // 设置WevView要显示的网页: // 互联网用:webView.loadUrl("http://www.google.com"); // 本地文件用:webView.loadUrl("file:///android_asset/XX.html"); 本地文件存放在:assets文件中 mWebView.loadUrl("http://m.appchina.com");//internet权限没有加问题导致404 // 如果用webview点链接看了很多页以后,如果不做任何处理,点击系统“Back”键, // 整个浏览器会调用finish()而结束自身,如果希望浏览的网页回退而不是退出浏览器,需要在当前Activity中处理并消费掉该Back事件。 // 覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法。 mWebView.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && mWebView != null && mWebView.canGoBack()) { mWebView.goBack(); return true;//return true表示这个事件已经被消费,不会再向上传播 } return false; } }); } /** * WebClient和WebChromeClient的区别? * onLoadResource onPageStart onPageFinish onReceiveError onReceivedHttpAuthRequest WebChromeClient是辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等 onCloseWindow(关闭WebView) onCreateWindow() onJsAlert (WebView上alert是弹不出来东西的,需要定制你的WebChromeClient处理弹出) onJsPrompt onJsConfirm onProgressChanged onReceivedIcon onReceivedTitle * @author chenxiaojian * */ final class MyWebClient extends WebViewClient{ public MyWebClient() { } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { //这个方法是必须要重写的,如果不重写就是会调用系统浏览器自己处理了 Log.v(TAG, "shouldOverrideUrlLoading "+url); view.loadUrl(url); return true; } /** * 这个事件就是开始载入页面调用的,通常我们可以在这设定一个loading的页面,告诉用户程序在等待网络响应。 */ @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { Log.i(TAG, "onPageStarted "+url); //这个主要是先不让图片加载,似乎可以达到快速的目的。 //但是在有的网页里面不可以详见:http://hi.baidu.com/goldchocobo/item/9f7b0639f3cd2efe96f88dfb view.getSettings().setBlockNetworkImage(true); super.onPageStarted(view, url, favicon); } /** * 同样道理,我们知道一个页面载入完成,于是我们可以关闭loading条,切换程序动作。 */ @Override public void onPageFinished(WebView view, String url) { Log.i(TAG, "onPageFinished "+url); view.getSettings().setBlockNetworkImage(false); super.onPageFinished(view, url); } @Override public void onLoadResource(WebView view, String url) { Log.i(TAG, "onLoadResource "+url); super.onLoadResource(view, url); } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); Log.e(TAG, "onReceivedError errorCode:"+errorCode+" description"+description+" failingUrl"+failingUrl); // finish(); } /** * 接收到Http请求的事件 */ @Override public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) { super.onReceivedHttpAuthRequest(view, handler, host, realm); } } final class DemoJavaScriptInterface{ public DemoJavaScriptInterface() { } /** * 里面的方面必须到UI线程中去调用,所以要post一下。 * 这个在html里面的js里面的方面名是window.chen.clickOnAndroid() */ public void clickOnAndroid(){ mHandler.post(new Runnable() { @Override public void run() { // 此处调用 HTML 中的javaScript 函数 mWebView.loadUrl("javascript:wave()"); } }); } } final class MyWebChromeClient extends WebChromeClient{ public MyWebChromeClient() { } @Override public void onProgressChanged(WebView view,final int newProgress) { super.onProgressChanged(view, newProgress); mHandler.post(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "加载进度 "+newProgress,Toast.LENGTH_SHORT).show(); } }); } @Override public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); Log.e(TAG, "标题Title "+title); } @Override public void onReceivedIcon(WebView view, Bitmap icon) { super.onReceivedIcon(view, icon); } } final class WebViewDownloadListener implements DownloadListener{ @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { //这个只是暂时调用系统的,可以做一个自己的下载器。 Uri uri = Uri.parse(url); Intent intent = new Intent(Intent.ACTION_VIEW,uri); startActivity(intent); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } }
http://download.csdn.net/detail/dacainiao007/7000097 回调
http://download.csdn.net/detail/dacainiao007/7035373 (本文源码)