Android 应用 A 想要跟踪 Android 应用 B 安装的 Google Play 推荐数据

Posted

技术标签:

【中文标题】Android 应用 A 想要跟踪 Android 应用 B 安装的 Google Play 推荐数据【英文标题】:Android App A wants to track Google Play referral data for Android App B installation 【发布时间】:2012-06-14 17:24:00 【问题描述】:

假设我有一个安装在用户设备中的 android 应用 A,并且我的应用中有一个 AppWidget,我们让其他 Android 开发人员在其中以每次安装成本为基础发布他们的应用促销广告。所以我们需要通过 App A 的推荐来跟踪 App B 是否被安装在用户的设备上。

我们还假设 Android 应用 B 的广告在 Android 应用 A 的小部件上运行,并且我们将应用 A 的用户重定向到应用 B 的用户到 Google Play 的链接包含所有引荐来源数据。 URL 看起来像这样(推荐here -

https://play.google.com/store/apps/details?id=com.joelapenna.foursquared&referrer=utm_source%3Dtooyoou%26utm_medium%3Dbanner%26utm_term%3Dfoursquare%26utm_content%3Dfoursquare-tooyoou%26utm_campaign%3Dfoursquare-android)

如果您在浏览器中点击上述链接或制作二维码并启动它,它将带您到 Google Play 中的 App B 以及所需的推荐数据。现在,当 App B 安装在用户的设备上并首次启动时,App A 期望接收的广播是com.android.vending.INSTALL_REFERRER。如果收到广播并且 utm_source 是 App A 则记录并处理事务。这就是我们的全部目标。

这里是 App A 的 AndroidManifest.xml 代码 sn-p。

<application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:debuggable="true" >
        <activity
            android:name=".LocateMeActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
       <receiver android:name="com.locateme.android.ReferralReceiver" android:exported="true">
      <intent-filter>
        <action android:name="com.android.vending.INSTALL_REFERRER" />
      </intent-filter>
    </receiver> 
    </application>

已添加权限 -

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>

这是应该处理广播的广播接收器类 ReferralReceiver.java。

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;

public class ReferralReceiver extends BroadcastReceiver

    @Override
    public void onReceive(Context context, Intent intent)
    
        // Workaround for Android security issue: http://code.google.com/p/android/issues/detail?id=16006
        try
        
            final Bundle extras = intent.getExtras();
            if (extras != null) 
                extras.containsKey(null);
            
        
        catch (final Exception e) 
            return;
        

        Map<String, String> referralParams = new HashMap<String, String>();

        // Return if this is not the right intent.
        if (! intent.getAction().equals("com.android.vending.INSTALL_REFERRER"))  //$NON-NLS-1$
            return;
        

        String referrer = intent.getStringExtra("referrer"); //$NON-NLS-1$
        if( referrer == null || referrer.length() == 0) 
            return;
        

        try
            // Remove any url encoding
            referrer = URLDecoder.decode(referrer, "x-www-form-urlencoded"); //$NON-NLS-1$
        
        catch (UnsupportedEncodingException e)  return; 

        // Parse the query string, extracting the relevant data
        String[] params = referrer.split("&"); // $NON-NLS-1$
        for (String param : params)
        
            String[] pair = param.split("="); // $NON-NLS-1$
            referralParams.put(pair[0], pair[1]);
        

        ReferralReceiver.storeReferralParams(context, referralParams);
    

    private final static String[] EXPECTED_PARAMETERS = 
        "utm_source",
        "utm_medium",
        "utm_term",
        "utm_content",
        "utm_campaign"
    ;

    private final static String PREFS_FILE_NAME = "ReferralParamsFile";

    public static void storeReferralParams(Context context, Map<String, String> params)
    
        SharedPreferences storage = context.getSharedPreferences(ReferralReceiver.PREFS_FILE_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = storage.edit();

        for(String key : ReferralReceiver.EXPECTED_PARAMETERS)
        
            String value = params.get(key);
            if(value != null)
            
                editor.putString(key, value);
            
        

        editor.commit();
    


    public static Map<String, String> retrieveReferralParams(Context context)
    
        HashMap<String, String> params = new HashMap<String, String>();
        SharedPreferences storage = context.getSharedPreferences(ReferralReceiver.PREFS_FILE_NAME, Context.MODE_PRIVATE);

        for(String key : ReferralReceiver.EXPECTED_PARAMETERS)
        
            String value = storage.getString(key, null);
            if(value != null)
            
                params.put(key, value);
            
        
        return params;
    

调试设备在 Android OS 2.3.4 上

通过应用程序主要活动中的一个简单的 TextView 和 Button,我尝试显示接收者捕获的推荐数据。这是调用和显示-

referraltext.setText(ReferralReceiver.retrieveReferralParams(this.getApplicationContext()).toString());

当我启动上面显示的 App B 的推荐链接时,转到 Google Play,安装它并第一次打开它 logcat 根本不显示广播 com.android.vending.INSTALL_REFERRER,因此显示时推荐数据显示一个空字符串。

同时,当我在同一个广播接收器下方使用 adb 命令时,它会像一个魅力一样工作并显示推荐数据。

am broadcast -a com.android.vending.INSTALL_REFERRER -n com.locateme.android/.ReferralReceiver --es "referrer" "utm_source=tooyoou&utm_medium=banner&utm_term=foursquare&utm_content=foursquare-tooyoou&utm_campaign=foursquare-android"

这是否意味着 Google Play 根本不广播引荐来源网址数据和预期意图?

或者这是否意味着它只为正在安装的 App B 广播意图?

还是我做错了什么?

如果 App B 不必为了向我们做广告而在他们的 App 中插入我们的跟踪 SDK 或代码,这是否可能实现。

非常感谢您的帮助。

附加信息 - 我们没有使用 Google Analytics SDK,因此我们使用的是自定义广播接收器,而不是 Google 的 BR

上面的代码就像一个魅力。我只是在下面标记为正确的答案中遵循了 Lucas 的建议,并将 x-www-form-urlencoded 替换为 UTF-8。为什么我一开始不这样做是因为一家名为 Localytics 的移动分析公司在这里发布了 - http://www.localytics.com/docs/android-market-campaign-analytics/ 他们的代码有同样的问题。所以基本上我现在所拥有的是我在 Google Play 中发布的 Android 应用程序中的上述代码,然后从运行 ICS 的 Android 设备从 Google Play 下载该应用程序,打开它并单击 Retrieve Referral 并且它工作。免费试用,这里是链接 - https://play.google.com/store/apps/details?id=com.locateme.android&referrer=utm_source%3Dtooyoou%26utm_medium%3Dbanner%26utm_term%3Dappdownload%26utm_content%3Dimage%26utm_campaign%3Dtooyooupromo

我想重申的另一件非常重要的事情是,如果您使用网络上的 google play 在您的设备上远程安装应用程序,那么这种方式的 google play 广告系列推荐跟踪将不起作用。我已经对其进行了测试,这是 Google 的一个公开缺陷。

【问题讨论】:

嗨 Aakash,请问您是否使用任何第三方 SDK 进行此跟踪过程,请尽快告诉我 不,实际上你不需要。您只需编写自己的接收器即可捕获 Google Play INSTALL REFERRER 广播并根据需要进行处理。 就我而言,我需要使用上述场景。你能指导我实现这个功能吗? @Aakash:找到您问题的答案:“或者这是否意味着它只为正在安装的 App B 广播意图?”我可以在 A 中接收应用 B 的 INSTALL_REFERRER 广播吗? @aakash,在我的 android 应用程序中,我也需要类似您的要求的东西,我尝试了您的代码,但在 ReferralReceiver 遇到问题。我无法导入此类。您能帮我解决我的问题吗?问题。 【参考方案1】:

上面的源代码不正确。

线

referrer = URLDecoder.decode(referrer, "x-www-form-urlencoded");

应该是

referrer = URLDecoder.decode(referrer, "UTF-8");

android 文档对此并不清楚,但是如果你使用 x-www-form-urlencoded 它将抛出一个不受支持的编码异常......

【讨论】:

【参考方案2】:

您还可以使用第三方跟踪,例如 Tunes 的移动应用跟踪。这将有助于 Android A 应用在安装 Android B 时获得回发。 MAT、Appsflyer 等第三方工具是用于跟踪安装的最常用工具之一。

【讨论】:

以上是关于Android 应用 A 想要跟踪 Android 应用 B 安装的 Google Play 推荐数据的主要内容,如果未能解决你的问题,请参考以下文章

为啥 appcenter 分析没有立即显示跟踪来自 android 应用程序的事件?

Android:如何让用户为其他被跟踪用户创建地理围栏?

Android利用Fiddler进行网络数据抓包怎么跟踪微信请求

(七) 下篇 Android 性能优化 Perfetto 详细介绍

是否可以同时跟踪 Android 和 iOS 应用程序的下载量?

我在 Facebook 中跟踪所有应用安装的应用广告,如何仅从 Facebook 的 ANDROID 线索跟踪应用安装