WebView上でのリクエストをフックする方法

Androidアプリ上でWebページを表示したい場合は「WebView」を使用することになる。
今回はWebViewで表示したWebページ上のリンクがユーザによりタップされた場合に、それをアプリで検知する方法を紹介する。

<方法概要>

1.WebViewでWebページを表示できる様にする
2.WebViewにWebViewClientを設定する

<方法詳細>

1.WebViewでWebページを表示できる様にする

1.1.パーミッションの設定

「<uses-permission android:name="android.permission.INTERNET" />」をAndroidManifest.xmlに追加する。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="biz.accele.samplewebview" >

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
1.2.画面レイアウトを定義するxmlファイルにWebViewを追加する

activity_main.xml

<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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <WebView
        android:id="@+id/webView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>
1.3.表示するURLを指定する

MainActivity.java

package biz.accele.samplewebview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.WebView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // WebViewの取得
        WebView webView1 = (WebView) findViewById(R.id.webView1);

        // 表示するURLを指定
        webView1.loadUrl("https://www.google.co.jp/");
    }
}

ここまででアプリを実行すれば、Googleのトップページがアプリ内に表示される。

f:id:MoonMtLab:20160825231805p:plain:w200

2.WebViewにWebViewClientを設定する

今回の本題である、Webページ上のリンクがタップされたことをアプリで検知するために、WebViewにWebViewClientを設定する。

WebViewにWebViewClientを設定するためには、WebViewクラスの「setWebViewClient」メソッドを使用する。
また、Webページ上のリンクがタップされたことをアプリで検知するためには、WebViewClientクラスの「shouldOverrideUrlLoading」メソッドをオーバーライドし、そこに検知後の処理を記述することで実施できる。

今回は単純にするために、タップされたリンクのURLを表示する例を準備した。

MainActivity.java

package biz.accele.samplewebview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // WebViewの取得
        WebView webView1 = (WebView) findViewById(R.id.webView1);

        // WebViewClientの設定
        webView1.setWebViewClient(new WebViewClient() {

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {

                Log.d("--- ログ --->", "タップされたリンクのurl:" + url);

                return true;
            }
        });

        // 表示するURLを指定
        webView1.loadUrl("https://www.google.co.jp/");
    }
}

アプリを実行して、Webページ内のリンクをタップすれば、logcatにリンクのURLが出力される。

08-25 20:12:36.401    5902-5902/biz.accele.samplewebview D/--- ログ --->﹕ タップされたリンクのurl:https://www.google.co.jp/webhp?output=search&tbm=isch&tbo=u



ただ、リンクのURLはログに表示されるが、画面がそのURLに遷移することはない。
これは、「WebViewClient#shouldOverrideUrlLoading」の戻り値として「true」を設定しているためである。
リンク先に遷移したい場合は、上記の戻り値を「false」に設定することで実施できる。

Enjoy Programing!!