I'm having trouble getting the host url in onGenerateRoute callback.
onGenerateRoute: (routeSettings) {
String url = routeSettings.name ?? "";
log(url);
}
On cold start (when the app is closed and opened via url) url will be the full link (host + query params) - OK
When the app is in the background, url will contain only the query parameters of the url - not OK, I need the full link
I couldn't find any explanation why the RouteSettings.name returns different values for the same url when app is closed vs in the background.
I set the url in the AndroidManifest.xml file:
<!-- Deep linking -->
<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:host="example.com"
android:scheme="https" />
</intent-filter>
For example, if the link that I want to open the app is this: https://example.com/something?param=value
- when the app is closed, the
routeSettings.namewill be the whole link - when the app is in the background, the
routeSettings.namewill be/something?param=value
EDIT: Minimal reproducable example (modified the default counter app):
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
onGenerateRoute: (routeSettings) {
print("url:${routeSettings.name}");
},
title: 'Deeplink Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Deeplink test'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() => setState(() => _counter++);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('You have pushed the button this many times:'),
Text('$_counter', style: Theme.of(context).textTheme.headlineMedium),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
Add the <!-- Deep linking --> section from above to AndroidManifest.xml, and also set the launchMode to android:launchMode="singleTask" so Android wont start a new instance of the app.