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

Flutter/Dart如何判断应用是Google Play的付费版还是免费版?

Android 端一次性购买版本判断方案

针对同一套代码实现免费/付费版的需求,推荐以下几种无需后端、无需登录的方案:

方案1:包名区分(最简单高效)

编译时为免费版和付费版配置不同包名(比如com.yourapp.free和com.yourapp.paid),启动时直接读取当前应用包名判断:

val packageName = context.packageName
val isPaidVersion = packageName == "com.yourapp.paid"
  • 优势:零网络请求,启动速度快,实现成本极低
  • 注意:需在Google Play后台分别上传两个包名的应用版本

方案2:Install Referrer API验证购买来源

一次性付费版的用户从Play Store付费商品页下载,可通过Install Referrer API获取安装来源参数判断:

  1. 添加依赖:
implementation "com.android.installreferrer:installreferrer:2.2"
  1. 核心代码:
val referrerClient = InstallReferrerClient.newBuilder(context).build()
referrerClient.startConnection(object : InstallReferrerStateListener {
    override fun onInstallReferrerSetupFinished(responseCode: Int) {
        when (responseCode) {
            InstallReferrerClient.InstallReferrerResponse.OK -> {
                val referrer = referrerClient.installReferrer.installReferrer
                // 付费版的安装来源会包含Google Play配置的付费标识,比如"utm_medium=paid"
                val isPaidVersion = referrer.contains("utm_medium=paid")
                referrerClient.endConnection()
            }
            // 处理服务连接失败等异常情况
        }
    }
    override fun onInstallReferrerServiceDisconnected() {
        // 可添加重试逻辑
    }
})
  • 优势:无需维护多个包名,依赖Play官方服务可靠性高
  • 注意:需确保付费版商品链接配置了正确的UTM参数

方案3:签名信息验证

为免费/付费版配置不同签名密钥,启动时读取应用签名哈希值对比:

fun isPaidVersion(context: Context): Boolean {
    val packageInfo = context.packageManager.getPackageInfo(
        context.packageName,
        PackageManager.GET_SIGNATURES
    )
    val paidSignatureHash = "你的付费版签名哈希值"
    return packageInfo.signatures.any { 
        it.toCharsString().hashCode().toString() == paidSignatureHash 
    }
}
  • 优势:无需网络,安全性高,避免包名被篡改的风险
  • 注意:需妥善保管两个签名密钥,避免丢失

iOS 端方案验证与修正建议

你提到的verifyReceipt接口方案仅适用于应用内购场景,对一次性购买的付费应用不适用,具体问题和修正方案如下:

原方案问题点

  1. 一次性购买的付费应用与免费应用的收据in_app列表均为空,无法通过该字段区分版本
  2. verifyReceipt接口要求POST请求(而非GET),且正式环境需使用https://buy.itunes.apple.com/verifyReceipt,沙箱地址仅用于内购测试

正确的iOS一次性购买版本区分方案

和Android一致,通过Bundle ID区分是最可靠的方式:
编译时为两个版本配置不同Bundle ID(比如com.yourapp.free和com.yourapp.paid),启动时读取判断:

let bundleId = Bundle.main.bundleIdentifier
let isPaidVersion = bundleId == "com.yourapp.paid"

通用建议

无论Android还是iOS,推荐使用**构建变体(Build Variants)**实现同一代码多版本:

  • Android:在Gradle中配置productFlavors,自动替换包名、资源、编译参数
  • iOS:在Xcode中配置Target和Scheme,实现版本差异化编译

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 18:42:36