小猪的Android入门之路 Day 8 part 5

小猪的Android入门之路 Day 8 part 5

Android网络编程浅析——WebView浏览器编程初涉

——转载请注明出处:coder-pig



本节引言:



不知不觉Android网络编程浅析也快接近尾声了,在这part中我们学习了很多关于android

在网络方面的编程,现在我们来回顾一下吧!

part 1:xml文件的简单了解:以及android中解析xml文件的一些常用方式:sax,dom,pull解析xml

part 2:Android访问网络资源:HTML协议,获取图片,获取网页代码,解析服务器返回的xml数据,

          解析服务器返回的JSON数据

part 3:Android网络数据的下载:J2SE单线程下载文件,J2SE普通多线程下载文件

          Android多线程断点下载

part 4:Android网络数据的上传:GET或POST方式上传数据;开源框架HttpClient上传数据;

          发送xml数据给服务;通过Http协议上传文件;WebService平台的了解以及简单应用

而在Part 5中为大家讲解的是Android中提供的一个组件:WebView(网络视图)的讲解,相比起前面

的内容来说,就容易很多了,那么,就跟随笔者的脚步来学习WebView的使用吧!



本节学习路线图:

笔者要上课,上完回去发哈





正文:

什么是WebView?




怎么用WebView?


①直接在Activity中调用WebView:



详细代码如下:

package com.jay.example.webviewdemo1;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class MainActivity extends Activity {

	private WebView wView;
	
	@SuppressLint("SetJavaScriptEnabled")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);    
        wView = new WebView(this); 					//①实例化WebView对象  
		wView.setWebViewClient(new WebViewClient()  //②设置在webView点击打开的新网页在当前界面显示,而不跳转到新的浏览器中
		{
			@Override
			public boolean shouldOverrideUrlLoading(WebView view, String url) {
				view.loadUrl(url);
				return true;
			}
		});
		
		wView.getSettings().setJavaScriptEnabled(true);  //③设置WebView属性,运行执行js脚本
		wView.loadUrl("http://www.baidu.com/");          //④调用loadView方法为WebView加入链接
		setContentView(wView);                           //⑤调用Activity提供的setContentView将webView显示出来
	}

	//⑥另外还需要重写回退按钮的方法,不然,当我们在WebView中点击多个页面后,一按回退就退出程序了的
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if ((keyCode == KeyEvent.KEYCODE_BACK) && wView.canGoBack()) {  
            wView.goBack(); //goBack()表示返回WebView的上一页面  
            return true;  
        }  
        return false; 
	}
}

效果图:






②在布局代码中设置WebView


这个其实和在Activity中直接设置的差别不大,代码都差不多;

另外在第一个代码中并没有深入的对回退按钮的点击事件只是

设置了webView的回退,相信细心的读者已经发现,这个程序无论你怎么

按都是退出不了程序的,哈哈!所以在demo2中给出处理方案;

当webView不能再回退,再设置点击两次后退出app,详情见代码


布局代码:activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.jay.example.webviewdemo2.MainActivity" >

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/editurl"
        android:hint="请输入要访问的Url"
        />
	<Button 
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:id="@+id/btnload"    
	    android:text="浏览"
	/>
	
	<WebView 
	  android:layout_width="match_parent"
	  android:layout_height="match_parent"
	  android:id="@+id/webview"  
	/>
	
</LinearLayout>


MainActivity.java

package com.jay.example.webviewdemo2;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;


public class MainActivity extends Activity {

	private EditText editurl;
	private Button btnload;
	private WebView webView;
	private String strurl;
	//定义一个用来存储点击退出按钮时间的便利
	private long exitTime = 0;
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		editurl = (EditText) findViewById(R.id.editurl);
		btnload = (Button) findViewById(R.id.btnload);
		webView = (WebView) findViewById(R.id.webview);
		
		//设置WebView属性,能够执行Javascript脚本  
        webView.getSettings().setJavaScriptEnabled(true);
        //设置Web视图
        webView.setWebViewClient(new MyWebViewClient());
        
