FlutterのWebView内からメールアプリを起動してみた件

# はじめに
　みなさんはFlutterでWebViewを使用したことありますか？
　すみません、そんなことはどうでもいいです。今回はタイトルにもある通り、FlutterのWebView内から端末内のメールアプリを起動してみます。

# 最終結果
　最終的に、下の画像みたいにメールアプリを起動する画面を出します。

![66005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600842/69e94c91-c5bd-b59e-cae3-3bbb1b3abb9c.jpeg)


# いつメールアプリを起動するのか
　普通にWebViewを出してるだけだと、メールアプリを起動する場面はなかなかありませんが、あるとするなら、「お問合せはコチラ」みたいなとこクリックしてメールアプリを起動するみたいな感じです！
　掲示板みたいに、自分の名前とかメアドを入力してお問合せできるページが用意されていれば、特に問題はないんですけど、全部がそういうわけじゃないからな～～～

# 普通にWebViewからメールアプリを起動してみる
　普通にWebViewからメールアプリを起動してみます。Flutterにはなぜか最初からWebViewは入っていないため、ライブラリを用います。今回使用するライブラリは「[webview_flutter](https://pub.dev/packages/webview_flutter)」です。
　また、メールアプリを起動するものには、urlに「"mailto:メアド"」がはいってます。（例：mailto:example@ex.com）

　今回開くURLは私が鹿児島大学で所属している「[KADAI INFO](https://kadai-info.com/)」のサークル紹介ページへアクセスします。（よかったら[KADAI INFO](https://kadai-info.com/)見てほしい！）

```main.dart
WebView(
    initialUrl:"https://kadai-info.com/2020/03/13/kabadiclub-2020/", // URL読み込み
    javascriptMode: JavascriptMode.unrestricted,  // javascriptの有効化
);
```
　これを開いてみると以下のような結果になります。
![66004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600842/36af2f02-ad12-cb18-1fa5-1fb09b303203.jpeg)

ここは、普通のページなので、特に問題なく表示されます。しかし、この「入部希望の連絡をする」をタップしてみると以下のようになります。
![66006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600842/1dd1f0d4-1d35-6b97-6da3-43684792f430.jpeg)


はい、なんやらエラーページがでました。urlを見てみると、「mailto:〇〇@gmail.com」とメールアプリを起動するURLが設定されています。
パソコンには既にこういうアドレスを開く機能が備わっていますが、アプリでは自分で設定しないとこのようなエラーがでます。

# url_launcherを使う
　こういったメールアプリを起動するような特殊なURL処理をするライブラリとして「[url_launcher](https://pub.dev/packages/url_launcher)」というものがあります。
　しかし、こちらのライブラリの例題は、WebView上で機能するものではなく、自分でボタンやら設定して、それがタップされたら起動する～みたいなやつです。
　使い方はめちゃくちゃ簡単で、WebViewとほぼ同じ感じです（下のやつを参考にしてくれい！）。

```hoge.dart
  const url = "指定のURL";

  // 有効なアドレスだったら
  if (await canLaunch(url)) {
    await launch(url);  // メールアプリを開く

  // 有効なアドレスでないなら
  } else {
    throw 'Could not launch $url';
  }
```
　しかし、これを使用するためにはURLを知っておく必要があります。1つしかないなら直接打ち込めばいいですが、このサークルページは他にもいくつもあり、全部あらかじめ用意しておくのはマジきつい。
　そこで、WebViewからURLを取得します。

# WebViewからURLを取得する
　そもそもWebViewからどうやって、URLを取得するのか？
　webview_flutterの中の「NavigationDeligate」から取得できます。これは、URL先に遷移するか制御するものです。また、これを使用するときは引数に「NavigationRequest」を渡します。つまり、こいつは遷移先のURLをどこかに保持している可能性があります。ライブラリを見てみると案の定「String url」を持っていたので、こいつにアクセスしてURLを取得します。

```hoge.dart
navigationDelegate: (NavigationRequest request) {
    String url = request.url; // request.urlで取得できる（requestの名前は何でもいい）
}
```

これで、URLは取得できましたので、あとはこのURLとurl_launcherを使用するだけでOKです！

# メールアプリを起動させてみる
　では、最後に実際に起動させてみます。コードは以下

```main.dart
_launchURL(String url) async {
    // 有効なアドレスだったら
    if(await canLaunch(url)){
      await launch(url);  // メールアプリを起動
      return true;
    }
    // 有効なアドレスでないなら
    else{
      return false;
    }
  }

return WebView(
    initialUrl: url,
    navigationDelegate: (NavigationRequest request) {
        // メールアプリを起動する必要があったら
        if(_launchURL(request.url)){
           return NavigationDecision.prevent;  // 前のページに戻る
        }
        // メールアプリを起動する必要がなかったら
        else{
           return NavigationDecision.navigate;  // そのままページを読み込む
        }
    },
);
```

メールアプリを起動したら前のページに戻る処理をしていますが、これはエラーページを表示させないためです。
これしないと↓みたいになって気持ち悪い。
![66007.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600842/653a6f9f-0e24-8fcb-4dfa-8603f8832eff.jpeg)

だから、メールアプリを起動する必要があるようなページだった場合は、前のページに戻って、そうでないならそのまま突き進む処理を施したってわけだぜ！
まあ、最初にも載せてるけど、戻れば↓みたいに遷移前の画面でメールアプリ起動の画面を出せる

![66005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600842/f53d5351-d5fa-2eab-c824-0f159edb2ad5.jpeg)

# 終わりに
　今回はメールアプリを起動させてみました。ていうか、メールアプリって最初から言ってるけど正しい言い方は分からんから別に指摘しないでくれ！頼む！フリじゃない！
　また、自分で調べて日本語記事がないやつあったら書いていきます！ではまた！