You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android SDK下如何确保隐式Intent广播仅定向至应用A

确保特定Scheme隐式Intent仅传递给应用A的可行方案

嘿,这个问题在Android应用间通信里挺常见的——默认情况下,你没法绝对保证test://something这类scheme的隐式Intent只传给应用A,如果有其他应用也注册了完全匹配的Intent过滤器,系统会弹出应用选择器让用户挑。但咱们有几个靠谱的办法,能最大化甚至100%确保只有应用A能响应这个Intent:

1. 直接指定应用A的包名(最稳妥的半显式Intent)

如果你的应用B明确知道应用A的包名,直接在发送Intent时指定包名就完事了,系统会跳过匹配流程,直接把Intent发给对应包名的应用:

// 应用B中发送Intent的代码示例(Kotlin)
val launchIntent = Intent(Intent.ACTION_VIEW).apply {
    data = Uri.parse("test://something")
    setPackage("com.yourcompany.appa") // 替换成应用A的实际包名
}
startActivity(launchIntent)

这个方法简单粗暴且有效,只要应用A已经安装,Intent就只会到它手里。要是应用A没装,系统会抛出ActivityNotFoundException,你可以捕获这个异常给用户提示(比如引导下载应用A)。

2. 用自定义签名权限做限制

如果需要更严格的权限管控,防止其他恶意应用注册相同scheme来抢Intent,你可以给应用A的目标Activity加自定义权限,而且把权限的保护级别设为signature——只有和应用A用相同签名的应用(比如你的应用B)才能持有这个权限:

步骤1:在应用A的Manifest里定义自定义权限

<permission
    android:name="com.yourcompany.appa.ACCESS_PERMISSION"
    android:protectionLevel="signature" />

步骤2:给应用A的目标Activity添加权限限制

<activity android:name=".TargetActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="test" android:host="something" />
    </intent-filter>
    <!-- 加上权限过滤,只有持有对应权限的应用能触发这个Activity -->
    <intent-filter android:permission="com.yourcompany.appa.ACCESS_PERMISSION">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="test" android:host="something" />
    </intent-filter>
</activity>

步骤3:在应用B的Manifest里声明使用该权限

<uses-permission android:name="com.yourcompany.appa.ACCESS_PERMISSION" />

这样一来,就算其他应用注册了相同的scheme过滤器,因为没有这个签名权限,系统也不会把Intent传给它们,只有应用A能响应。

3. 配置App Links(适合公共场景)

如果你的scheme是面向用户的公共链接(比如自定义scheme对应你的域名),可以用Android 6.0+推出的App Links功能,通过数字资产链接验证来让系统默认把该scheme的Intent交给应用A,不会弹出选择器:

步骤1:给应用A的Intent过滤器加上autoVerify属性

<activity android:name=".TargetActivity">
    <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="test" android:host="something" />
    </intent-filter>
</activity>

步骤2:在对应域名的服务器上放置数字资产链接文件

你需要在https://something/.well-known/assetlinks.json路径下放置验证文件,证明应用A的签名和该域名关联。系统会自动验证,验证通过后就会默认把test://something的Intent交给应用A。

不过这个方法需要你控制对应的域名,而且自定义scheme的autoVerify支持在部分Android版本上有差异,更适合面向普通用户的公共应用,内部应用间通信还是前两种方法更靠谱。

总结一下

  • 要是你同时控制应用A和B,直接指定包名是最简单高效的方案,能100%确保Intent精准传递。
  • 要是需要防止其他应用恶意响应,自定义签名权限是最佳选择,安全性拉满。
  • App Links适合公共场景,但内部通信没必要折腾这个。

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

火山引擎 最新活动