AndroidのWebViewチュートリアルとサンプルです。WebView`はAndroid SDKのビューで、Webページをレンダリングする機能を持っています。

WebView とは?

WebView`とは、Webページを表示するビューのことです。

これは WebView クラスで表現されます。このクラスは思っている以上に強力です。しかし、使い方はとても簡単でわかりやすく、抽象化されたものを提供してくれます。

このクラスは、独自のウェブブラウザを作成したり、単にオンラインコンテンツを Activity 内に表示するための基礎となるものです。WebView は Web ページを表示するために WebKit レンダリングエンジンを利用しており、以下のようなメソッドがあります。

  1. 履歴を前後に移動する。
  2. ズームインとズームアウト。
  3. テキスト検索など。

WebViewは、JavascriptやHTMLマークアップのような言語でアプリケーションを書く方法を提供してくれる、非常に強力なツールです。この機能を利用したフレームワークは非常に多く、HTML5技術でアプリを書くことができます。例えば、ワードプレスなどのウェブサイトをアンドロイドアプリにすることもできます。

WebView APIの定義

WebViewは、android.webkitパッケージに含まれる具象クラスです。このクラスは android.widget.AbsoluteLayout` クラスから派生したもので,以下に示すようないくつかのインタフェースを実装しています。

public class WebView extends AbsoluteLayout implements ViewTreeObserver.OnGlobalFocusChangeListener, ViewGroup.OnHierarchyChangeListener

継承階層は以下の通りです。

java.lang.Object
   ↳    android.view.View
       ↳    android.view.ViewGroup
           ↳    android.widget.AbsoluteLayout
               ↳    android.webkit.WebView

なぜWebViewなのか?

WebViewは、おそらくアンドロイドの中で最も実用的で使いやすいのに使われていないクラスの一つです。それは、基本的にHTML、CSS、Javascriptを使ってアンドロイドアプリを作ることができるからです。もし、Javascriptの実行やCSSのレンダリングができないのであれば、あまり使われていないのも理解できます。しかし、このアプリはそれらをすべて実行します。

HTML、CSS、Javascriptは簡単に使えるポピュラーな技術で、皆さんが訪れたことのあるほとんどのウェブアプリやウェブサイトのユーザーインターフェースを動かしているので、これによって強力な機能が提供されます。さらに、これらの技術には、強力なウィジェットや抽象化を提供する何百ものフレームワーク/ライブラリがあります。これらの技術には、jQuery、Vue.js、Angular、React.js、Bootstrap、materializecss、UIKitなどがあります。

Node.jsやPHPのようなサーバーサイドの技術と対話できる、シンプルなクライアントサイドのウェブアプリケーションを簡単に作成し、assetsフォルダに配置することができます。そして WebView を使ってそれを読み込みます。ただし、Javascriptが有効になっていることを確認する必要があります。この方法は、JavaやKotlin、C#で書かれた完全なJavaアプリケーションに比べて強力ではありませんが、初心者にとっては最初のアプリをすぐに起動し、教育を受けながら友人に見せることができるでしょう。

WebView の使用

ほとんどの場合、オンラインのコンテンツをウェブビューで表示したいと思うでしょう。そこで、アクティビティがインターネットにアクセスして、WebViewにWebページを読み込むためには、Android ManifestファイルにINTERNETパーミッションを追加する必要があります。

<uses-permission android_name="android.permission.INTERNET" />

次に、レイアウト内に<WebView>を追加するか、onCreate()時にActivityウィンドウ全体をWebViewとして設定します。

 WebView webview = new WebView(this);
 setContentView(webview);

このようにして、loadUrl()メソッドでウェブページを読み込みます。

 // Simplest usage: note that an exception will NOT be thrown
 // if there is an error loading this page (see below).
 webview.loadUrl("https://camposha.info/");

loadurl()`は、指定したURLからWebサイトを読み込みます。これは最もよく使われる方法です。

また、HTMLの string から読み込むこともできます。

 String summary = "<html><body>You scored <b>192</b> points.</body></html>";
 webview.loadData(summary, "text/html", null);
 // ... although note that there are restrictions on what this HTML can do.
 // See the JavaDocs for loadData() and loadDataWithBaseURL() for more info.

これは基本的に、HTMLコードを string の中に記述することを意味します。そして、それを loadData() メソッドで読み込みます。簡単なDOM(Document Object Model)構造のWebサイトを読み込むのに適しています。

Quick WebView Examples and HowTo’s

WebViewクラスの簡単なHowToを見てみましょう。この後、アプリ全体を書く方法を見ていきます。

1. よく使われる WebView の設定

