如何在Flutter中实现应用出现在WhatsApp共享位置的打开选项中?
要让你的Flutter打车应用出现在WhatsApp位置分享的打开选项中,需要分别配置Android和iOS的原生配置文件,并在Flutter端处理传入的地理位置参数,具体实现如下:
Android 端配置
修改android/app/src/main/AndroidManifest.xml,在主Activity标签内添加对应的<intent-filter>,让应用能响应geo协议的位置请求:
<activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> <!-- 原有配置保持不变 --> <!-- 添加以下intent-filter --> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <!-- 响应geo协议的位置链接 --> <data android:scheme="geo" /> </intent-filter> </activity>
该配置会让系统识别你的应用可处理geo://开头的位置URI,当WhatsApp触发位置打开请求时,应用会出现在选项列表中。
iOS 端配置
修改ios/Runner/Info.plist,添加URL Scheme以支持geo协议:
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>geo</string> </array> </dict> </array>
同时,在AppDelegate.swift中添加链接处理逻辑,将外部URL传递给Flutter端:
import UIKit import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:] ) -> Bool { let controller = window?.rootViewController as! FlutterViewController let channel = FlutterMethodChannel(name: "com.yourapp/location_link", binaryMessenger: controller.binaryMessenger) channel.invokeMethod("handleGeoLink", arguments: url.absoluteString) return true } }
Flutter 端处理
使用uni_links插件监听并解析传入的geo链接,提取地理位置坐标:
- 添加依赖到
pubspec.yaml:
dependencies: flutter: sdk: flutter uni_links: ^0.5.1 # 使用最新版本
- 在Flutter页面实现链接监听与解析:
import 'package:flutter/material.dart'; import 'package:uni_links/uni_links.dart'; class RideRequestPage extends StatefulWidget { const RideRequestPage({super.key}); @override State<RideRequestPage> createState() => _RideRequestPageState(); } class _RideRequestPageState extends State<RideRequestPage> { double? _latitude; double? _longitude; @override void initState() { super.initState(); _initGeoLinkListener(); } Future<void> _initGeoLinkListener() async { // 处理应用启动时传入的链接 final Uri? initialUri = await getInitialUri(); if (initialUri != null) { _parseGeoUri(initialUri); } // 监听后续传入的链接 uriLinkStream.listen((Uri? uri) { if (uri != null) { _parseGeoUri(uri); } }); } void _parseGeoUri(Uri uri) { // 解析geo URI格式,例如:geo:12.9716,77.5946 final String path = uri.path; final List<String> coords = path.split(','); if (coords.length == 2) { setState(() { _latitude = double.parse(coords[0]); _longitude = double.parse(coords[1]); }); // 跳转到打车请求页面,传入解析后的坐标 _navigateToRideRequest(_latitude!, _longitude!); } } void _navigateToRideRequest(double lat, double lng) { Navigator.push( context, MaterialPageRoute( builder: (context) => RideBookingPage(latitude: lat, longitude: lng), ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("打车应用")), body: Center( child: _latitude != null && _longitude != null ? Text("收到位置:${_latitude!}, ${_longitude!}") : const Text("等待位置链接"), ), ); } } // 示例打车预订页面 class RideBookingPage extends StatelessWidget { final double latitude; final double longitude; const RideBookingPage({super.key, required this.latitude, required this.longitude}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("发起打车请求")), body: Center( child: Text("目的地坐标:$latitude, $longitude"), ), ); } }
注意事项
- 测试时可手动构造
geo:纬度,经度格式的链接,验证应用是否能被唤起。 - Android 12+需确保
android:exported="true",否则intent-filter不会生效。 - iOS若使用SceneDelegate,需在
scene(_:openURLContexts:)方法中处理链接,逻辑与AppDelegate一致。
内容的提问来源于stack exchange,提问作者Rahul Chauhan
相关产品推荐
相关产品推荐

