com.android.vending.INSTALL_REFERRER isn't working

12,178

Solution 1

So xbakesx says that it seems to work if his receiver extends com.google.analytics.tracking.android.AnalyticsReceiver.

I think the key is that the intent has permissions for ...AnalyticsReceiver and so no other class that is not extending it can pick up the intent. If you look at their test broadcast https://developers.google.com/analytics/solutions/testing-play-campaigns it does appear specific for that class.

If you change that test broadcast so that your class replaces com.google.analytics.tracking.android.AnalyticsReceiver you can then receive it. The biggest problem is they seemed to have locked down this class in beta 4 or 5. If anyone has a link to beta 3 we could test this, or if xbakex could confirm with playing around with the new jars that would rock!

Update:

BAM! So permissions are not an issue. I created a test project and used the PlayStores alpha testing to test out referrer links, which you can build here: https://developers.google.com/analytics/devguides/collection/android/v2/campaigns.

The cool thing is you don't need any GA jar at all! Checkout my test project here: https://github.com/twotoasters/AnalyticsTest/ This project also shows you how to parse the link to get all of the information that you need.

Solution 2

After many failed attempts i could finally see the passed referral parameters in logcat.

Along the way, i figured out a few things, i am not too sure if i am doing it rite or wrong, but for some reasons, these worked. If someones still stuck, they can get some pointers from my learnings.

