【Flutter】QRコードから特定の画面を開く
「スマホのカメラアプリからQRコードを読み取って、アプリ内の特定の画面を開きたい」というリクエストがあり、実装できたので紹介します。
Androidでちょっとした落とし穴もあったので、忘備録も兼ねて...
全体的な流れとしては
①Deeplinkからアプリを起動できるようにする
②Deeplink経由でアプリを起動したことを検知し、特定のページに遷移する
という感じです。
①Deeplinkからアプリを起動できるようにする
Android、iOSのそれぞれで設定します。
サンプルとして、kenji0622://で始まるURLでアプリを開けるようにします。
kenji0622のところは好きな文字に変更して下さい。
iOS
iOS/Runner/Info.plistの<dict>の中に次のコードを追加します。
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>kenji0622</string>
</array>
</dict>
</array>
Android
android/app/src/main/AndroidManifest.xmlの<activity>の中に次のコードを追加します。
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="keni0622" />
</intent-filter>
ここで注意!!
すでにある<intent-filter>の中に上の4行を追加するのではなく、新たに<intent-filter>のタグで囲ってあげて下さい。
そうしないと、Androidでビルドしたときにアイコンが表示されなくなるようです。
アイコンが表示されない理由がわからず、結構悩みました...
ここまでの作業が完了すれば、kenji0622://で始まるURLにアクセスすると、アプリを起動できるはずです。
QRコード作成ツールなどを使って、URLをQRコードに変換すれば、カメラアプリでQRコードを読み取り、アプリを起動できるようになります。
②Deeplink経由でアプリを起動したことを検知し、特定のページに遷移する
app_linksというパッケージを使います。
app_linksをインストールしたら、一番最初に読み込むページで、Deeplink経由で起動したことを検知し、特定のページに遷移させる処理を書いていきます。
StatefulWidgetの場合のサンプルコードを紹介します。
//app_linksをインポート
import 'package:app_links/app_links.dart';
//Deeplink経由で起動したことを検知&特定のページに移動する処理
Future<void> initDynamicLinks() async {
final appLinks = AppLinks();
appLinks.uriLinkStream.listen((uri) {
print('url:$uri');
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SpecificPage()),
);
}).onError((error) {
print('onLink error');
print(error.message);
});
}
void initState() {
super.initState();
initDynamicLinks();
}
これで、QRコードからアプリを起動した場合は特定のページに遷移させられるようになります。
print('url:$uri')で、読み込んだDeeplinkの確認ができるので、工夫をすればDeeplinkのパラメータごとに異なる処理をすることもできそうです!
以上、スマホのカメラアプリからQRコードを読み取って、アプリ内の特定の画面を開く方法の紹介でした!
Discussion