React Native Expo 安卓深链接配置指定路径却异常唤起域名全URL(三星多发)
安卓应用迁移至Expo后深链接全域名唤起问题
我们将原生Android应用迁移为React Native应用,新应用采用Expo托管工作流,深链接配置参考Expo官方Linking文档规范,上线初期功能运行完全正常。近期排查发现,部分安卓用户(尤其三星设备)的应用会唤起配置域名下的所有URL,而非仅命中已配置的路径规则。即便将Expo项目导出为裸工作流,上述问题仍然存在。
现有配置说明
Expo项目内的Intent Filters配置
{ "expo": { "android": { "intentFilters": [ { "action": "VIEW", "data": [ { "scheme": "https", "host": "*.domain.com", "pathPrefix": "/jobs" }, { "scheme": "https", "host": "*.domain.com", "pathPrefix": "/can/recommended-jobs" }, { "scheme": "https", "host": "*.domain.com", "pathPrefix": "/can/cv-views" }, { "scheme": "https", "host": "*.domain.com", "pathPrefix": "/can/conversations" }, { "scheme": "https", "host": "*.domain.com", "pathPrefix": "/can/profile/basic-info" }, { "scheme": "https", "host": "*.domain.com", "pathPattern": "/.*/jobs/.*-.*" }, { "scheme": "https", "host": "*.domain.com", "pathPrefix": "/mobile/can/profile" }, { "scheme": "https", "host": "*.domain.com", "pathPrefix": "/mobile/can/cv-views" }, { "scheme": "https", "host": "*.domain.com", "pathPrefix": "/mobile/" }, { "scheme": "https", "host": "*.domain.com", "pathPrefix": "/mobile/jobs/country" }, { "scheme": "https", "host": "*.domain.com", "pathPattern": "/mobile/jobs-in-.*/.*/.*" } ], "category": ["BROWSABLE", "DEFAULT"] } ] } } }
导出后生成的Android Manifest文件片段
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.android.dev"> <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:requestLegacyExternalStorage="true"> <meta-data android:name="expo.modules.updates.EXPO_SDK_VERSION" android:value="41.0.0"/> <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </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"/> <data android:scheme="com.company"/> <data android:scheme="com.company.android.dev"/> </intent-filter> <intent-filter> <data android:scheme="https" android:host="*.domain.com" android:pathPrefix="/jobs"/> <data android:scheme="https" android:host="*.domain.com" android:pathPrefix="/can/recommended-jobs"/> <data android:scheme="https" android:host="*.domain.com" android:pathPrefix="/can/cv-views"/> <data android:scheme="https" android:host="*.domain.com" android:pathPrefix="/can/conversations"/> <data android:scheme="https" android:host="*.domain.com" android:pathPrefix="/can/profile/basic-info"/> <data android:scheme="https" android:host="*.domain.com" android:pathPattern="/.*/jobs/.*-.*"/> <data android:scheme="https" android:host="*.domain.com" android:pathPrefix="/mobile/can/profile"/> <data android:scheme="https" android:host="*.domain.com" android:pathPrefix="/mobile/can/cv-views"/> <data android:scheme="https" android:host="*.domain.com" android:pathPrefix="/mobile/"/> <data android:scheme="https" android:host="*.domain.com" android:pathPrefix="/mobile/jobs/country"/> <data android:scheme="https" android:host="*.domain.com" android:pathPattern="/mobile/jobs-in-.*/.*/.*"/> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> </intent-filter> </activity> </application> </manifest>
导出的Manifest存在层级语法错误:MainActivity标签闭合后,额外悬空挂载了一个未配置任何
data匹配规则的VIEW类型intent-filter,且文件尾部存在无对应开标签的</activity>闭合标记。
问题原因与修复方案
- 核心原因:悬空的无
data约束的intent-filter符合安卓隐式匹配规则——只要声明了VIEW动作、DEFAULT和BROWSABLE类别,即使没有配置任何匹配数据,也会拦截同类型的唤起请求,完全跳过对scheme、host、path的校验。三星定制ROM的intent解析逻辑比原生安卓更宽松,会优先命中这个无约束规则,导致应用被配置域名下的所有URL唤起,不会走预设的路径匹配逻辑。 - 修复操作:
- 修正Manifest层级语法错误:删除悬空的无
data规则的intent-filter标签,删除多余的</activity>闭合标记,保证所有intent-filter都归属在MainActivity标签内部。 - 拆分合并的intent-filter配置:将原本写在同一intent-filter节点下的多组path规则,拆分为独立的intent-filter节点。安卓系统对同一节点下的多组data标签采用“任意匹配即命中”的逻辑,多规则合并时部分定制ROM会忽略path校验,直接识别为对整个host域生效。
- 校验导出的Manifest文件:确认所有
VIEW类型、带httpsscheme的intent-filter都完整配置了host、path规则,不存在遗漏data标签的同类intent-filter。
- 修正Manifest层级语法错误:删除悬空的无
内容的提问来源于stack exchange,提问作者Waqas Shahzad
相关产品推荐
相关产品推荐

