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

Android 11+如何编程检测应用是否从Google Play安装

Android 11+ 检测应用是否从Google Play安装的可行方案

以下方案均不需要申请QUERY_ALL_PACKAGES等特殊权限,可直接用于非GP渠道安装场景下禁用AdMob广告的需求:

方案1:Google官方Play Install Referrer API(优先推荐,准确率最高)

这是Google Play官方提供的安装来源查询接口,不受Android 11包可见性规则限制,只要设备搭载可用的Google Play服务就能返回准确结果,无额外权限要求。

  • 接入步骤:
    1. 在应用模块的build.gradle中引入官方依赖:
      implementation "com.android.installreferrer:installreferrer:2.2"
    2. 应用启动时异步连接客户端,校验安装来源,核心实现代码(Kotlin):
// 初始化客户端
val referrerClient = InstallReferrerClient.newBuilder(appContext).build()
referrerClient.startConnection(object : InstallReferrerStateListener {
    override fun onInstallReferrerSetupFinished(resultCode: Int) {
        when (resultCode) {
            InstallReferrerResponse.OK -> {
                val referrerData = referrerClient.installReferrer
                // Google Play安装的来源包名固定为com.android.vending
                val isGpInstall = referrerData.installOriginPackage == "com.android.vending"
                if (!isGpInstall) {
                    // 非GP渠道,关闭AdMob广告加载逻辑
                    disableAdLoad()
                }
                referrerClient.endConnection()
            }
            // 设备无可用Play服务、服务不支持的场景,直接按非GP渠道处理
            InstallReferrerResponse.FEATURE_NOT_SUPPORTED,
            InstallReferrerResponse.SERVICE_UNAVAILABLE -> disableAdLoad()
        }
    }
    override fun onInstallReferrerServiceDisconnected() {}
})
  • 该接口返回的是Google Play服务端记录的真实安装来源,第三方渠道、侧载安装的场景要么返回非GP的安装包名,要么无法连接服务,不会出现误判。

方案2:包可见性适配 + PackageManager原生API(轻量无额外依赖)

你之前查到的PackageManager方案失效,核心原因是Android 11引入的包可见性限制:默认情况下应用无法查询其他非核心应用的包信息,直接调用getInstallerPackageName会返回null。只要在清单文件做简单适配,不需要特殊权限就能正常拿到结果:

  1. 在AndroidManifest.xml中添加如下查询声明:
<queries>
    <package android:name="com.android.vending" />
</queries>
  1. 直接调用原生API判断安装来源:
val installerPackage = appContext.packageManager.getInstallerPackageName(appContext.packageName)
val isGpInstall = installerPackage == "com.android.vending"
  • 注意:该方案在部分深度定制的第三方ROM上可能被篡改安装器记录,稳定性弱于方案1,适合不想引入额外依赖的场景使用。

方案3:签名校验兜底(防二次打包、防篡改)

如果需要覆盖第三方渠道二次打包你的应用的场景,可以搭配GP应用签名校验做兜底:在Google Play后台开启Play应用签名功能后,提取GP签发的应用证书哈希值,硬编码在应用内,启动时校验当前运行应用的签名是否匹配,不匹配则直接禁用广告。

  • 核心校验逻辑无额外权限要求,兼容所有Android版本:
@Suppress("DEPRECATION")
fun checkAppSignature(context: Context, validGpHash: String): Boolean {
    val pkgInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        context.packageManager.getPackageInfo(
            context.packageName,
            PackageManager.GET_SIGNING_CERTIFICATES
        )
    } else {
        context.packageManager.getPackageInfo(
            context.packageName,
            PackageManager.GET_SIGNATURES
        )
    }
    val signers = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        pkgInfo.signingInfo.apkContentsSigners
    } else {
        pkgInfo.signatures
    }
    val currentHash = signers.firstOrNull()?.toByteArray()?.let { hashSHA256(it) }
    return currentHash == validGpHash
}

补充说明:Firebase App Check等移动应用证明服务确实不适合该场景,这类服务的核心作用是校验请求是否来自你未被篡改的官方应用,无法区分官方包的具体安装渠道,无法满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:27:22