摘要:[Android] WebView 傳值給 HTML
目的
透過 WebView 將參數傳送給 HTML。
方法
- WebView 載入 HTML l時,呼叫在 HTML 上 JavaScript 函數。
- WebView 設定 JavaScript 介面,並 HTML 上呼叫 Java 函數。=====> 本文的方法,原因是此方法比較符合資訊安全。
實作
輸入經緯度跳出 Goole Map 地圖。
畫面如下
程式結構
XML(activity_main.xml)
主頁面包含二個 TextView、二個 EditView 與一個 Button。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textViewLat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="31dp"
android:layout_marginTop="90dp"
android:text="緯度"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/textViewLon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="31dp"
android:layout_marginTop="140dp"
android:text="經度"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="@+id/editTextLat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="90dp"
android:layout_marginTop="90dp" >
</EditText>
<EditText
android:id="@+id/editTextLon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="90dp"
android:layout_marginTop="140dp" >
</EditText>
<Button
android:id="@+id/buttonmap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/editTextLon"
android:layout_centerVertical="true"
android:text="Google Map" />
</RelativeLayout>
XML(map.xml)
跳出頁面的套版包含一個 WebView (用來載入網頁)與一個 ImageView (用來結束畫面的X)。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="300dp"
android:orientation="vertical" >
<WebView
android:id="@+id/webviewmap"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_margin="@dimen/activity_horizontal_margin" />
<ImageView
android:id="@+id/imageviemap"
android:layout_width="70dp"
android:layout_height="70dp"
android:src="@drawable/cancel" />
</RelativeLayout>
HTML(map.html)
給WebView載入的 HTML 檔。
- 第6行 為 Google Map API載入。
- 第9~30行 為載入 Google Map的函數。
- 第11~12行 先賣個關子,後頭會解釋。
- 第17行 zoom 是 Google Map 的縮放等級,值愈大地圖會愈細。
-
第18行 mapTypeId 是 Google Map 的地圖類型。
- ROADMAP 顯示 Google 地圖的正常、預設 2D 地圖方塊。
- SATELLITE 可顯示攝影地圖方塊。
- HYBRID 可顯示混合攝影地圖方塊與重要地圖項 (道路、城市名稱) 的地圖方塊圖層。
- TERRAIN 可顯示實際起伏的地圖方塊,以呈現海拔高度和水域圖徵 (山嶽、河流等)。
- 第19行 center 是地圖中心位置。
- 第28行 地圖上註記的文字說明。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Google Maps</title>
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&v=3.9"></script>
<script>
function initialize()
{
var lat = AndroidFunction.GetLat();
var lon = AndroidFunction.GetLon();
var latlon = new google.maps.LatLng(lat,lon);
var mapOptions =
{
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: latlon
};
map = new google.maps.Map(document.getElementById('map'),mapOptions);
var marker = new google.maps.Marker(
{
position: latlon,
map: map,
});
var infowindow = new google.maps.InfoWindow();
infowindow.setContent("<p>No 1105 到此一遊</p>");
infowindow.open(map, marker);
}
</script>
</head>
<body onload="initialize()">
<div id="map" style="width: device-width; height: 300px;"></div>
</body>
</html>
MainActivity.java
- 第29~30行 為設定按下 Google Map 按鈕的事件。
- 第61~65行 為擷取輸入的經緯度。
- 第69~72行 為彈出視窗套上 map.xml 的格式。
- 第74~75行 為設定按下X按鈕的事件。
- 第77行 為 map.html 的位置。
- 第80行 為可以使用 Javascript。
- 第81行 為本文的重點,從字面上的翻譯是說建立一個 Javascript 的介面,意思是說在 HTML 裡面的 Javascript 可以呼叫 Java 本身的函數, 還記的 map.html 的第11~12行,那奇怪的東西嗎,那部份就是呼叫40~44行與46~50行的 GetLat 與 GetLon 來取得經緯度,我這邊是直接設定成原 Class 且給定期名字(本文設定:AndroidFunction),當然也可以其他的 Class,只是有一點要注意,那就是 GetLat 與 GetLon 上面都有一行標記@JavascriptInterface,這部份有 聽說是 Android4.2.2 以後才要加,但這點我不是很肯定,但因為我是用 Android4.2.2,所以沒加真的不會出來,其他版本就請大大自己試試看嚕,呼叫時前面要加你設定介面的名字+函數的名稱。
- 第82行 為 WebView 載入 map.html。
- 第83行 為彈出視窗。
- 第83行 為關閉視窗。
package com.example.webviewdamo;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
public class MainActivity extends Activity
{
private String Lat;
private String Lon;
private AlertDialog alerdialog;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button MapButton = (Button) findViewById(R.id.buttonmap);
MapButton.setOnClickListener(Click);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@JavascriptInterface
public String GetLat()
{
return Lat;
}
@JavascriptInterface
public String GetLon()
{
return Lon;
}
private View.OnClickListener Click= new View.OnClickListener ()
{
@Override
public void onClick(View view)
{
switch(view.getId())
{
case R.id.buttonmap:
EditText latedittext = (EditText) findViewById(R.id.editTextLat);
EditText lonedittext = (EditText) findViewById(R.id.editTextLon);
Lat = latedittext.getText().toString();
Lon = lonedittext.getText().toString();
if (Lat != null && Lon != null)
{
Builder builder = new AlertDialog.Builder(MainActivity.this);
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
View mapview = inflater.inflate(R.layout.map,null);
builder.setView(mapview);
ImageView imageview = (ImageView)mapview.findViewById(R.id.imageviemap);
imageview.setOnClickListener(Click);
String mapurl = "file:///android_asset/map.html";
WebView webview = (WebView) mapview.findViewById(R.id.webviewmap);
webview.getSettings().setJavaScriptEnabled(true);
webview.addJavascriptInterface(MainActivity.this , "AndroidFunction");
webview.loadUrl(mapurl);
alerdialog = builder.show();
}
break;
case R.id.imageviemap:
alerdialog.cancel();
break;
}
}
};
}
AndroidManifest.xml(需要增加==>才可以上網)
<uses-permission android:name="android.permission.INTERNET" />
結果
我輸入了我大學的母校東吳大學,經度:121.5457,緯度:25.0944。
以上有任何問題與錯誤,歡迎各位指教,謝謝。