        btnload.setOnClickListener(new OnClickListener() {			
			@Override
			public void onClick(View v) {
				strurl = editurl.getText().toString();
				//如果用户输入的url不带有http://是找不到网页的哦!
				if(!strurl.startsWith("http://"))
				{
					strurl = "http://" + strurl;
				}
				webView.loadUrl(strurl);
			}
		});
	}
	
	
	//当我们在webView上打开多个网页后,我们会习惯性地按回退键
	//这个时候我们需要重写回退键按钮,当点击后调用的是WebView的goBack方法
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if(keyCode == KeyEvent.KEYCODE_BACK)
		{
			if(System.currentTimeMillis() - exitTime > 2000)
			{
				
				if(webView.canGoBack())
				{
					webView.goBack();					
				}
				else 
				{
					Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
					exitTime = System.currentTimeMillis();
				}
			}
			else 
			{
				System.exit(0);
			}
		}
		
		return false;
	}
	
	//Web视图,继承WebViewClient,重写shouldOverrideUrlLoading方法
	//这样做的话可以避免我们点击了WebView中某个链接,继续在该WebView窗口上打开网页
	//而不是开启手机自身的broswer来打开链接
	class MyWebViewClient extends WebViewClient
	{
		@Override
		public boolean shouldOverrideUrlLoading(WebView view, String url) {
			view.loadUrl(url);
			return true;
		}
	}	
}

效果图:






WebView常用的相关方法:


WebView常用方法:

getSettings()
返回一个WebSettings对象,用来控制WebView的属性设置
loadUrl(String url)
加载指定的Url
loadData(String data,String mimeType,String encoding)
 加载指定的Data到WebView中.使用"data:"作为标记头,
改方法不能加载网络数据.其中mimeType为数据类型如:textml,image/jpeg. 
encoding为字符的编码方式 
setWebViewClient(WebViewClient client)
为WebView指定一个WebViewClient对象.WebViewClient可
以辅助WebView处理各种通知,请求等事件。
setWebChromeClient(WebChromeClient client)
为WebView指定一个WebChromeClient对象,WebChromeClient专门用来辅助WebView处理js的对话框,网站title,网站图标,加载进度条等









WebSettings的常用方法:

setJavaScriptEnabled(boolean flag)
设置是否支持JavaScript
setDefaultFontSize(int size)
设置默认的字体大小
setDefaultTextEncodingName(String encoding)
设置默认字符的编码方式
setAllowFileAccess(boolean allow):
设置是否允许访问文件数据
setDatabaseEnabled(boolean flag)
设置是否可以使用数据库相关的api
setDatabasePath(String databasePath) 若使用数据库API,该方法指定数据库文件的路径
setBlockNetworkImage(boolean flag) 设置是否禁止显示图片,true表示禁止图片
setSavePassword(boolean save) 设置是否保存密码
setTextize(WebSetting.TextSize) 设置页面文字大小
setSupportZoom(bollean support) 设置是否支持变焦












WebViewClient的常用方法


onPageStared(WebView view,String url) 通知主程序网页开始加载
onPageFinished(WebView view,String url,Bitmap favicon)
通知主程序,网页加载完毕
doUpdateVisitedHistory(WebView view,String url,boolean isReload)
更新历史记录
onLoadResource(WebView view,String url)
通知主程序WebView即将加载指定url的资源
onScaleChanged(WebView view,float oldScale,float newScale)
ViewView的缩放发生改变时调用
shouldOverrideKeyEvent(WebView view,KeyEvent event) 控制webView是否处理按键时间,如果返回true
则WebView不处理,返回false则处理
shouldOverrideUrlLoading(WebView view,String url) 控制对新加载的Url的处理,返回true,说明主程序处理
WebView不做处理,返回false意味着WebView会
对其进行处理
onReceivedError(WebView view,int errorCode,String description,
String failingUrl)
遇到不可恢复的错误信息时调用














WebChromeClient的常用方法