ここでは、よく使われる WebView の設定をいくつか紹介します。簡単に再利用できるように、シンプルなスタティックメソッドでカプセル化してみましょう。

    // Commonly used WebViewSetting
    public static void initWebSetting(WebView webView) {
        WebSettings setting = webView.getSettings();
        setting.setJavaScriptEnabled(true);
        setting.setAllowFileAccess(true);
        setting.setAllowFileAccessFromFileURLs(true);
        setting.setAllowUniversalAccessFromFileURLs(true);
        setting.setAppCacheEnabled(true);
        setting.setDatabaseEnabled(true);
        setting.setDomStorageEnabled(true);
        setting.setCacheMode(WebSettings.LOAD_DEFAULT);
        setting.setAppCachePath(webView.getContext().getCacheDir().getAbsolutePath());
        setting.setUseWideViewPort(true);
        setting.setLoadWithOverviewMode(true);
        setting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            setting.setAllowFileAccessFromFileURLs(true);
        }
    }

このメソッドは WebView オブジェクトを受け取ります。まず、WebViewクラスのgetSettingsメソッドでウェブビューの設定を取得します。そして、setJavaScriptEnabled()メソッドでjavascriptを有効にします。これらの設定メソッドのほとんどは、様々な設定を有効または無効にするためのブール値を受け取ります。

2. カスタム WebView の作成方法

NestedScrollViewで使用できるカスタムWebViewを作成したいと思います。

import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.webkit.WebView;

public class MyWebView extends WebView {

    public MyWebView(Context context) {
        super(context);
    }

    public MyWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyWebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        //Check pointer index to avoid -1 (error)
        if (MotionEventCompat.findPointerIndex(event, 0) == -1) {
            return super.onTouchEvent(event);
        }

        if (event.getPointerCount() >= 1) {
            requestDisallowInterceptTouchEvent(true);
        } else {
            requestDisallowInterceptTouchEvent(false);
        }

        return super.onTouchEvent(event);
    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
        requestDisallowInterceptTouchEvent(true);
    }
}

1. Android WebView – URL、文字列、Asset Folderからの読み込み

Android WebView – URL、Strings、Asset Folderからの読み込み 1.

WebViewは、実はアンドロイドに最初から存在しているクラスの一つです。

APIレベル1で追加されたもので、android.webkitパッケージに含まれています。これは、ウェブコンテンツを activity の中で表示するために使用されます。これは非常に強力で、動作する基本的なブラウザを構築するのにも使用できます。これはまだビューなので、パレットからレイアウトにドラッグするだけです。webkit レンダリング エンジンを使用して Web ページをレンダリングします。この例では、ウェブビューを使用して、次のようなウェブコンテンツをレンダリングします。

  • オンラインの URL。
  • ローカルの Assets フォルダ。
  • javaコード内の「文字列」。

URLから読み込むためには、androidmanifest.xmlにandroid internet permissionを設定する必要があります。WebView "についての詳細はこちらをご覧ください。

スクリーンショット
  • 以下はプロジェクトのスクリーンショットです。

この例でよくある質問を説明します。
  • WebView とは何ですか?
  • WebViewのURLからWebサイトをロードする方法。
  • Webviewでassetsフォルダからhtmlをロードする方法。
  • どのようにしてWebviewでhtml stringをロードするか。
  • どのようにしてアンドロイドの activity でウェブビューを使用するか。
使用ツール

このサンプルは、以下のツールを使用して作成しました。

  • Windows 8
  • AndroidStudio IDE
  • Genymotionエミュレータ
  • 言語:Java

このプロジェクトでは、サードパーティのライブラリは使用していません。

ソースコードに直接アクセスしてみましょう。

AndroidManifest.xml
  • Android Manifest ファイル。
  • URLからWebページも取得するので、インターネット許可を追加します。

<?xml version="1.0" encoding="utf-8"?>
<manifest
    package="com.tutorials.hp.webviewer">

    <uses-permission android_name="android.permission.INTERNET"/>
    ...
</manifest>
Build.Gradle
  • 通常、アンドロイドプロジェクトでは、2つの build.gradle ファイルがあります。1つはアプリレベルの build.gradle で、もう1つはプロジェクトレベルの build.gradle です。appレベルはappフォルダ内にあり、通常はここに依存関係を追加し、コンパイルとターゲットのsdkを指定します。
  • また、AppCompatとDesignサポートライブラリの依存関係も追加します。
  • MainActivity」はAppCompatActivityから派生し、デザインサポートライブラリのフローティングアクションボタンを使用します。

dependencies {
    implementation 'com.android.support:appcompat-v7:26.+'
    implementation 'com.android.support.constraint:constraint-layout:1.0.0-alpha7'
    implementation 'com.android.support:design:26.+'
    testImplementation 'junit:junit:4.12'
}
MainActivity.java
  • ランチャー Activity です。
  • この activity のコンテンツビューとして ActivityMain.xml を作成します。
  • この activity 内のビューとウィジェットを初期化します。
  • ツールバーのメニューアイテムを切り替えて、URL、assets、stringからの読み込みを選択します。

package com.tutorials.hp.webviewer;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebView;

public class MainActivity extends AppCompatActivity {

    WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        webView= (WebView) findViewById(R.id.myWebview);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });
    }

    /*
    LOAD WEBSITE
     */

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.urlID) {
            //LOAD FROM URL
            webView.loadUrl("https://camposha.info");

            return true;
        }else if (id == R.id.assetsID) {

            //LOAD FROM ASSETS
            webView.loadUrl("file:///android_asset/Campo.html");

            return true;
        }else if (id == R.id.stringID) {

            //LOAD FROM STRING
            String html="<html><title></title><body>" +
                    "<h1><u>Programming Languages</u></h1>" +
                    "Below are some languages check them out: " +
                    "<ol>" +
                    "<li>Java</li><li>C#</li><li>C++</li><li>Python</li><li>PHP</li><li>Perl</li>" +
                    "</ol>" +
                    "</body></html>";
            webView.loadData(html,"text/html","UTF-8");

            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
ActivityMain.xml
  • テンプレートのレイアウトです。
  • ContentMain.xml を含んでいます。
  • また、appbarlayouttoolbarfloatingaction butttonなども定義しています。

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout

    android_layout_width="match_parent"
    android_layout_height="match_parent"
    tools_context="com.tutorials.hp.webviewer.MainActivity">

    <android.support.design.widget.AppBarLayout
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android_id="@+id/toolbar"
            android_layout_width="match_parent"
            android_layout_height="?attr/actionBarSize"
            android_background="?attr/colorPrimary"
            app_popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton
        android_id="@+id/fab"
        android_layout_width="wrap_content"
        android_layout_height="wrap_content"
        android_layout_gravity="bottom|end"
        android_layout_margin="@dimen/fab_margin"
        app_srcCompat="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>
ContentMain.xml
  • コンテンツのレイアウトです。
  • MainActivity の内部に表示されるビューやウィジェットを定義します。
  • ここでは、シンプルなウェブビューを使用します。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout

    android_layout_width="match_parent"
    android_layout_height="match_parent"
    app_layout_behavior="@string/appbar_scrolling_view_behavior"
    tools_context="com.tutorials.hp.webviewer.MainActivity"
    tools_showIn="@layout/activity_main">

    <WebView
        android_id="@+id/myWebview"
        android_layout_width="match_parent"
        android_layout_height="match_parent"
        android_layout_centerHorizontal="true"
        />

</android.support.constraint.ConstraintLayout>
menu_main.xml
  • ツールバーのメニューアイテムを切り替えることにしましょう。
  • メニューのディレクトリにある menu_main.xml で定義しましょう。

<menu

    tools_context="com.tutorials.hp.webviewer.MainActivity">
    <item
        android_id="@+id/action_settings"
        android_orderInCategory="100"
        android_title="@string/action_settings"
        app_showAsAction="never" />
    <item
        android_id="@+id/urlID"
        android_title="URL"
        app_showAsAction="never" />

    <item
        android_id="@+id/assetsID"
        android_title="Assets"
        app_showAsAction="never" />

    <item
        android_id="@+id/stringID"
        android_title="String"
        app_showAsAction="never" />
</menu>
ダウンロード
  • 以下のプロジェクトをダウンロードしてください。
No. 場所 リンク
1. GitHub Direct Download
2. GitHub Browse
結論です。

簡単なandroid webviewの例を見ました。Webページをオンラインからurlで読み込む方法、assetsフォルダから読み込む方法、stringデータから読み込む方法。

WebView`にCSSをインジェクトする方法

自分が持っていないページを、CSSを使って操作したい場合があります。例えば、Webページが読み込まれた後に、CSSで独自のスタイルを適用するとします。

これはアンドロイドのウェブビューで可能です。以下にその手順を示します。

ステップ1: Base64のインポート

以下のインポートを追加します。

import android.util.Base64

ステップ2: cssを注入する関数の作成

この関数は、Javascriptを介してcssを注入します。

private fun injectCSS() {
            try {
                val inputStream = assets.open("style.css")
                val buffer = ByteArray(inputStream.available())
                inputStream.read(buffer)
                inputStream.close()
                val encoded = Base64.encodeToString(buffer , Base64.NO_WRAP)
                webframe.loadUrl(
                    "javascript:(function() {" +
                            "var parent = document.getElementsByTagName('head').item(0);" +
                            "var style = document.createElement('style');" +
                            "style.type = 'text/css';" +
                            // Tell the browser to BASE64-decode the string into your script !!!
                            "style.innerHTML = window.atob('" + encoded + "');" +
                            "parent.appendChild(style)" +
                            "})()"
                )
            } catch (e: Exception) {
                e.printStackTrace()
            }

        }

Step 3: onPageFinished をオーバーライドする

次のステップでは、ウェブビューがコンテンツの読み込みを完了したときに呼び出される onpage finished イベントをオーバーライドします。

 override fun onPageFinished(view: WebView?, url: String?) {
                injectCSS()
}

以上で完成です。