【Flutter】AppLinksで別アプリから起動できるようにしてみる
公式ドキュメントどおりに進めてみる。
起動したいアプリ側のAndroidManifest.xml
にドキュメントのとおり、.MainActivity
を持つ<activity>
の部分に記載する。
+ <meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
+ <intent-filter android:autoVerify="true">
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+ <data android:scheme="http" android:host="example.com" />
+ <data android:scheme="https" />
+ </intent-filter>
host
についてはこのあとassetlinks.json
を置くドメインを記載しておく。
ストアに既に登録している場合、assetlinks.json
の中身はGooglePlayConsoleの該当アプリを表示後、設定 > アプリの署名 > Digital Asset Links JSON からコピーすることができる。
手っ取り早くFirebaseHostingでも使って、<host>/.well-known/assetlinks.json
となるように配置する。
AppLinksが正しく設定できているかは以下のサイトで検証可能(Proxyなどがあり、Googleからのリクエストを受け取れない場合は失敗するので注意)。
また、同様にコマンドでも検証可能。
adb shell 'am start -a android.intent.action.VIEW \
-c android.intent.category.BROWSABLE \
-d "http://<web-domain>/<some-root>"' \
<package name>
他のアプリから立ち上げてみる。
ひとまず android_intent_plus を使って、律儀に飛ばしてみる。
適当なボタンウィジェットとかのアクションで以下を実行する。
const intent = AndroidIntent(
action: 'android.intent.action.VIEW',
category: 'android.intent.category.BROWSABLE',
data: 'https://example.com',
package: '<packageName>',
);
await intent.launch();
【悲報】普通にWEBサイトが開かれた。
どうやら、起動したいアプリの設定から「対応するWebアドレス」を開いて、assetlinks.json
を置いたドメインをONにする必要があるみたい。
「アプリで開きますか?」みたいな確認メッセージ的なのって、出せないんだろうか・・・。
気を取り直して、再度飛んでみる。
・・・
内部でアプリが立ち上がった。
起動したいアプリ側のAndroidManifest.xml
のlaunchMode
を変更すると外部アプリとして立ち上がってくれる。
この変更をした場合、もはやurl_launcher
でも十分になる。
<activity
android:name=".MainActivity"
android:exported="true"
- android:launchMode="singleTop"
+ android:launchMode="singleTask"
</activity>
上記の修正をしない場合、flag
にFLAG_ACTIVITY_NEW_TASK
を付与することで外部アプリとして立ち上げることができた。
const intent = AndroidIntent(
action: 'android.intent.action.VIEW',
category: 'android.intent.category.BROWSABLE',
+ flags: [268435456],
data: 'https://example.com',
package: '<packageName>',
);
await intent.launch();
<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
の記述とgo_router
があれば、特に受け取る側で何かをする必要はなく、parserがいい感じに対応してくれる。