A. creating a custom BroadcastReceiver where you can ready the intent. (this will executed, only once you have successfully fired the Install_referrer intent from the ADB for testing). Also make sure, if you need to do a post back of the referrer information to a server, it will have to be on a separate thread.

    public class CustomBR extends BroadcastReceiver {

    private static final String D_TAG = "BR";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(D_TAG, "CustomReceiver onReceive (context, intent)");
        try {

            String referrer = intent.getStringExtra("referrer");
            // pass the referrer string to another singleton class to post it to server
            HandleServerComm.getInstance().postData(referrer);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

B. update the androidmanifest.xml file to reflect the custom receiver you have created

    <receiver android:exported="true" android:name="com.example.myapp.CustomBR" android:enabled="true">
        <intent-filter>
            <action android:name="com.android.vending.INSTALL_REFERRER" />
        </intent-filter>
    </receiver>

C. make sure you have adb installed correctly to test this on local environment. you will also need a device to be connected via USB with remote debugging enabled.

D. run the adb shell command to remotely broadcast a install_referrer on the device and pass it parameters.

The command is

adb shell am broadcast -a com.android.vending.INSTALL_REFERRER -n com.example.myapp/.CustomBR --es  "token" "sample_token" --es  "source" "banner"

Note that the important parts of this command is com.example.myapp/.CustomBR and --es "token" "sample_token" where --es is the additional parameters that are being sent along with the intent. the first quote after --es is the querystring / parameter name and the second quote is the value. Similarly, if you have to add more than one value, replicate it as shown in the example above.

E. Finally the most important part that kept me frustrated all the while - the app installed on the device itself. Your app should be installed on the device but not running at all. To do this, you will have to "Force Close" the app and then fire the adb shell command to fire up the install_referrer. thats when, you should see the logcat light up with required data.

F. You might also want to uninstall the update on google play store app and restore it to factory settings. at times (not confirmed) the version of google play determines what data is being passed to the app via the install_referrer or if the referrer is called at all.

Hope this helps someone.

Solution 3

Registering a BroadcastReceiver in your app's AndroidManifest.xml with an intent filter is the correct solution to app install referrals whether using Google Analytics or not.

<receiver
    android:exported="true"
    android:name="com.yourcompany.package.receivers.InstallReceiver">
    <intent-filter>
        <action android:name="com.android.vending.INSTALL_REFERRER" />
    </intent-filter>
</receiver>

If you're already using Google Analytics you simply specify android:name="com.google.android.gms.analytics.CampaignTrackingReceiver" for your receiver and the following service as well. Both are included in the Google Play services client library so there isn't any Java code to write. If you haven't already, you will also have to go through the initial setup instructions for Google Analytics for your App.

 <service android:name="com.google.android.gms.analytics.CampaignTrackingService" />

If you're not using Google Analytics then you'll need to define your own BroadcastReceiver in your java code. You will want it to inspect the extras on the received intent when implementing onReceive.

The referrer parameter in the URL that is received by Google Play (the store) is the only parameter passed through to the Android app for the referral so it's very common to encode a few parameters within it. For Google Analytics that means industry standard utm_* parameters, but you can use others. Here's the test adb command I typically use for opening Google Play to install and test the full flow.

adb shell "am start -a android.intent.action.VIEW -d \"https://play.google.com/store/apps/details?id=com.somecompany.package&referrer=utm_source%253Dtest_campaign_source%2526utm_medium%253Dtest_campaign_medium%2526utm_term%253Dtest_campaign_term%2526utm_content%253Dtest_campaign_content%2526utm_campaign%253Dtest_campaign_name\""

Testing Notes:

  • When testing this flow it's very important to check that the above command resulted in an output where the Intent was logged to your console with the FULL referrer information still attached. It's very easy for the escaping to be incorrect and silently drop the referrer.
  • Remember that the APK must have been installed by Google Play (the Store) on to the device you're testing on (you can't side-load). Therefore, you usually need to use your Alpha distribution channel in Google Play to test this.
  • It's important to note that if the device is >= Honeycomb MR1 the INSTALL_REFERRER intent is broadcast after the App is first launched rather than after the app is installed.
  • You will need to reinstall your app every time you need to test the referrer flow.
  • Install referrals are tracked when the app is installed from the Android Google Play app, but not the web version of the store.
Share:
12,178
xbakesx
Author by

xbakesx

I write software in Java (and Android) and PHP, javascript and whatever else needs to happen. Mostly I solve problems. Please don't judge me based on my website... it's been neglected for awhile now.

Updated on July 20, 2022

Comments

  • xbakesx
    xbakesx almost 2 years

    I originally asked this question, about passing parameters through a market link into my app on install.

    Everyone seems to be saying to create a BroadcastListener with the intent-filter action of com.android.vending.INSTALL_REFERRER. All the documentation on that seems to imply this is a capability of Google Analytics (the documentation is in v1, but I can only download v2 SDK at this point... so that's what I am using). I can't get these links to pass data through. I have my full manifest and my broadcast listener. I have included Google Analytics just in case that was a requirement.

    It doesn't work at all. My broadcast listener is never called, nothing gets printed out in the logs. Help!

    AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.robotsidekick.webbrowser"
          android:versionCode="4"
          android:versionName="4.0">
    
    <uses-sdk android:minSdkVersion="17"/>
    
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    
    <application
        android:label="@string/app_name"
        android:icon="@drawable/ic_launcher">
    
        <activity
            android:name="WebBrowser"
            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:exported="true"
            android:name="com.robotsidekick.webbrowser.InstallReceiver">
            <intent-filter>
                <action android:name="com.android.vending.INSTALL_REFERRER" />
            </intent-filter>
        </receiver>
    
    </application>
    
    </manifest>
    

    Broadcast Listener

    public class InstallReceiver extends BroadcastReceiver
    {
        private static final String TAG = "InstallReceiver";
    
        public void onReceive(Context context, Intent intent)
        {
            Log.e(TAG, "Context: " + context);
            Bundle extras = intent.getExtras();
            if (extras != null)
            {
                Log.e(TAG, "Extras:");
                for (String keys : extras.keySet())
                {
                    Log.e(TAG, keys + " -> " + extras.get(keys));
                }
            }
            else
            {
                Log.e(TAG, "Extras are null");
            }
        }
    }
    
  • xbakesx
    xbakesx almost 11 years
    It is definitely apparent that after beta 3, you can't extend AnalyticsReceiver. I could change the test broadcast, but I'm not entirely sure how you can change the broadcast the system makes to not specify a target package/class to receive it. So beyond using beta 3 and never upgrading, I'm not sure how to get this to work the way we want.
  • MinceMan
    MinceMan almost 11 years
    Updated answer. Just checkout my example project to see how to do this. github.com/twotoasters/AnalyticsTest
  • Y M
    Y M over 9 years
    Hi, I followed your repository to create a referrer receiver, when using the fake adb broadcast it works. But on releasing app in alpha I am not getting any broadcast. Does it not work in alpha release ?? productforums.google.com/d/msg/analytics/FV2mOfywmlU/…
  • MinceMan
    MinceMan over 9 years
    I used it just fine with an alpha release. Make sure you get to the Play Store through a referral link when installing. .
  • mdavid
    mdavid almost 9 years
    When I get to Play Store without any referral link, I don't get the intent. Is that behavior expected? I want to track my all installs
  • MinceMan
    MinceMan almost 9 years
    That is expected. If the app wasn't installed with a referral link then the play store will not send out a referral intent. You'll have to get a little creative on tracking the other installs.
  • Greg Ennis
    Greg Ennis over 8 years
    It seems that your adb shell command is passing string extras "token" and "source", but your receiver is looking for an extra "referrer". Is something amiss?
  • Parth Anjaria
    Parth Anjaria over 5 years
    @MinceMan thanks, but the issue I am facing is that the code i am able to read when i test from terminal(i.e. by this code : adb shell am broadcast -a com.android.vending.INSTALL_REFERRER -n com.sharesmile.share/.refer_program.InstallReferrerReceiver --es "referrer" "utm_source%3Dapp%26utm_medium%3Dsmc%26utm_term%3Drunning%25‌​2Bshoes%26utm_conten‌​t%3DsmcContent%26utm‌​_campaign%3DParth495‌​21" it works, when i upload the build in alpha testing to test on playstore that time it doesnt work.