onJsAlert(WebView view,String url,String message,JsResult result) 处理Js中的Alert对话框  
onJsConfirm(WebView view,String url,String message,JsResult result)
处理Js中的Confirm对话框
onJsPrompt(WebView view,String url,String message
String defaultValue,,JsPromptResult result)

处理Js中的Prompt对话框
onProgressChanged(WebView view,int newProgress)
当加载进度条发生改变时调用











使用WebView中的js调用Android方法:


在开始讲解这里之前,相信大家都知道webView是一个类似于浏览器的组件了,他就是用来加载网页的;

但是它真的只有加载网页那么简单么?答案肯定是否定的;首先大家都知道HTML是拿来做静态网站的吧

但是Android的界面开发可以采用HTML网页技术,相比起我们用Layout技术慢慢布局显得更加方便,快捷

当然,屏幕适配是需要解决的问题;另外在我们的HTML中需要获取Android设备的相关信息时,比如获取设备

所在的经纬度(定位),或者读取联系人,打电话,发送信息等的!而实现互访的原理如下:

html——js——java,就是说以js为媒介,只需要传递JSon类型的数据即可!


注意:为了节省篇幅.以下代码使用的html文件都是放到assets目录下的,访问时

直接用loadUrl("file:///android_asset/~")即可



代码示例:

①html通过js显示Toast与普通列表的对话框

效果图:



核心代码:

自定义一个Object对象,js通过该类暴露的方法来调用Android

MyObject.java:

package com.jay.example.webviewdemo3;

import android.app.AlertDialog;
import android.content.Context;
import android.widget.Toast;

public class MyObject {
	Context context;
	public MyObject(Context context) {
		this.context = context;
	}
	
	//将显示Toast和对话框的方法暴露给JS脚本调用
	public void showToast(String name)
	{
		Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
	}
	public void showDialog()
	{
		new AlertDialog.Builder(context)
		.setTitle("联系人列表").setIcon(R.drawable.ic_launcher)
		.setItems(new String[]{"小王","小坏","小猪","小狗","小猫"}, null)
		.setPositiveButton("确定", null).create().show();
	}
}

创建一个html文件,内容如下,接着把它放到工程的assets目录下:

my.html

<!DOCTYPE html>
<html>
  <head>
    <title>Js调用Android</title>
  </head>
  
  <body>
    <input type="button" value="Toast提示" onclick="myObj.showToast('逗比');"/>
    <input type="button" value="列表对话框" onclick="myObj.showDialog();"/>
  </body>
</html>

在MainActivity中完成WebView的初始化,设置运行调用js,最后通过addJavascriptIntefcae()将

对象暴露给Js,js就可以通过该对象操作与Android相关的操作了

package com.jay.example.webviewdemo3;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;


public class MainActivity extends Activity {

	private WebView webView;
	
	
	@SuppressLint("JavascriptInterface")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		webView = (WebView) findViewById(R.id.webView);
		webView.loadUrl("file:///android_asset/my.html");
		WebSettings webSettings = webView.getSettings();
		//①设置WebView允许调用js
		webSettings.setJavaScriptEnabled(true);
		webSettings.setDefaultTextEncodingName("UTF-8");
		//②将object对象暴露给Js,调用addjavascriptInterface
		webView.addJavascriptInterface(new MyObject(MainActivity.this), "myObj");
	}
}
ps:上述代码在4.2及以上的虚拟机上都是运行后都是没有点击效果的,

笔者也不知道为什么,但是在真机上都是可以的!




②HTML通过js调用三种不同的对话框

效果图:


核心代码:


创建一个html文件,然后把它放到工程的assets目录下:

