You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android配置scheme/host intent filter的BroadcastReceiver点击链接不触发怎么办

根本原因

系统浏览器或WebView处理自定义scheme的链接点击时,默认构造的是Intent.ACTION_VIEW类型的Intent,调用startActivity()匹配对应的Intent Filter,不会主动发送广播,因此即便广播接收器配置了相同的data规则,也无法接收到事件。

解决方案

根据HTML的加载场景不同,可选择以下两种实现方案:

场景1:HTML在自有App的WebView中加载

直接在WebView的加载回调中拦截目标scheme链接,手动构造并发送广播:

  1. 给WebView设置自定义WebViewClient,重写url加载拦截方法:
webView.webViewClient = object : WebViewClient() {
    override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
        val uri = request?.url ?: return super.shouldOverrideUrlLoading(view, request)
        // 匹配自定义scheme和host
        if (uri.scheme == "tisseo.main" && uri.host == "login") {
            // 构造显式广播Intent,避免8.0+静态注册广播的隐式匹配限制
            val broadcastIntent = Intent(context, ConnectionReceiver::class.java).apply {
                data = uri
                // 可按需添加extra参数
            }
            context?.sendBroadcast(broadcastIntent)
            // 拦截本次url加载,避免WebView默认处理
            return true
        }
        return super.shouldOverrideUrlLoading(view, request)
    }
}
  1. 若需使用隐式广播,需给广播接收器的Intent Filter添加自定义Action配置:
<receiver
    android:name=".receiver.ConnectionReceiver"
    android:exported="true">
    <intent-filter>
        <!-- 自定义Action,需和发送广播时设置的Action保持一致 -->
        <action android:name="com.yourpackage.action.SCHEME_LOGIN" />
        <category android:name="android.intent.category.DEFAULT" />
        <data
            android:host="login"
            android:scheme="tisseo.main" />
    </intent-filter>
</receiver>

发送广播时对应设置Action即可:

val broadcastIntent = Intent("com.yourpackage.action.SCHEME_LOGIN").apply {
    data = uri
    setPackage(context.packageName) // 8.0+隐式广播需要指定包名才能匹配静态注册接收器
}
context?.sendBroadcast(broadcastIntent)

场景2:HTML在外部系统浏览器中加载

无法直接控制浏览器的行为,可通过透明无界面的中转Activity转接事件:

  1. 新增完全透明的中转Activity,配置原有的scheme Intent Filter:
<activity
    android:name=".SchemeTransferActivity"
    android:exported="true"
    <!-- 配置透明无动画主题,避免用户感知到页面跳转 -->
    android:theme="@style/Theme.Transparent.NoAnimation">
    <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:host="login"
            android:scheme="tisseo.main" />
    </intent-filter>
</activity>
  1. 中转Activity的逻辑实现,接收到Intent后直接转发为广播并销毁自身:
class SchemeTransferActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 无需设置布局
        intent?.data?.let { uri ->
            val broadcastIntent = Intent(this, ConnectionReceiver::class.java).apply {
                data = uri
            }
            sendBroadcast(broadcastIntent)
        }
        finish()
        // 去掉Activity切换动画,避免闪屏
        overridePendingTransition(0, 0)
    }
}
  1. 在res/values/styles.xml中添加透明主题配置:
<style name="Theme.Transparent.NoAnimation" parent="Theme.MaterialComponents.Light.NoActionBar">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowAnimationStyle">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowActionBar">false</item>
    <item name="android:windowContentOverlay">@null</item>
</style>
注意事项
  • Android 8.0及以上系统对静态注册的隐式广播做了限制,优先使用显式广播,或发送隐式广播时调用setPackage()指定应用包名,确保接收器能正常匹配。
  • 若使用全局广播,可按需添加自定义权限,避免信息泄露或被恶意应用拦截。

内容的提问来源于stack exchange,提问作者Kevin ABRIOUX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 03:09:04