React Native安卓端Waze导航链接失效问题及解决方案咨询
解决方案
问题根源
安卓端你使用的google.navigation:q=...是Google Maps专属协议,Waze并不识别该格式,因此只会启动APP而无法触发导航。同时React Native的Linking.openURL无法获取系统应用选择弹窗的用户选择结果,所以需要换一种方式处理。
最优实现方式
1. 适配Waze的URL Scheme
Waze支持的导航URL格式(安卓/iOS通用):
waze://?ll={纬度},{经度}&navigate=yes
若需指定起点,可追加from={起点纬度},{起点经度}参数。
2. 自定义应用选择弹窗(推荐)
放弃系统默认选择弹窗,自行实现选择界面让用户明确选择Google Maps或Waze,再根据选择打开对应协议的URL,精准控制每个应用的导航链接。
修改后的代码示例:
import { useCallback, useState } from 'react'; import { Linking, Alert } from 'react-native'; import { isIos } from '@core/constants'; import { useLocationTools } from '@hooks/location'; type LanLon = number | string; interface SitePoint { site_latitude?: LanLon; site_longitude?: LanLon; } export default function useDirectionsRedirect({ data }: { data?: SitePoint }) { const { userPosition } = useLocationTools(true); // 检查应用是否安装 const checkAppInstalled = async (url: string) => { try { return await Linking.canOpenURL(url); } catch (err) { return false; } }; return useCallback(async () => { const startPoint = { latitude: userPosition?.coords?.latitude, longitude: userPosition?.coords?.longitude, }; const finishPoint = { latitude: data?.site_latitude, longitude: data?.site_longitude }; if (!finishPoint.latitude || !finishPoint.longitude) { console.error('目的地坐标缺失'); return; } if (isIos) { // iOS端用通用maps链接,系统自动唤起选择器且支持Waze const start = userPosition ? `saddr=${startPoint.latitude}+${startPoint.longitude}&` : ''; const finish = `daddr=${finishPoint.latitude}+${finishPoint.longitude}`; const link = `maps://app?${start}${finish}`; if (await checkAppInstalled(link)) { await Linking.openURL(link).catch(console.error); } } else { // 安卓端检测已安装的导航应用 const googleMapsUrl = `google.navigation:q=${finishPoint.latitude}+${finishPoint.longitude}`; const wazeUrl = `waze://?ll=${finishPoint.latitude},${finishPoint.longitude}&navigate=yes`; const hasGoogleMaps = await checkAppInstalled(googleMapsUrl); const hasWaze = await checkAppInstalled(wazeUrl); const options = []; if (hasGoogleMaps) options.push('Google Maps'); if (hasWaze) options.push('Waze'); if (options.length === 0) { Alert.alert('提示', '未安装任何导航应用'); return; } // 自定义选择弹窗 Alert.alert( '选择导航应用', '', options.map(app => ({ text: app, onPress: async () => { const url = app === 'Google Maps' ? googleMapsUrl : wazeUrl; await Linking.openURL(url).catch(console.error); } })) ); } }, [data, userPosition]); }
3. 安卓Manifest配置(必要)
Android 11+需在android/app/src/main/AndroidManifest.xml中添加queries,否则无法检测应用是否安装:
<queries> <!-- Google Maps --> <package android:name="com.google.android.apps.maps" /> <!-- Waze --> <package android:name="com.waze" /> </queries>
补充说明
- iOS端的
maps://协议会自动唤起系统应用选择器,且Waze能正确识别daddr参数,无需额外处理。 - 自定义选择弹窗可完全控制每个应用的导航参数,避免系统选择器带来的协议兼容问题。
内容的提问来源于stack exchange,提问作者HugoTek
相关产品推荐
相关产品推荐

