I am attempting to get Android Referral tracking to work. I am following the only documentation I have found here http://code.google.com/mobile/analytics/docs/android/#referrals I have the following in my android manifest file
<receiver
android:name="com.google.android.apps.analytics.AnalyticsReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
<receiver android:name="com.package.Receiver" android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
<uses-sdk android:minSdkVersion="4"/>
com.package.Receiver starts with:
public void onReceive(Context paramContext, Intent paramIntent) {
String str1 = paramIntent.getStringExtra("referrer");
Log.i("myapp", "action: '" + paramIntent.getAction() + "'
referrer string: '" + str1 + "'");
Also with a little bit of decompiling com.google.android.apps.analytics.AnalyticsReceiver has the following code in it:
public void onReceive(Context ctx, Intent intent)
/* */ {
/* 24 */ String referrer = intent.getStringExtra("referrer");
/* */
/* 26 */ if ((!
("com.android.vending.INSTALL_REFERRER".equals(intent.getAction())))
|| (referrer == null))
/* */ {
/* 28 */ return;
/* */ }
/* */
/* 31 */ String formattedReferrer = formatReferrer(referrer);
/* */
/* 33 */ if (formattedReferrer != null) {
/* 34 */ PersistentEventStore store = new
PersistentEventStore(ctx);
/* 35 */ store.setReferrer(formattedReferrer);
/* 36 */ Log.d("googleanalytics", new
StringBuilder().append("Stored
referrer:").append(formattedReferrer).toString());
/* */ } else {
/* 38 */ Log.w("googleanalytics", "Badly formatted referrer, ignored");
/* */ }
/* */ }
Note the two lines 36 and 38 that Log "googleanalytics" I have tried pushing the above app to the market, downloading it on my Nexus One (after uninstalling a previous version of the app). I have generated a link using the google page I linked to at the beginning of this post
http://www.google.com/url?sa=D&q=http://market.android.com/search%3Fq%3Dpname:com.package.app%26referrer%3Dutm_source%253Dgoogle%2526utm_medium%253Dcpc%2526utm_term%253Drunning%25252Bshoes%2526utm_content%253Dcontent1%2526utm_campaign%253Dslogan&usg=AFQjCNFctwqk1WgWl0bhiIBNVqy3U4OPRw
I attached logcat to my Nexus One while I download the app from that link, I do not see any logs from "googleanalytics" or "myapp". The rest of the google analytics library does work for my app. I.E. I see records on google analytics about pages hits etc. However all the traffic sources are "Direct Traffic". I am at a loss as to what is going on. Does anyone
have any insight into what I might be doing wrong?
As is often the case I found my own answer. My problem was in my AndroidManifest.xml
I had the following in my manifest:
<manifest>
<application>
</application>
<receiver>
</receiver>
<uses-sd/>
</manifest>
The receiver tag was in the wrong spot. It should look like this
<manifest>
<application>
<receiver>
</receiver>
</application>
<uses-sd/>
</manifest>
I am now seeing the logs I expect to when I install the app. In a few hours hopefully Google Analytics will have the data as well.
I have explore quite a lot the referral tracker with analytics for android. You don't need to put the app in the market you can just send a broadcast intent.
Intent i = new Intent("com.android.vending.INSTALL_REFERRER");
i.setPackage(com.package.yourapp)
//referrer is a composition of the parameter of the campaing
i.putExtra("referrer", referrer);
sendBroadcast(i);
There can be only one BroadcastReceiver for an action. In your AndroidManifest.xml, you have two listening for com.android.vending.INSTALL_REFERRER.
If you want to your receiver AND the Google Analytics receiver to both handle the intent, make your receiver a subclass of AnalyticsReceiver, like this:
import com.google.android.apps.analytics.AnalyticsReceiver;
class Receiver extends AnalyticsReceiver {
#Override
void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
// Add your custom handling here
}
}
Then make sure yours is the only receiver in AndroidManifest.xml:
<receiver android:name="com.package.Receiver" android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
Related
I have to implement the referral linking functionality in my application like mCent application. For that I have done the following lines of code.
My application Manifest file. In the <application >..... </application> , I have done some entries for it.
<service android:name="com.google.android.gms.analytics.CampaignTrackingService" />
<receiver
android:name=".receivers.InstallReceiver"
android:exported="true" >
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
And My BrodcastRecevier class is as follow , please check it.
public class InstallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String rawReferrer = intent.getStringExtra("referrer");
if (rawReferrer != null) {
trackReferrerAttributes(rawReferrer, context);
}
}
private void trackReferrerAttributes(String rawReferrer, Context context) {
String referrer = "";
try {
referrer = URLDecoder.decode(rawReferrer, "UTF-8");
} catch (UnsupportedEncodingException e) {
return;
}
if (Strings.isNullOrEmpty(referrer)) {
return;
}
Uri uri = Uri.parse('?' + referrer); // appends ? for Uri to pickup query string
String memberCode;
try {
referringMember = uri.getQueryParameter("mcode");
} catch (UnsupportedOperationException e) {
return;
}
SharedPreferences.Editor editor = context.getSharedPreferences(
BuildConfig.PACKAGE_NAME, Context.MODE_PRIVATE).edit();
if (!Strings.isNullOrEmpty(memberCode)) {
editor.putString(Constants.REFERRER_CODE, memberCode);
}
String referralMedium = uri.getQueryParameter("tc");
if (!Strings.isNullOrEmpty(referralMedium)) {
editor.putString("referral_medium", referralMedium);
}
editor.apply();
}
}
But i am not receiving any referral from the above code...
I have created the refferal link like this
https://play.google.com/store/apps/details?id=tv.CaseGaurd&referrer=ravindrakushwaha
Is there is any error in my referral link above OR friends , what am i doing wrong in my BroadcastRecevier class or in Manifest file
From this documentation I found that the action filter is (in manifest):
<!-- Used for install referrer tracking-->
<receiver android:name="YOUR_RECEIVER"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
Also be sure that your Receiver is in that real package ".receivers.InstallReceiver", but package com.example.app.receivers;... is your package really com.example.app?
(I considered you to be using the Google Play Store app)... also, about your downvotes, this is likely to bad wording on your question, or that you are not showing effort about your question, finally, note that this is a "free to use community forum", and that people are random...
Finally, put a breakpoint in the Receiver, send a broadcast (using adb for instance), and test that you are really not getting the broadcast.
I'm building a library that uses GCM. I was testing it with a sample app that implements GCM as well.
I have used same implementation for both except every one of them has its own sender ID
That's what I wrote for my sample app I'm testing the library with. I also wrote same thing for the library but with different names for the services:
<!-- GCM -->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.example.instabug" />
</intent-filter>
</receiver>
<service
android:name=".SampleInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<service
android:name=".SampleGcmRegistrationIntentService"
android:exported="false"/>
<service
android:name=".SampleGcmListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
My problem is whenever I sent a push notification to my library the App receiver always catch it. the library receiver don't do anything.
Is there a way to resolve this issue?!
As far as I understand you have two services with same intent filter. In that case Android will pick the service with higher priority (foreground). If priority is the same - will pick random, i.e. just one service will receive the intent.
For your case best solution will be to use just one service and dispatch according to from (senderId) parameter of onMessageReceived() in your GcmListenerService.
I figured out someway to do that. In my Android library I gave the intent filter of GcmListenerService a higher priority than the one is in the Android app so that the GCM message received and processed by the library first.
<service
android:name=".SampleGcmListenerService"
android:exported="false">
<intent-filter priority="100">
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
When the GCM message arrive to the library's GcmListenerService you have to forward to the android app if it's irrelevant to the library. Since I'm making a library that can be used by anyone in the future. I will not know where can I find the GcmListenerService in the the app module. All I can do is to use reflection to get all classes in the app module and see which one has GcmListenerService as a super class and then starting a wakeful service to that class.
Here what I did:
#Override
public void onMessageReceived(String from, Bundle data) {
if (!from.equalsIgnoreCase("51XXXXXXXX")) {
String[] classes = getClassesOfPackage(getPackageName());
for (int i = 0; i < classes.length; i++) {
String sClassName = classes[i];
try {
Class classToInvestigate = Class.forName(sClassName);
String superClassName = classToInvestigate.getSuperclass().getName();
if (superClassName.equalsIgnoreCase("com.google.android.gms.gcm.GcmListenerService")) {
//sending intent to the wakeful app's service
forwardGcmToApp(from, data, sClassName);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
//TODO: fire the polling service
String message = data.getString("message");
}
}
/**
* Called to get list of classes included in the current project
*
* #param packageName the name of application package
* #return array of classes' names
*/
private String[] getClassesOfPackage(String packageName) {
ArrayList<String> classes = new ArrayList<>();
try {
String packageCodePath = getPackageCodePath();
DexFile df = new DexFile(packageCodePath);
for (Enumeration<String> iter = df.entries(); iter.hasMoreElements(); ) {
String className = iter.nextElement();
if (className.contains(packageName)) {
classes.add(className);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return classes.toArray(new String[classes.size()]);
}
/**
* Called to forward Gcm content to the App {#link GcmListenerService}
*
* #param from Gcm sender ID
* #param data bundle received from Gcm
* #param className Class name that extends {#link GcmListenerService}
*/
private void forwardGcmToApp(String from, Bundle data, String className){
Intent intent = new Intent();
intent.setAction("com.google.android.c2dm.intent.RECEIVE");
data.putString("from", from);
data.putString("message_type", null);
intent.putExtras(data);
intent.setComponent(new ComponentName(getPackageName(), className));
GcmReceiver.startWakefulService(getApplicationContext(), intent);
}
I've spent the last two days trying to find a workaround for this.
I need to pre-config my app depending on the referral and since google play is broadcasting an Install Referrer intent when an app is installed, I created my own receiver for this task. The code for the manifest declaration and the Receiver is:
Manifest declaration:
<receiver
android:name="my.package.CustomReceiver"
android:exported="true" >
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
And the simplified code of the CustomReceiver:
public class CustomReceiver extends BroadcastReceiver {
private static final String CAMPAIGN_SOURCE_PARAM = "utm_source";
#Override
public void onReceive(Context context, Intent intent) {
Log.d("debug", "waking receiver");
Uri uri = intent.getData();
getReferrerMapFromUri(uri);
new CampaignTrackingReceiver().onReceive(context, intent);
}
void getReferrerMapFromUri(Uri uri) {
MapBuilder paramMap = new MapBuilder();
// If no URI, return an empty Map.
if (uri == null) {
Log.d("debug", "intent null");
return;
}
if (uri.getQueryParameter(CAMPAIGN_SOURCE_PARAM) != null) {
// MapBuilder.setCampaignParamsFromUrl parses Google Analytics
// campaign
// ("UTM") parameters from a string URL into a Map that can be set
// on
// the Tracker.
paramMap.setCampaignParamsFromUrl(uri.toString());
Log.d("debug", paramMap.get(Fields.CAMPAIGN_SOURCE));
// If no source parameter, set authority to source and medium to
// "referral".
} else if (uri.getAuthority() != null) {
paramMap.set(Fields.CAMPAIGN_MEDIUM, "referral");
paramMap.set(Fields.CAMPAIGN_SOURCE, uri.getAuthority());
}
}
}
That's all. I am sending broadcast install intent with the adb shell command but it's not getting activated at all. I am using google analytics v3.
Thank you in advance!
I've tried this way. And it does work.( I am also using Google Analytics v3)
First, in manifest :
<!-- Used for Google Play Store Campaign Measurement-->;
<service android:name="com.google.analytics.tracking.android.CampaignTrackingService" />
<receiver android:name="com.google.analytics.tracking.android.CampaignTrackingReceiver" android:exported="true" >
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
Second, add an CustomReceiver extends BroadcastReceiver
( In my case, I just copy and paste all the codes from developers )
package com.example.testanalytics;
import com.google.analytics.tracking.android.CampaignTrackingReceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class CustomReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// Pass the intent to other receivers.
// When you're done, pass the intent to the Google Analytics receiver.
new CampaignTrackingReceiver().onReceive(context, intent);
}
}
last step: in my activity( which I want to send messages to Google Analytics )
create an Intent and call sendBroadcast( Intent ) as follow:
Intent it = new Intent("com.android.vending.INSTALL_REFERRER");
it.setPackage("com.example.testanalytics");
it.putExtra("referrer", "utm_source%3Dyahoo%26utm_medium%3Dbanner+cpc%26utm_term%3Debook%26utm_content%3Dmy_content%26utm_campaign%3Dmy_campaign_name_2");
sendBroadcast(it);
And just get it.
I hope this may help you.
I've found some solutions to track referrer URL from the market, but my apps aren't in the market.
Is there a way to get the referrer URL for applications downloaded from private sites?
To get referrer, you need to register your receiver for that. After installation, a broadcast is fired which you need to catch by following code.
First take a look at Android Native Application Tracking Overview
1. Create a Receiver
public class ReferrerReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
String referrerString = extras.getString("referrer");
Log.i("Home", "Referrer is: " + referrerString);
}
}
2. Register in Manifest file
<receiver android:name="your.package.name.ReferrerReceiver" android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
i created an app that has a BroadcastReceiver that catches a INSTALL_REFERRER broadcast.
When I'm installing the app with eclipse and creating a broadcast with adb I see that all work fine, the LogCat is displaying all that it should be.
But when I'm installing the app from the play store nothing is showing on the logcat.
If I understand correctly, the play store app should create a broadcast witch the app that is being installed supposed to catch, right?
Thats basicly what im doing:
public class SDK_Referrer extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals("com.android.vending.INSTALL_REFERRER"))
{
String referrer = intent.getStringExtra("referrer");
if (!(referrer == null || referrer.length() == 0))
{
// extracting the relevant data to Map
Log.d("SAMPLE", "Generating Ymid from referrel");
Map<String, String> referralmap =
createHashMapFromQueryString(referrer);
Log.d("SAMPLE", "Ymid is: " + referralmap.get("ymid"));
}
}
}
}
i only want to send someting to a server when the app is being installed.
Thanks!
You need to add the receiver to your manifest, so your app knows you have something listening for the broadcast. Something like this:
<receiver android:name="com.company.cool.SDK_Referrer" android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>