my.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

  <head>
	<meta http-equiv = "Content-Type" content="text/html;charset=UTF-8"
    <title>测试Js的三种不同对话框</title>
    <script language="JavaScript">
    	function alertFun()
    	{
    		alert("Alert警告对话框!");
    	}
    	function confirmFun()
    	{
    		if(confirm("访问百度?"))
			{location.href = "http://www.baidu.com";}
    		else alert("取消访问!");
    	}
    	function promptFun()
    	{
    		var word = prompt("Prompt对话框","请输入点什么...:");
    		if(word)
    		{
    			alert("你输入了:"+word)
    		}else{alert("呵呵,你什么都没写!");}
    	}
    </script> 
  </head>
  
  <body>
    <p>三种对话框的使用</p>
    
    <p>Alert对话框</p>
    <p>
    	<input type="submit" name = "Submit1" value="展示1" onclick="alertFun()"/>
    </p>
    <p>Confirm对话框</p>
    <p>
    	<input type="submit" name = "Submit2" value="展示2" onclick="confirmFun()"/>
    </p>
    <p>Prompt对话框</p>
    <p>
    	<input type="submit" name = "Submit3" value="展示3" onclick="promptFun()"/>
    </p>
  </body>
</html>

接着一次创建主布局与prompt的布局

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.jay.example.webviewdemo4.MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="请输入要访问的Url的地址" />
	<EditText 
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    android:id="@+id/editurl"
	    android:text="file:///android_asset/my.html"
	/>
	<Button
	    android:id="@+id/btnload"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="加载网页" />
	<WebView 
		android:layout_width="match_parent"
		android:layout_height="match_parent"
		android:id="@+id/webview"    
	/>
	
	
</LinearLayout>
prompt_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
	<TextView 
		android:id="@+id/text"
		android:layout_width="match_parent"
		android:layout_height="wrap_content"    
	/>
	<EditText 
		android:id="@+id/edit"
		android:layout_width="match_parent"
		android:layout_height="wrap_content"
		android:selectAllOnFocus="true"
		android:scrollHorizontally="true"    
	/>
    
</LinearLayout>


最后编写我们的MainActivity即可,设置webView相关属性以及重写WebChromeClient的

三种不同的对话框的方法即可

package com.jay.example.webviewdemo4;

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;


public class MainActivity extends Activity {

	private EditText editurl;
	private Button btnload;
	private WebView webView;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		editurl = (EditText) findViewById(R.id.editurl);
		btnload = (Button) findViewById(R.id.btnload);
		webView = (WebView) findViewById(R.id.webview);
		
		//获得WebSetting对象,支持js脚本,可访问文件,支持缩放,以及编码方式
		WebSettings webSettings = webView.getSettings();
		webSettings.setJavaScriptEnabled(true);
		webSettings.setAllowFileAccess(true);
		webSettings.setBuiltInZoomControls(true);
		webSettings.setDefaultTextEncodingName("UTF-8");
		//设置WebChromeClient,处理网页中的各种js事件
		webView.setWebChromeClient(new MyWebChromeClient());
		btnload.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				String url = editurl.getText().toString();
				webView.loadUrl(url);
				
			}
		});
	}
	
	
	//这里需要自定义一个类实现WebChromeClient类,并重写三种不同对话框的处理方法
	//分别重写onJsAlert,onJsConfirm,onJsPrompt方法
	class MyWebChromeClient extends WebChromeClient
	{
		@Override
		public boolean onJsAlert(WebView view, String url, String message,
				final JsResult result) {
			//创建一个Builder来显示网页中的对话框
			new Builder(MainActivity.this).setTitle("Alert对话框").setMessage(message)
			.setPositiveButton("确定",new OnClickListener() {				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					result.confirm();					
				}
			}).setCancelable(false).show();
			return true;
		}
		
		
		@Override
		public boolean onJsConfirm(WebView view, String url, String message,
				final JsResult result) {
			new Builder(MainActivity.this).setTitle("Confirm对话框").setMessage(message)
			.setPositiveButton("确定", new OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					result.confirm();					
				}
			})
			.setNegativeButton("取消", new OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					result.cancel();					
				}
			}).setCancelable(false).show();
			return true;
		}
		
		@Override
		public boolean onJsPrompt(WebView view, String url, String message,
				String defaultValue, final JsPromptResult result) {
			//①获得一个LayoutInflater对象factory,加载指定布局成相应对象
			final LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
			final View myview = inflater.inflate(R.layout.prompt_view, null);
			//设置TextView对应网页中的提示信息,edit设置来自于网页的默认文字
			((TextView) myview.findViewById(R.id.text)).setText(message);
			((EditText) myview.findViewById(R.id.edit)).setText(defaultValue);
			//定义对话框上的确定按钮
			new Builder(MainActivity.this).setTitle("Prompt对话框").setView(myview)
			.setPositiveButton("确定", new OnClickListener() {				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					//单机确定后取得输入的值,传给网页处理
					String value = ((EditText)myview.findViewById(R.id.edit)).getText().toString();
					result.confirm(value);					
				}
			})
			.setNegativeButton("取消", new OnClickListener() {				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					result.cancel();				
				}
			}).show();			
			return true;
		}
		
		
		
	}
	
}


