Android:通过DeepLink唤起应用时如何获取调用应用名称
获取唤起Activity的调用应用名称(适配API33+)
针对API33中getReferrer()返回null的问题,以下是几个可靠的替代方案:
1. 使用Jetpack兼容方法获取Referrer
优先使用androidx.core.content.ContextCompat.getReferrer(Context),这个方法内部会自动适配不同API版本的实现逻辑,能在API33+环境下正确获取启动来源的Referrer信息(只要调用方遵循系统规范传递了Referrer)。
示例代码:
// 在Activity的onCreate()中调用 val referrer = ContextCompat.getReferrer(this) referrer?.let { uri -> val callingPackage = uri.host callingPackage?.let { pkg -> val pm = packageManager try { val appInfo = pm.getApplicationInfo(pkg, 0) val appName = pm.getApplicationLabel(appInfo).toString() // 这里拿到了调用应用的名称 } catch (e: PackageManager.NameNotFoundException) { // 处理包名不存在的异常 } } }
2. 处理显式Intent启动的场景
如果调用方是通过显式Intent直接启动你的Activity,getReferrer()可能返回null,这时候可以尝试从Intent的额外参数或Sender信息中获取:
// 尝试从EXTRA_REFERRER_NAME获取包名 val callingPackage = intent.getStringExtra(Intent.EXTRA_REFERRER_NAME) if (callingPackage != null) { // 同上,通过PackageManager获取应用名称 } else { // 尝试从Intent的Sender解析包名 val sender = intent.sender if (sender is ComponentName) { val pkg = sender.packageName // 同上,获取应用名称 } }
3. 权限声明注意事项
在API33+,要查询其他应用的信息,需要在AndroidManifest.xml中添加对应声明:
- 如需查询所有应用,添加全权限:
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:ignore="QueryAllPackagesPermission" />
- 更合规的方式是仅声明需要查询的特定包:
<queries> <package android:name="com.example.targetapp" /> <!-- 添加你需要支持的调用方包名 --> </queries>
关于getCallingPackage()和getCallingActivity()的说明
这两个方法仅适用于**通过startActivityForResult()启动、调用方与被调用方处于不同进程且未设置FLAG_ACTIVITY_NEW_TASK**的特殊场景,普通启动流程下它们只会返回当前包名,不适合作为通用方案。
内容的提问来源于stack exchange,提问作者FurElise
相关产品推荐
相关产品推荐

