WebView の DOM 操作

Android の WebView 動作

やりたいことは、Android のネイティブアプリのコンポーネントandroid.webkit.WebView」で読み込んだ HTML のページに対して DOM 操作を行いたい。

動作環境

Device SDK
Nexus S(Android 4.1.2) Android 4.0.3 Google APIs

検証方法

適当なドメインで公開されている単純な HTML で DOM操作をしてみる。

こんな感じの HTML をどこかに公開する。

<h1>TEST PAGE</h1>
<form action="/" method="GET" id="form1">
    <input type="hidden" name="param1" value="hgoehoge">
    <input type="submit">
</form>

AndroidManifest.xml で次の Permission を設定する。

android.permission.INTERNET

layout 配下に適当な名前で次の画面を作る。

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <WebView android:id="@+id/web_view"
             android:layout_width="fill_parent"
             android:layout_height="0dip"
             android:layout_weight="1"
            />
    <Button android:id="@+id/button"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Button"
            android:drawablePadding="10dip"
            />

</LinearLayout>

Activity クラスで画面制御。

package com.example.test_android_ui;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.widget.Toast;

public class MyActivity2 extends Activity implements View.OnClickListener {

    WebView webView = null;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 上記のレイアウトを設定する
        setContentView(R.layout.webviewtest);

        // 上記の公開している URL を指定する
        webView = (WebView) findViewById(R.id.web_view);
        String url = "http://hogehoge/test.html";
        webView.loadUrl(url);

        // Javascript を有効に
        webView.getSettings().setJavaScriptEnabled(true);

        // DOM 操作を行うネイティブボタンのイベントを登録する
        findViewById(R.id.button).setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {

        int id = v.getId();
        switch (id) {
            case R.id.button:
                // Javascript 実行
                String formAction = "http://yahoo.co.jp/";
                final String script = String.format("javascript:document.getElementById(\"form1\").action = \"%s\"", formAction);
                Toast.makeText(v.getContext(), String.format("Changed form action. %s", formAction), Toast.LENGTH_SHORT).show();
                webView.loadUrl(script);
                break;
            default:
                break;
        }
    }
}

ネイティブボタンを押下せずにサブミットすると自身のドメインのトップに遷移する。
自身のネイティブボタンを押下してからサブミットすると yahoo.co.jp へ遷移する。
異なるドメインへのアクションの変更が可能っぽい。

未検証

  • HTTPS のページで DOM 操作可能かどうか
  • 制限についての詳細(WebKit の許す範囲で制限なしかどうか)