③HTML通过js读取Android联系人并显示:

该代码实现的是通过js读取Android手机中联系列表,然后显示到HTML中

当我们点击某个电话号码时,会直接跳转到拨号页面

效果图:




首先是创建我们的HTML文件,这里可能有部分对JS不熟悉的朋友,笔者也是如此,因为JS的问题,笔者卡了

一晚上都没找到错误!后来才发现自己的Js写错了,这里有兴趣的可以研究下流程,不会的就直接复制可以了

通常HTML都是有人编写的,我们要做的只是WebView上的开发,以及定义用于JS传递数据相关的对象即可!

下述代码的简单原理是:利用onload()在网页加载的时候加载相应的js脚本,而js脚本中定义的一个函数是

取出传递过来的对象,获取里面的数据,通过for循环以单元行的形式打印出来!


my.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>显示获取的联系人列表</title>
    <script language="JavaScript">	
		function show(jsondata)
		{
			//将传递过来的Json转换为对象
			var jsonobjs = eval(jsondata);
			//获取下面定义的表格
			var table = document.getElementById("PersonTable");
			//遍历上面创建的Json对象,将每个对象添加为
			//表格中的一行,而它的每个属性作为一列
			for(var i = 0;i < jsonobjs.length;i++)
			{
				//添加一行,三个单元格:
				var tr = table.insertRow(table.rows.length);
				var td1 = tr.insertCell(0);
				var td2 = tr.insertCell(1);
				td2.align = "center";
				var td3 = tr.insertCell(2);
				//设置单元格的内容和属性
				//其中innerHTML为设置或者获取位于对象起始和结束标签内的HTML
				//jsonobjs[i]为对象数组中的第i个对象
				td1.innerHTML = jsonobjs[i].id;
				td2.innerHTML = jsonobjs[i].name;
				//为现实的内容添加超链接,超链接会调用Java代码中的
				//call方法并且把内容作为参数传递过去
				td3.innerHTML = "<a href = 'javascript:sharp.call(\""+jsonobjs[i].phone + "\")'>"
				+jsonobjs[i].phone + "</a>";;
			}
		}
	</script>	
</head>


<!-- onload指定该页面被加载时调用的方法,这里调用的是Java代码中的contactlist方法-->
<body style="margin:0px; background-color:#FFFFFF; color:#000000;" onload = "javascript:sharp.contactlist()">
	<!--定义一个表格-->
	<table border = "0" width = "100%" id = "PersonTable" cellspacing = "0">
	<tr>
		<td width = "15%">用户id</td>
		<td align = "center">姓名</td>
		<td width = "15%">号码</td>
	</tr>
	</table>	
</body>
</html>





定义一个业务bean类:

contact.java

package com.jay.example.webviewdemo5;

public class Contact {
	private Integer id;
	private String name;
	private String phone;
	
	public Contact(){}
	
	public Contact(Integer id, String name, String phone) {
		super();
		this.id = id;
		this.name = name;
		this.phone = phone;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}
	
	
	
	
}


最后是MainActivity.java文件,这里为了节省篇幅,把获取联系人的方法也定义

在了该类中,实际开发中不要这样做!!!

package com.jay.example.webviewdemo5;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.webkit.WebView;

public class MainActivity extends Activity {

	private WebView webView;
	
	
	@SuppressLint("JavascriptInterface")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		webView = (WebView) findViewById(R.id.webview);
		
