工作と競馬2

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

WebViewを使ってWebアプリを表示させるアプリを作った時にやったことメモ

概要

WebViewを使ってWebアプリを表示させるアプリを作った時にやったことをメモした。


背景と目的

最近、Webアプリでユーザージェスチャーなしで音声が自動再生されるようにしようとしたところ、ブラウザの制約上どうしても難しいことが分かった。(Web上で調べると、できるとかできないとかいろいろ情報が錯綜しているのだが、数年前の情報が中心で、2020年6月時点で最新の主要なWebブラウザでは、動画で音量ゼロなら可能そうだが、音声のみのメディアファイル自動再生はできないようだ。やってみたがやっぱりうまくいかなかった。)そこで、この制約をどうにか乗り越えたいので、WebViewを使ってWebアプリを表示させるだけのAndroidアプリを作った。そのときに雑多にハマった内容が多かったのでメモしておく。


詳細

0.前提

0.1 表示対象のWebアプリ主な仕様

  • 常にフルスクリーン
  • http通信
  • ユーザージェスチャーなしで音声を再生(ブラウザ制約で実現できていないので、WebViewを使ったネイティブアプリで実現した)
  • javascriptを使用

0.2 使用端末

  • NEC TE507
    • Android 9(アプリ)
    • WebViewで使用するエンジンはChrome バージョンは83.0.4103.83

0.3 Androidアプリで実現したい最低限の機能

  • スワイプでリロード
  • 0.1の機能がすべて動く


1. フルスクリーン表示

プロジェクト作成時に、fullscreen layoutのアクティビティのサンプルコードを使用すると簡単。いちばん外側のFrameLayoutの直下にあるTextViewをWebViewに置き換えればOK。

<TextView ...

<WebView ...

また、コードの方は、mContentViewというオブジェクトがTextViewなので、これをWebViewに置き換えればOK。

private TextView mContentView;
↓
private WebView mContentView;

あと、onCreateメソッドにある以下の部分を変更。

mVisible = true;
↓
mVisible = false;


2. スワイプで更新

こちらなどを参考に実装。以下のようにSwipeRefreshLayoutでWebViewを囲む。

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/swipeToRefresh"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <WebView
        android:id="@+id/fullscreen_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:keepScreenOn="true"
        android:text="@string/dummy_content"
        android:textColor="#33b5e5"
        android:textSize="50sp"
        android:textStyle="bold" />

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

さらに、onCreateメソッドで、

        mContentView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                toggle();
            }
        });
        final SwipeRefreshLayout swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipeToRefresh);
        swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                // Insert your code here
                mContentView.reload(); // refreshes the WebView

                // プログレスインジケータが表示されたままなので3秒後に消す
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        // 更新が終了したらインジケータ非表示
                        swipeLayout.setRefreshing(false);
                    }
                }, 3000);
            }
        });


2. ユーザージェスチャーなしで音声を再生

mContentView.getSettings().setMediaPlaybackRequiresUserGesture(false);


3.javascriptを使用

mContentView.getSettings().setJavaScriptEnabled(true);


4. HTTP通信

今回のWebアプリをホスティングしているのはHTTP通信のサーバだったので、HTTP通信が必要なのだが、Androidアプリのポリシー上マニュフェストファイルにusesCleartextTrafficの追加が必要だった。これがないと、ERR_CLEARTEXTどうのこうのというエラーが出る。HTTPSならいらない。

<application
:
android:usesCleartextTraffic="true"
:
>
以下省略


5.jqueryを使用

jqueryCDNから読み込んでいるが、以下ががないと、読み込めない旨のエラーが出る。CDNじゃなくても出るのかな???わからない。

mContentView.getSettings().setDomStorageEnabled(true);


6. MQTTを使用

MQTTについては、特に引っかかるところはなく、何もしなかった。状況としてはjqueryとあまり変わらないので、もしかして、5をやったついでに回避できたのかもしれない???


7. Android Studio上に、Webアプリのjavascriptデバッグコンソールの内容を表示させる

Webアプリの機能ではないが、デバッグ時に使用。

        mContentView.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onConsoleMessage(ConsoleMessage cslMsg) {
                Log.d("MyApp", cslMsg.message() + " at line "
                        + cslMsg.lineNumber() + " of "
                        + cslMsg.sourceId());
                return super.onConsoleMessage(cslMsg);
            }
        });


まとめと今後の課題

WebViewを使ううえでこまごました設定などがあって面倒だったがどうにかアプリが動いてよかった。