如何在Flutter中实现Android/iOS端浏览器链接唤起App?
在Flutter中实现浏览器唤起App并生成对应HTML跳转链接
一、配置Flutter App的自定义URL Scheme
要让浏览器能唤起你的App,首先得在Android和iOS平台分别配置自定义URL Scheme(类似myapp://这种自定义协议)。
Android 端配置
打开android/app/src/main/AndroidManifest.xml,给主Activity添加对应的intent-filter,用于识别自定义Scheme:
<activity android:name=".MainActivity" android:exported="true"> <!-- 保留原有配置 --> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <!-- 自定义Scheme,这里用myapp://为例,host可用于区分跳转场景 --> <data android:scheme="myapp" android:host="pay-success" /> </intent-filter> </activity>
iOS 端配置
打开ios/Runner/Info.plist,添加Scheme相关配置:
<key>LSApplicationQueriesSchemes</key> <array> <string>myapp</string> <!-- 允许系统查询你的自定义Scheme --> </array> <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>myapp</string> <!-- 自定义Scheme --> </array> <key>CFBundleURLName</key> <string>com.yourcompany.yourapp</string> <!-- 替换为你的App Bundle ID --> </dict> </array>
二、生成HTML中的唤起链接
在支付成功的网页中,添加用于唤起App的锚点标签。推荐同时处理App未安装的 fallback 逻辑:
基础唤起链接
<a href="myapp://pay-success?orderId=123&status=success">返回我的App</a>
这里的myapp://pay-success对应之前配置的Scheme和host,后面的查询参数可以传递订单ID、支付状态等信息,供App后续处理。
带Fallback的优化版本
如果用户未安装App,直接点击链接会无效,所以可以用JS做降级处理:
<a href="#" onclick="handleBackToApp()">返回我的App</a> <script> function handleBackToApp() { const appLink = 'myapp://pay-success?orderId=123&status=success'; const fallbackUrl = 'https://your-app-download-url.com'; // 替换为你的App下载页 const start = Date.now(); window.location.href = appLink; // 1.5秒后检测是否唤起成功,未成功则跳转到下载页 setTimeout(() => { if (Date.now() - start < 1800) { window.location.href = fallbackUrl; } }, 1500); } </script>
三、Flutter中接收并处理唤起参数
当App被浏览器唤起时,需要解析传递的参数。可以使用app_links包来实现深链接监听:
- 添加依赖到
pubspec.yaml:
dependencies: app_links: ^3.4.0 # 使用最新版本即可
- 在Flutter代码中监听并处理链接:
import 'package:app_links/app_links.dart'; import 'package:flutter/material.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(); Uri? _receivedUri; @override void initState() { super.initState(); _setupDeepLinkListener(); } void _setupDeepLinkListener() async { // 处理App冷启动时的深链接 final initialUri = await _appLinks.getInitialAppLink(); if (initialUri != null) { _handleDeepLink(initialUri); } // 监听App运行时的深链接 _appLinks.uriLinkStream.listen((Uri uri) { _handleDeepLink(uri); }); } void _handleDeepLink(Uri uri) { setState(() { _receivedUri = uri; }); // 解析传递的参数 final orderId = uri.queryParameters['orderId']; final status = uri.queryParameters['status']; if (status == 'success') { // 执行支付成功后的业务逻辑,比如跳转到订单详情页 ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('订单$orderId支付成功!')), ); } } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('支付回调测试')), body: Center( child: _receivedUri != null ? Text('收到跳转链接:${_receivedUri.toString()}') : const Text('等待浏览器唤起'), ), ), ); } }
注意事项
- 自定义Scheme尽量使用唯一值(比如结合公司域名),避免和其他App冲突
- 部分浏览器(如微信内置浏览器)会拦截自定义Scheme,需要做特殊适配或引导用户用系统浏览器打开支付页
- iOS 14+需确保
Info.plist配置正确,否则可能无法唤起App
内容的提问来源于stack exchange,提问作者Ashikul Islam Sawan
相关产品推荐
相关产品推荐