		//设置WebView的相关设置,依次是:
		//支持js,不保存表单,不保存密码,不支持缩放
		//同时绑定Java对象
		webView.getSettings().setJavaScriptEnabled(true);
		webView.getSettings().setSaveFormData(false);
		webView.getSettings().setSavePassword(false);
		webView.getSettings().setSupportZoom(false);
		webView.getSettings().setDefaultTextEncodingName("UTF-8");
		webView.addJavascriptInterface(new SharpJS(), "sharp");
		webView.loadUrl("file:///android_asset/my.html");
		System.out.println("webView相关参数设置");
				
	}
	
	//自定义一个Js的业务类,传递给JS的对象就是这个,调用时直接javascript:sharp.contactlist()
	public class SharpJS
	{
		public void contactlist()
		{
			try
			{
				System.out.println("contactlist()方法执行了!");
				String json = buildJson(getContacts());
				webView.loadUrl("javascript:show('"+json+"')");
			}catch(Exception e){System.out.println("设置数据失败" + e);}
		}
		
		public void call(String phone)
		{
			System.out.println("call()方法执行了!");
			Intent it = new Intent(Intent.ACTION_CALL,Uri.parse("tel:"+phone));
			startActivity(it);
		}
	}
	
	
	
	
	
	//将获取到的联系人集合写入到JsonObject对象中,再添加到JsonArray数组中
	public String buildJson(List<Contact> contacts)throws Exception
	{
		JSONArray array = new JSONArray();
		for(Contact contact:contacts)
		{
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("id", contact.getId());
			jsonObject.put("name", contact.getName());
			jsonObject.put("phone", contact.getPhone());
			array.put(jsonObject);
		}
		return array.toString();
	}
	
	
	
	//定义一个获取联系人的方法,返回的是List<Contact>的数据
	public List<Contact> getContacts()  
    {  
		System.out.println("getContacts方法执行了");
        List<Contact> Contacts = new ArrayList<Contact>();  
        ContentResolver cr = getApplicationContext().getContentResolver();  
        Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI,null, null, null, null);  
        while(cursor.moveToNext()){  
            Contact Contact = new Contact();  
            //获取联系人id  
            String contatId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));  
            Contact.setId(Integer.parseInt(contatId));  
            //获取联系人姓名  
            String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));  
            Contact.setName(name);  
            //因为一个联系人的电话号码可能有几个,但我们这里仅仅是获取一个就够了,所以就不循环遍历了  
            Cursor phones = getApplicationContext().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,  
                    null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+contatId, null, null);  
            phones.moveToFirst();  
            String num = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));  
            Contact.setPhone(num);  
            Contacts.add(Contact);  
            phones.close();  
        }  
        cursor.close();
        for(Contact ct:Contacts)
        {
        	System.out.println(ct.getId() + "*" + ct.getName() + "*" + ct.getPhone());
        }
        return Contacts;  
    }  
	
	
}



本节小结:

1.对WebViwe进行简单了解,在Activity中调用WebView中的两种方式

2.WebView的相关方法:①WebView②WebSetting③WebViewClient④WebChromeClient

3.Html通过WebView的js调用Android中的方法流程总结:

①webView.getSettings().setJavaScriptEnabled(true);  设置启动JS调用功能

②webView.addJavascriptInterface(new SharpJS(), "sharp");   将object对象暴露给JS,

③JS可以根据sharp操作SharpJS对象中的参数与方法



另外,上述demo可能需要加入以下权限,自己看情况添加:

<uses-permission android:name="android.permission.INTERNET"/>     //联网

<uses-permission android:name="android.permission.CALL_PHONE"/>        //打电话

<uses-permission android:name="android.permission.READ_CONTACTS"/>    //读取联系人





相关代码下载:

笔者要上课,回去再上传

1)直接在Activity中使用WebView:

2)在布局中设置静态WebView

3)HTML通过js弹出Toast和列表对话框

4)HTML通过js弹出三种不同对话框:

5)HTML通过WebView的js读取Android联系人并显示:WebViewDemo5.zip












郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。