まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

タグ:webview

人気のテキストエディタである Visual Studio Code(以下 "VSCode")の機能を独自に拡張するプラグインの開発に挑戦してみました。以下で紹介するプラグインの開発は主にこのページにかかれている内容を参照し、参考にさせていただきました。ありがとうございます:
Visual Studio Codeの拡張機能を一通り触って自分用に公開するまで


作った拡張機能は MOTD(Manhole of this day) といいます:
https://marketplace.visualstudio.com/items?itemName=dotnsf.manholeofthisday

2020062305


機能は名前そのままですが、拙作マンホールマップの機能の1つである「今日のマンホール」を VSCode 内に表示する、というマンホーラー向けのものです。

VSCode にこのプラグインをインストールするには左ペインから「拡張機能」を選ぶか、Ctrl + Shift + X を押して拡張機能画面に移動し、検索バーに "manholeofthisday" と入力します("manholeof" あたりまで入力すると、検索候補が一つになります)。そして「インストール」と書かれた箇所をクリックしてインストールします:
2020062301


インストール後、実際に MOTD 機能を利用する場合は Ctrl + Shift + P でコマンドパレットを開き、このパレットに "MOTD" と入力してコマンドを検索し、最後に見つかった MOTD 部分をクリックします:
2020062302


MOTD コマンドを実行した日(月&日)のマンホールがマンホールマップの「本日のマンホール」に記録されて存在していた場合は VSCode 内の新しいタブが一つ追加され、その中で「本日のマンホール」画像と説明が表示されます。なおこの機能の実現には Webview API を使っています:
2020062303


画像部分をクリックすると、ブラウザで該当マンホールのマンホールマップ内ページが開き、より詳しい情報を参照することができる、というものです:
2020062304



この MOTD プラグインのソースコードはこちらで公開しています。開発言語として TypeScript を選ぶこともできましたが、今回は JavaScript で開発しました。この手軽さもハードル低くていいですね:
https://github.com/dotnsf/manholeofthisday

 

WebView は、「ネイティブアプリに内蔵して使うブラウザ」です。

HTML5 をベースにするなどして、ネイティブアプリっぽい見栄えになったウェブアプリケーションであっても、利用するには URL を打ち込むか、ブックマークから選択するなどして(つまり、あくまでウェブページとして)利用することになります。

でも、そのようなウェブアプリは簡単にネイティブ化する方法があります。それが上述の WebView を使う方法です。WebView 自体はネイティブアプリケーションに組み込んで使う部品ですが、例えば「全画面 WebView だけを表示するネイティブアプリ」を作れば、(メニューの表示項目は何にするか、JavaScript を有効にするか無効にするか、最初に表示するページの URL はどうするか・・・などの設定項目はありますが)それはウェブブラウザでウェブページを見ているのと大きく変わりません。モバイルUIに対応したウェブページを比較的簡単にネイティブアプリ化する方法、といえます。

実際に自分も Android アプリ開発の中で使ってみる機会があったのですが、そこで想定外のことに1つ躓きました。それがタイトルにある「何も考えずに Android の WebView を使うと viewport が無視される」ということです。

これがバグ扱いなのか、何らかの理由があっての仕様なのかもよくわかりませんが、ともあれ何故か viewport は無視されてしまいます。

そしてそれが原因で、本来モバイルUIで表示されるべきページが、WebView を使って見た時だけモバイル端末と判断されず、PC 用の UI で表示されてしまう、という現象が起こってしまいます。

で、これを回避するための方法がこちらです。色々設定してますが、今回の肝は青字部分の2つ:
(1) 読み込み時にページ横幅を画面幅に無理やり合わせる
(2) ワイドビューポートへの対応
public class MainActivity extends Activity{
  public WebView webView = null;

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

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

    //. JavaScript 有効
    webView.getSettings().setJavaScriptEnabled( true );

    //. リンクタップ時に標準ブラウザを使わない
    webView.setWebViewClient( new WebViewClient() );

    //. (1) 読み込み時にページ横幅を画面幅に無理やり合わせる
    webView.getSettings().setLoadWithOverviewMode( true );

    //. (2) ワイドビューポートへの対応
    webView.getSettings().setUseWideViewPort( true );

      :
      :
    //. 初期URLを指定してロード
    webView.loadUrl( "http://neppi.co/" );
  }

  :
  :
}

これで viewport を読んでいる時と同様に画面幅を強制的に変更して、本来の(モバイルUIの)ページに対応させることができました。

なお、WebView に関しては Android 4.3 以下の(WebKit ベースの)WebView については Google による脆弱性サポートが提供されなくなる、というニュースがありました(4.4 以上の Chrome ベースの WebView に対してのみサポート継続):
Google No Longer Provides Patches for WebView Jelly Bean and Prior

4.3 以下ってまだ結構多いはず。そして WebView を使ってるアプリってどのくらいあるんだろ?? その意味でも少し気になるニュースではあります。







 

このページのトップヘ