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.youkuaiyun.com/chenshijun0101/article/details/7045394
* http://blog.youkuaiyun.com/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.youkuaiyun.com/detail/dacainiao007/7000097 回调
http://download.youkuaiyun.com/detail/dacainiao007/7035373 (本文源码)