url_launcher
ネイティブアプリからWebサイトを開く場合は「url_launcher」というパッケージを使用します。
例えば、Webサイトとして公開されている利用規約をネイティブアプリから開く際などに使用されることが多いです。
パッケージの準備
まずは url_launcherパッケージ を pubspeck.yaml に記述し、Pub get します。
dependencies:
flutter:
sdk: flutter
url_launcher: ^6.1.5
次にパッケージを使いたい画面でインポートします。
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart';
SMSなどを使用する場合は他の準備も必要ですが、今回は実装しません。
これで準備は完了です!
URLへの遷移を実装する方法は以下の二つがあります。
- String 型のURLを使用する
- Uri 型のURLを使用する
それぞれ実装方法を解説します。
String型のURL
ChangeLog を見ると、バージョン6.1.0から大きな変更が加えられています。
それまでは String型のURLで遷移先を指定することが一般的だったものが、Uri 型で指定するように変更されました。しかし、String 型で指定する方法も残されているので紹介します。
コードは以下の通りです。
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart';
class UrlLauncherExample extends StatelessWidget {
UrlLauncherExample({Key? key}) : super(key: key);
final _urlLaunchWithStringButton = UrlLaunchWithStringButton();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("UrlLauncherExample"),
),
body: Center(
child: ElevatedButton(
child: const Text("Google"),
onPressed: () {
_urlLaunchWithStringButton.launchUriWithString(
context,
"https://www.google.com",
);
}),
),
);
}
}
class UrlLaunchWithStringButton {
final alertSnackBar = SnackBar(
content: const Text('このURLは開けませんでした'),
action: SnackBarAction(
label: '戻る',
onPressed: () {},
),
);
Future launchUriWithString(BuildContext context, String url) async {
if (await canLaunchUrlString(url)) {
await launchUrlString(url);
} else {
alertSnackBar;
ScaffoldMessenger.of(context).showSnackBar(alertSnackBar);
}
}
}
今回はUrlLaunchWithStringButton
というクラスを作成しました。
Future launchUriWithString(BuildContext context, String url) async {
if (await canLaunchUrlString(url)) {
await launchUrlString(url);
} else {
alertSnackBar;
ScaffoldMessenger.of(context).showSnackBar(alertSnackBar);
}
}
このコードでは String 型のURLで遷移するための処理を記述しています。
引数として context
とurl
を取得しています。
canLaunchUrlString()
メソッドは引数に指定したURLに遷移することができるかを確かめるためのメソッドです。遷移可能であれば True、不可能であれば False を返すため、遷移前の条件分岐に使用されています。
launchUrlString()
メソッドで引数に指定したURLへ遷移します。
final alertSnackBar = SnackBar(
content: const Text('このURLは開けませんでした'),
action: SnackBarAction(
label: '戻る',
onPressed: () {},
),
);
このコードでは先述したlaunchUrlString()
メソッドで引数に指定したURLへ遷移できなかった際に表示する SnackBar を記述しています。
final _urlLaunchWithStringButton = UrlLaunchWithStringButton();
このコードでは作成した UrlLaunchWithStringButton
クラスをインスタンス化し、_urlLaunchWithStringButton
という変数に代入しています。
onPressed: () {
_urlLaunchWithStringButton.launchUriWithString(
context,
"https://www.google.com",
);
}
このコードでは_urlLaunchWithStringButton
のメソッドを使って、引数に context
と遷移先のURL(今回は Googleのページ)を指定しています。
第二引数のURLを変更することで遷移先を変更することができます。
Uri 型のURL
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart';
class UrlLauncherExample extends StatelessWidget {
UrlLauncherExample({Key? key}) : super(key: key);
final _urlLaunchWithUriButton = UrlLaunchWithUriButton();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("UrlLauncherExample"),
),
body: Center(
child: ElevatedButton(
child: const Text("Flutter"),
onPressed: () {
_urlLaunchWithUriButton.launchUrlWithUri(context);
}),
),
);
}
}
class UrlLaunchWithUriButton {
final Uri _flutterUrl = Uri.parse('https://flutter.dev');
final alertSnackBar = SnackBar(
content: const Text('このURLは開けませんでした'),
action: SnackBarAction(
label: '戻る',
onPressed: () {},
),
);
Future<void> launchUrlWithUri(BuildContext context) async {
if (!await launchUrl(
_flutterUrl,
)) {
alertSnackBar;
ScaffoldMessenger.of(context).showSnackBar(alertSnackBar);
}
}
}
String 型のURLと区別するため、UrlLaunchWithUriButton
というクラスを作成しています。
final Uri _flutterUrl = Uri.parse('https://flutter.dev');
このコードでは Uri 型へ変更した URL を _flutterUrl
という変数に代入しています。
Future<void> launchUrlWithUri(BuildContext context) async {
if (!await launchUrl(
_flutterUrl,
)) {
alertSnackBar;
ScaffoldMessenger.of(context).showSnackBar(alertSnackBar);
}
}
遷移先と指定したURLがString型だったときは launchUrlString()
メソッドで引数に指定したURLへ遷移していましたが、このコードでは遷移先の URL が Uri 型であるため、 launchUrl()
メソッドを使用しています。混同しないよう気をつけましょう。
その他のコードは String 型の URL とほぼ同じであるため、省略します。
mode
mode とは URL を開く際の遷移方法を指します。
6.1.0バージョンまで launchUrl()
メソッドには forceSafariVC
や forceWebView
というプロパティがありましたが、アップデートされたパッケージでは mode
というプロパティに変更されています。
mode
には以下の4種類があります。
- inAppWebView
- externalApplication
- externalNonBrowserApplication
- platformDefault
コード | 説明 |
---|---|
LaunchMode.inAppWebView | デフォルトで指定されているモード。 遷移先のページをアプリ内の一つのページで開いているかのように遷移するモード |
LaunchMode.externalApplication | Webページを Safari など 別のアプリケーションで開くモード |
LaunchMode.externalNonBrowserApplication | ブラウザ以外の外部のアプリケーションを 開く際に使用するモード |
LaunchMode.platformDefault | プラットフォームのデフォルトの 遷移方法を採用するモード |
iOSシュミレータでは platformDefault
は inAppWebView
と同じになっていました。
inAppWebView と externalApplication の違い
inAppWebView
inAppWebView ではアプリ内の一ページのように遷移し、画面左上の「完了」ボタンを押すと元のページに戻ることができます。
externalApplication
externalApplication では開いていたアプリとは別のアプリとして Safari を開いています。
元のページに戻るには「完了」ボタンではなく、SafeArea にある 「◀︎ アプリ名」 の表示を押す必要があります。
inAppWebView と比較するとユーザにとって元のアプリに戻るコストが高いと言えるでしょう。
逆に、Webページ上でユーザにじっくり読んでもらいたいコンテンツがある場合は externalApplication による遷移を実装した方が良いと言えるのではないでしょうか。
以上です。
あとがき
今回は簡単な Webサイトへの遷移のみを行いましたが、実機で試す場合にはインストールされているアプリとの連携も可能なので、使ってみたいと思います。
参考にしていただければ幸いです。
誤っている箇所があればご指摘いただければ幸いです。
参考にしたサイト