Flutter中使用Android App Link后,如何获取URL路径并启动正确路由?
解决方案
要让Flutter应用根据Android App Link的跳转路径导航到对应路由,需要获取启动时的Intent数据并解析路径,同时区分主动启动和外部跳转场景,具体步骤如下:
1. 原生层(Android)配置Intent数据传递
在MainActivity中通过MethodChannel将Intent的URL数据传递给Flutter:
Kotlin代码(MainActivity.kt)
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel class MainActivity : FlutterActivity() { private val CHANNEL = "app/intent_channel" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> when (call.method) { "getInitialIntent" -> { val intentUrl = intent?.data?.toString() result.success(intentUrl) } else -> result.notImplemented() } } } // 处理应用后台时的新跳转Intent override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) setIntent(intent) val channel = MethodChannel(flutterEngine?.dartExecutor?.binaryMessenger, CHANNEL) channel.invokeMethod("onNewIntent", intent.data?.toString()) } }
2. Flutter层解析路由并导航
在Flutter中获取Intent数据,判断是否来自App Link跳转,设置对应初始路由,并处理后台唤醒的跳转:
Dart代码(main.dart)
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() async { // 初始化Flutter绑定 WidgetsFlutterBinding.ensureInitialized(); // 获取初始Intent的URL String? initialUrl = await _getInitialIntentUrl(); runApp(MyApp(initialUrl: initialUrl)); } Future<String?> _getInitialIntentUrl() async { const channel = MethodChannel('app/intent_channel'); try { return await channel.invokeMethod<String>('getInitialIntent'); } on PlatformException catch (e) { print("获取Intent失败: ${e.message}"); return null; } } class MyApp extends StatefulWidget { final String? initialUrl; const MyApp({super.key, required this.initialUrl}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> with WidgetsBindingObserver { final MethodChannel _channel = const MethodChannel('app/intent_channel'); @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); // 监听后台唤醒的新Intent _channel.setMethodCallHandler((call) async { if (call.method == 'onNewIntent') { String? url = call.arguments as String?; _navigateToRoute(url); } }); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } // 根据URL导航到对应路由 void _navigateToRoute(String? url) { if (url?.contains('/result') == true) { Navigator.pushReplacementNamed(context, '/result'); } } @override Widget build(BuildContext context) { // 确定初始路由:主动启动用'/', App Link跳转用'/result' String initialRoute = widget.initialUrl?.contains('/result') == true ? '/result' : '/'; return MaterialApp( title: 'Example', theme: ThemeData(primarySwatch: Colors.blue), initialRoute: initialRoute, routes: { '/': (context) => const Center(child: Text("/")), '/result': (context) => const Center(child: Text("/result")), }, ); } }
3. 关键说明
- 主动启动判断:当用户直接点击应用图标启动时,
initialUrl为null,初始路由设为/。 - App Link跳转处理:当通过
https://myusername.github.io/result跳转时,解析URL包含/result,自动导航到/result路由。 - 后台唤醒处理:通过
onNewIntent方法监听应用后台时的跳转请求,确保再次跳转也能导航到正确路由。
内容的提问来源于stack exchange,提问作者M. Akar
相关产品推荐
相关产品推荐

