[Android] Android 學習筆記:使用 WebView 看 assets 中的網頁檔
想要把自己寫的圖書館多重帳戶登入這個 chrome extension,
移植到 Android 手機上已經很久了,不過一直沒有實現(因為不會寫 Android 程式)~
自從前幾個月開始摸一點點 Android programming 之後,又開始打算做出這個 app,
不過因為還蠻不熟的,連如何將 chrome extension 中的那些 js/html/css 檔案包到 android apk 裡面也不知道,
因此一下子就卡關了 =_=…
參加了公司的 Android programming 讀書會後,發現有 asset 這個東西,
可以將任意的檔案附加進 apk 裡面,再加上 WebView 就可以去顯示網頁檔案,
這樣基本上就可以讓 chrome extension 在 Android 上執行了~
以下簡單介紹要如何完成這件事情~
1. 首先將要放入 apk 的檔案與目錄都複製到專案的 assets 目錄下~
舉例來說,我想要把圖書館多重帳戶登入的整個目錄放進去,
所以我就把 NewTaipeiCityLibraryMultiLogin 整個目錄複製進 assets 之中~
2. 在 Activity 中加入一個 WebView 的物件~
你可以取得這 WebView 物件的 WebSettings,
來設定這個物件的一些屬性,像是是否允許執行 JavaScript、是否允許 HTML5 的 local storage 等等~
(這邊的程式參考到了 stackoverflow: losing values in local storage)
webViewSettings.setJavaScriptEnabled(true);
webViewSettings.setDomStorageEnabled(true);
webViewSettings.setDatabaseEnabled(true);
webViewSettings.setDatabasePath(“/data/data/”+getPackageName()+“/databases”);
3. 讓 WebView 顯示 asset 中的某個網頁
基本上這相當的容易,只要使用 loadUrl() 函式,
參數給像是 file:///android_asset/folder/filename 的格式就可以了~
如果載入的網頁只是純 HTML,不包含任何的 JavaScript 的話,
這樣子就已經算是結束了~
不過有用到 JavaScript 的話,還需要下面的幾個動作喔~
4. 提供一個 WebChromeClient 並改寫必要的函式
通常我們必須要改寫 WebView 中的 WebChromeClient,
沒有改寫的話,像 JavaScript 中如果有呼叫到 alert() 或是 confirm() 之類的函式時,
基本上是不會跳出警告或確認視窗的!!
所以通常需要去改寫 WebChromeClient 中的 onJsAlert() 與 onJsConfirm() 函式,
好讓它們改呼叫 Android 原生的 AlertDialog 來產生對話視窗:
{
@Override
public boolean onJsAlert(WebView view, String url, String message,
final JsResult result)
{
new AlertDialog.Builder(MyTestActivity.this)
.setMessage(message)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}})
.show();
return true;
}
@Override
public boolean onJsConfirm(WebView view, String url,
String message, final JsResult result)
{
new AlertDialog.Builder(MyTestActivity.this)
.setMessage(message)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}})
.show();
return true;
}
});
5. 提供一個 WebViewClient
如果沒有提供 WebViewClient 的話,此時在網頁裡面使用類似 location.href = “xxx.html” 的話,
Activity Manager 會選擇適當的程式(如瀏覽器)來開啟這個網址,
而不是用現在的這個 WebView 喔(說明可參閱 Android SDK: WebViewClient::shouldOverrideUrlLoading)~
像我在 JavaScript 裡面寫 location.href = “file:///android_asset/xxx”; 的話就會出錯了,
因為對外部的瀏覽器來說,這個網址是不存在的!
想要解決這個問題的話,只要提供一個 WebViewClient 就行了,
就算沒有改寫裡面的函式也沒關係~
{
});
下面是一個比較完整的程式範例:
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
public class MyTestActivity extends Activity {
// Controls
private WebView m_webView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Initialize controls
m_webView = (WebView)findViewById(R.id.webViewMain);
// Initialize web view
WebSettings webViewSettings = m_webView.getSettings();
webViewSettings.setJavaScriptEnabled(true);
webViewSettings.setDomStorageEnabled(true);
webViewSettings.setDatabaseEnabled(true);
webViewSettings.setDatabasePath(“/data/data/”+getPackageName()+“/databases”);
// Override functions so that javascript alert() and confirm() can work
m_webView.setWebChromeClient(new WebChromeClient()
{
@Override
public boolean onJsAlert(WebView view, String url, String message,
final JsResult result)
{
new AlertDialog.Builder(MyTestActivity.this)
.setMessage(message)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}})
.show();
return true;
}
@Override
public boolean onJsConfirm(WebView view, String url,
String message, final JsResult result)
{
new AlertDialog.Builder(MyTestActivity.this)
.setMessage(message)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}})
.show();
return true;
}
});
// Initialize a webview client
m_webView.setWebViewClient(new WebViewClient()
{
});
// Show main page
m_webView.loadUrl(“file:///android_asset/NewTaipeiCityLibraryMultiLogin/popup.html”);
}
}
執行之後,就可以看到 WebView 中有顯示我們在 asset 中放入的 popup.html 了~