12

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

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

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 代码片段。

<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 的一个公开缺陷。

4

2 回答 2

7

上面的源代码不正确。

线

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

应该

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

android 文档对此并不清楚,但如果您使用 x-www-form-urlencoded 它将引发不受支持的编码异常......

于 2012-07-20T21:15:37.417 回答
0

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

于 2016-03-08T04:10:30.700 回答