Flutter应用打开浏览器URL后如何返回并跳转至对应页面?
Flutter实现网页跳转回应用并根据操作路由页面
你用url_launcher只能打开浏览器,要实现返回应用+路由跳转,得靠深度链接(Deep Link)——让网页通过自定义链接唤起你的Flutter应用,同时带上操作结果参数,应用解析参数后跳对应页面。下面是具体步骤:
1. 给应用配置Deep Link
Android端
打开android/app/src/main/AndroidManifest.xml,给主Activity添加intent-filter,用来接收Deep Link请求:
<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <!-- 把myapp换成你的自定义scheme,比如用应用名缩写 --> <data android:scheme="myapp" android:host="callback" /> </intent-filter>
iOS端
打开ios/Runner/Info.plist,添加以下配置:
<key>LSApplicationQueriesSchemes</key> <array> <string>myapp</string> <!-- 和Android的scheme保持一致 --> </array> <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>myapp</string> </array> <key>CFBundleURLName</key> <string>com.yourcompany.yourapp</string> <!-- 替换成你的应用Bundle ID --> </dict> </array>
2. 网页端处理回调逻辑
用户在网页完成操作后,通过跳转你的Deep Link唤起应用,同时带上参数(比如操作类型、订单ID)。举两个例子:
- HTML链接跳转:
<a href="myapp://callback?type=success&orderId=123">返回应用查看结果</a>
- JS自动跳转:
// 操作完成后自动触发 window.location.href = "myapp://callback?type=cancel";
3. Flutter端解析Deep Link并跳转页面
推荐用app_links插件,比原生监听更省心。当然你也可以写原生通道,但插件效率更高。
第一步:添加依赖
在pubspec.yaml里添加:
dependencies: app_links: ^3.4.0
第二步:实现监听和路由跳转
import 'package:app_links/app_links.dart'; import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; void main() => runApp(const MyApp()); class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { final AppLinks _appLinks = AppLinks(); late StreamSubscription<Uri> _linkStream; @override void initState() { super.initState(); // 处理应用刚启动时的Deep Link _checkInitialLink(); // 监听应用运行中收到的Deep Link _linkStream = _appLinks.uriLinkStream.listen(_handleDeepLink); } Future<void> _checkInitialLink() async { final initialUri = await _appLinks.getInitialAppLink(); if (initialUri != null) _handleDeepLink(initialUri); } void _handleDeepLink(Uri uri) { // 解析网页传过来的参数 final opType = uri.queryParameters['type']; final orderId = uri.queryParameters['orderId']; // 根据参数跳对应页面 switch (opType) { case 'success': Navigator.pushNamed(context, '/orderDetail', arguments: orderId); break; case 'cancel': Navigator.popUntil(context, ModalRoute.withName('/')); // 返回首页 break; default: // 处理未知参数的情况 break; } } @override void dispose() { _linkStream.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return MaterialApp( initialRoute: '/', routes: { '/': (context) => const HomePage(), '/orderDetail': (context) => OrderDetailPage( orderId: ModalRoute.of(context)?.settings.arguments as String, ), }, ); } } // 示例首页,用url_launcher打开网页 class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('首页')), body: Center( child: ElevatedButton( onPressed: () async { await launchUrl(Uri.parse('https://your-web-url.com/operate')); }, child: const Text('去网页完成操作'), ), ), ); } } // 示例订单详情页 class OrderDetailPage extends StatelessWidget { final String orderId; const OrderDetailPage({super.key, required this.orderId}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('订单详情')), body: Center(child: Text('订单ID:$orderId')), ); } }
测试小技巧
- Android:用adb命令测试Deep Link:
adb shell am start -W -a android.intent.action.VIEW -d "myapp://callback?type=success&orderId=123" com.yourcompany.yourapp - iOS:在Safari里输入你的Deep Link,比如
myapp://callback?type=cancel,就能唤起应用
内容的提问来源于stack exchange,提问作者Nikita Bhoyar
相关产品推荐
相关产品推荐

