Flutter中如何从应用商店URL获取参数?
Flutter 从唤起URL中获取参数
针对你提到的通过https://apps.apple.com/app/id16385122342?param1=1¶m2=2这类URL唤起App并获取参数的需求,分平台配置+Flutter端处理的步骤如下:
一、iOS端配置与处理
1. 开启Universal Links
要让App能被HTTPS链接唤起,需配置Universal Links:
- 在Xcode中,选中你的target → 「Signing & Capabilities」→ 添加「Associated Domains」,填入
applinks:apps.apple.com(如果是自定义域名,替换为你的域名)。 - 在域名根目录或
.well-known目录上传apple-app-site-association文件,格式示例:{ "applinks": { "apps": [], "details": [ { "appID": "TeamID.BundleID", "paths": ["/app/id16385122342*"] } ] } }
2. AppDelegate处理回调
修改AppDelegate.swift,解析URL参数并传给Flutter:
import UIKit import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void ) -> Bool { guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL else { return super.application(application, continue: userActivity, restorationHandler: restorationHandler) } // 解析URL参数 let components = URLComponents(url: url, resolvingAgainstBaseURL: false) let params = components?.queryItems?.reduce(into: [String: String?]()) { result, item in result[item.name] = item.value } ?? [:] // 通过MethodChannel传递参数给Flutter let controller = window?.rootViewController as! FlutterViewController let channel = FlutterMethodChannel(name: "app_url_channel", binaryMessenger: controller.binaryMessenger) channel.invokeMethod("handleUrlParams", arguments: params) return super.application(application, continue: userActivity, restorationHandler: restorationHandler) } }
二、Android端配置与处理
1. 配置Intent Filter
修改AndroidManifest.xml,添加能捕获目标URL的intent-filter:
<activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <!-- 处理HTTPS唤起链接 --> <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="https" android:host="apps.apple.com" android:pathPrefix="/app/id16385122342"/> </intent-filter> </activity>
2. MainActivity处理回调
修改MainActivity.kt,处理初始唤起和后台唤起的参数:
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel import android.content.Intent import android.net.Uri class MainActivity: FlutterActivity() { private val CHANNEL = "app_url_channel" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> if (call.method == "getInitialUrlParams") { val params = mutableMapOf<String, String?>() intent.data?.let { uri -> uri.queryParameterNames.forEach { name -> params[name] = uri.getQueryParameter(name) } } result.success(params) } } } override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) setIntent(intent) // 处理后台唤起的参数 val params = mutableMapOf<String, String?>() intent.data?.let { uri -> uri.queryParameterNames.forEach { name -> params[name] = uri.getQueryParameter(name) } } MethodChannel(flutterEngine?.dartExecutor?.binaryMessenger, CHANNEL) .invokeMethod("handleUrlParams", params) } }
三、Flutter端接收参数
通过MethodChannel接收原生传递的参数,处理初始参数和后续唤起的参数:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() => runApp(const MyApp()); class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { static const _channel = MethodChannel('app_url_channel'); Map<String, String?>? _urlParams; @override void initState() { super.initState(); _fetchInitialParams(); // 监听后台唤起的参数 _channel.setMethodCallHandler((call) async { if (call.method == 'handleUrlParams') { setState(() { _urlParams = Map<String, String?>.from(call.arguments); }); } }); } Future<void> _fetchInitialParams() async { try { final dynamic params = await _channel.invokeMethod('getInitialUrlParams'); setState(() { _urlParams = params?.map((key, value) => MapEntry(key.toString(), value?.toString())); }); } on PlatformException catch (e) { print('获取初始参数失败: ${e.message}'); } } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('URL参数展示')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('param1: ${_urlParams?['param1'] ?? '未获取到'}'), const SizedBox(height: 16), Text('param2: ${_urlParams?['param2'] ?? '未获取到'}'), ], ), ), ), ); } }
注意事项
- iOS的Universal Links需要确保
apple-app-site-association文件能被苹果服务器访问到,可通过苹果官方验证工具检查。 - Android测试时,需在真实设备上操作,部分模拟器可能无法正确处理HTTPS唤起。
- 如果是自定义URL Scheme(如
myapp://),只需修改对应平台的scheme配置即可,参数解析逻辑一致。
内容的提问来源于stack exchange,提问作者huon sokly
相关产品推荐
相关产品推荐

