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

如何实现Flutter应用的安装追踪及来源上报功能?

WhatsApp分享安装来源与渠道追踪方案

核心逻辑

通过带归因参数的深度链接标记分享来源,结合应用商店的分发渠道检测,在用户首次启动应用时上报数据。

分步实现

1. 生成带参数的分享链接

用户在WhatsApp分享时,生成包含来源标识的深度链接,比如:
yourapp://track?source=whatsapp
(渠道信息无需提前硬编码,可在用户安装后通过系统API获取)

2. 捕获深度链接参数并存储

Android端

  • 先在AndroidManifest.xml中配置Intent Filter,让应用能捕获自定义链接:
    <activity android:name=".MainActivity">
        <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:scheme="yourapp" android:host="track" />
        </intent-filter>
    </activity>
    
  • 应用启动时解析链接参数,存入SharedPreferences:
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        intent.data?.let { uri ->
            val source = uri.getQueryParameter("source")
            source?.let {
                getSharedPreferences("install_track", MODE_PRIVATE)
                    .edit()
                    .putString("install_source", it)
                    .apply()
            }
        }
        // 同时调用Install Referrer API获取商店渠道
        getStoreChannel()
    }
    
    private fun getStoreChannel() {
        val referrerClient = InstallReferrerClient.newInstance(this)
        referrerClient.startConnection(object : InstallReferrerStateListener {
            override fun onInstallReferrerSetupFinished(responseCode: Int) {
                if (responseCode == InstallReferrerClient.InstallReferrerResponse.OK) {
                    val referrer = referrerClient.installReferrer.installReferrer
                    val channel = if (referrer.contains("googleplay")) "Google Play" else "未知渠道"
                    getSharedPreferences("install_track", MODE_PRIVATE)
                        .edit()
                        .putString("store_channel", channel)
                        .apply()
                    // 触发上报
                    reportToAPI()
                }
                referrerClient.endConnection()
            }
            override fun onInstallReferrerServiceDisconnected() {
                // 重试逻辑或标记渠道为未知后上报
                reportToAPI()
            }
        })
    }
    

iOS端

  • 在Info.plist配置Custom URL Scheme(或用Universal Links提升稳定性):
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>yourapp</string>
            </array>
        </dict>
    </array>
    
  • 处理链接跳转并存储参数:
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
              let source = components.queryItems?.first(where: { $0.name == "source" })?.value else {
            return false
        }
        UserDefaults.standard.set(source, forKey: "install_source")
        // 获取渠道并触发上报
        getStoreChannelAndReport()
        return true
    }
    
    private func getStoreChannelAndReport() {
        var channel = "未知渠道"
        if let receiptURL = Bundle.main.appStoreReceiptURL, receiptURL.lastPathComponent == "sandboxReceipt" {
            channel = "App Store(沙盒)"
        } else if Bundle.main.bundleIdentifier == "com.apple.testflight" {
            channel = "TestFlight"
        } else {
            channel = "App Store"
        }
        UserDefaults.standard.set(channel, forKey: "store_channel")
        reportToAPI()
    }
    

3. 上报数据到API

首次启动时读取存储的参数,发起请求到你的服务器:

// Android上报示例
private fun reportToAPI() {
    val sp = getSharedPreferences("install_track", MODE_PRIVATE)
    val source = sp.getString("install_source", "unknown")
    val channel = sp.getString("store_channel", "unknown")

    val requestBody = JSONObject().apply {
        put("install_source", source)
        put("store_channel", channel)
    }

    // 用OkHttp发起POST请求示例
    val client = OkHttpClient()
    val mediaType = MediaType.parse("application/json")
    val body = RequestBody.create(mediaType, requestBody.toString())
    val request = Request.Builder()
        .url("你的API接口地址")
        .post(body)
        .build()
    client.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) { /* 失败重试逻辑 */ }
        override fun onResponse(call: Call, response: Response) { /* 处理响应结果 */ }
    })
}

注意事项

  • WhatsApp可能对长链接转码,建议用内部短链接服务压缩,避免参数丢失
  • 若用户直接从商店搜索安装,install_source会显示为unknown,正常上报即可
  • Android需添加Install Referrer API依赖:implementation 'com.android.installreferrer:installreferrer:2.2'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 02:50:20