【Android】ローカルWebViewを使ってみた

## はじめに
今回はAndroidのローカルにあるHTMLを表示させてみようと思います。
ローカルWebViewと呼ばれています。
HTMLを表示するだけではなく、JavaScript⇒Androidや、Android⇒JavaScriptのメソッドを呼び出してみようと思います。
実装自体はあまり変わりません。前回の「WebViewを使ってみた」の記事を参考にしてください。
変わった部分としてはWebViewのURLがローカルファイルを参照するようにしたことと、HTMLをAndroid側に持ってきたぐらいです。

ディレクトリの構成はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/7ac42194-f14e-2dd1-944f-aa06ab925610.png)

シンプルにボタンがあるだけです。
クリックするとjsのメソッドを呼び出します。
```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <title>sample</title>
    <meta charset="UTF-8">
    <script src="./js/common.js"></script>
</head>
<body>
    <div>
        <input type="button" id="callButton" value="Android⇒JavaScript" onclick="callAndroid()">
    </div>
</body>
</html>
```
callAndroid()はAndroid側のメソッドを呼び出しています。
callJavaScript()はAndroid側から呼び出されるメソッドです。
```javascript:common.js
// Android側のメソッドを呼び出す処理
function callAndroid(){
    console.log(Android.sum(1,2));
}

// Android側から呼ばれるメソッド
function callJavaScript(){
    console.log('Androidからjavascriptを呼び出す');
}
```
「file:///android_asset/index.html」でローカルのHTMLファイルを参照するようにしてます。
```java:WebViewActivity.java
package com.example.testapp;

import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.HttpAuthHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import androidx.appcompat.app.AppCompatActivity;

public class WebViewActivity extends AppCompatActivity {

    static final String URL = "file:///android_asset/index.html";
    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 画面レイアウトをセット
        setContentView(R.layout.activity_webview);

        webView = (WebView) findViewById(R.id.webView);
        webView.getSettings().setJavaScriptEnabled(true); // JavaScriptを有効にする
        webView.addJavascriptInterface(new MainJsInterface(this,webView),"Android");
        webView.setWebViewClient(new WebViewClient(){
            @Override
            public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) {
                handler.proceed("××", "××");
            }
        }); // WebViewを設定する
        webView.loadUrl(URL); // URLを読み込む

    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent e){
        if(keyCode == KeyEvent.KEYCODE_BACK){ // 戻るボタンがタップされた時
            if(webView != null && webView.canGoBack()){ // WebViewがNULLでなく、閲覧履歴があるなら
                webView.goBack(); // 一つ前のウェブページを表示する
            }
            return true;
        }else{
            return super.onKeyDown(keyCode, e);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();// バックグラウンドからフォアグランドに戻った時など
        if(webView != null){ // WebViewが空でなければ
            String url = webView.getUrl(); // 現在のウェブページを
            webView.loadUrl(url); // 再表示する
        }
    }
}

```

sum()というメソッドがJavaScript側から呼ばれます。
その中でAndroid側のcallJavaScript()を呼んでいます。
```java:MainJsInterface.java
package com.example.testapp;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.webkit.HttpAuthHandler;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

public class MainJsInterface extends AppCompatActivity {

    Context context;
    WebView mywebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    MainJsInterface(Context a,WebView webView){
        context = a;
        mywebView = webView;
    }
    @JavascriptInterface
    public void showMain(){
        Intent intent = new Intent(this.context, MainActivity.class);
        context.startActivity(intent);
    }

    // JavaScript側から呼ばれるメソッド
    @JavascriptInterface
    public int sum(int a,int b){
        // Javascript側のメソッドを呼び出す
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                /// WebView側でJSを実行(エラー)
                mywebView.loadUrl("javascript:callJavaScript();");
            }
        });
        return a + b;
    }
}

```

以上

ローカルのHTMLを表示し、
Android⇔JavaScriptでメソッドを呼び合うことができました。
アプリを使いたいけどオフライン環境でも動作させたい、、みたいな状況で活かせそうです。

## 関連リンク

https://qiita.com/mojapico/items/be37fcba7545756625e7

https://qiita.com/mojapico/items/a6ef2e741b80c88787c0

https://qiita.com/mojapico/items/ed8ca624de85fe47cffa