Referral linking in Android like mCent application - android

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.

Related

Android MY_PACKAGE_REPLACED not called in release mode

I have an app update receiver which is running fine in debug apk. but after release and update with Google Play build or already installed release build, it's not getting called.
Receiver entry in manifest file is
<receiver android:name=".receiver.AppUpdateReceiver">
<intent-filter android:priority="100">
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
and Receiver class is
public class AppUpdateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
String action = intent.getAction();
if (action != null && TextUtils.equals(action, Intent.ACTION_MY_PACKAGE_REPLACED)) {
Toast.makeText(context, "updated", Toast.LENGTH_SHORT).show();
}
} catch (Exception ex) {
CTAnalytics.sendExceptionToServer("AppUpdateReceiver onReceive error:", ex);
}
}
}
Looks about right. I'm not sure why there's a need to specify 'android:priority'?
Try removing android:priority and make your receiver exported (I think it should be so by default, since you're specifying an intent-filter). So something like:
<receiver android:name=".receiver.AppUpdateReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
</intent-filter>
</receiver>

Getting broadcast if user installs app successfully using my intent play store url

I am working on app which suggested app. If user installs app successfully using my app then he gets reward in my app.
I am getting info about "com.android.vending.INSTALL_REFERRER" action of receiver which provides this but didn't get success...
So please help me with getting some full examples or other suggestion...
This is my code...
Button Click Event
btnInstallApp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent goToMarket = new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse("market://details?id=com.idea.backup.smscontacts&referrer=tecksky"));
startActivity(goToMarket);
}
});
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tecksky.referrerdemo">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".activity.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".receiver.ReferrerCatcher"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER"></action>
</intent-filter>
</receiver>
</application>
</manifest>
ReferrerCatcher.java
public class ReferrerCatcher extends BroadcastReceiver {
private static String referrer = "";
#Override
public void onReceive(Context context, Intent intent) {
referrer = "";
Bundle extras = intent.getExtras();
if (extras != null) {
referrer = extras.getString("referrer");
}
Log.e("REFERRER : ", referrer);
}
}
Hey Just see how it works I have implemented this in my app as well and works for me perfectly so I am posting you referral code:
Create separate class for receiving reference:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.google.android.gms.analytics.CampaignTrackingReceiver;
public class CustomReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
new CampaignTrackingReceiver().onReceive(context, intent);
Bundle b= intent.getExtras();
String referrerString = b.getString("referrer");
// Log.e("bundle", "bundle= " + referrerString+ " " + referrerString.substring(11, referrerString.length()));
SharedPrefManager.setPrefVal(context, Constants.REFERRAL, referrerString.substring(11, referrerString.length()));
}
}
This class will receive the referral that you have to save somewhere like I am saving it in SharedPrefrence. This broadcast will receive when the user will install app from play store and in "referrer" you will get info that which user pass this user the link to download app then from that referrer key you can give benefit to user who referred your app.
In manifest file add receiver Tag
<receiver
android:name="gcm.CustomReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
From backend you will get a link from server side for a particular user which you will hit to play store then something like
https://play.google.com/store/apps/details?id=com.example.app&referrer=utm_source=123456ref
Basically in your receiver class you are picking this utm_source and you have to send it to server side when user will sign up in you app. Which means it ll let know that from which reference which id has been generated.
Hope this helps you. Try this and let me know.

GCM conflict between Android App and Android Library

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);
}

Google Analytics Tracking with Android App Installs

I need help with some Google Analytics tracking with Android app installs. I've tried researching this but haven't understood it all clearly.
So far, I have this in my AndroidManifest.xml:
<receiver
android:name="<IHaveMyPackageNameHere>.InstallReferrerReceiver"
android:exported="true" >
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
Also, I have the following in my InstallReceiver class:
public class InstallReceiver extends BroadcastReceiver {
private static final String TAG = "InstallReferrerReceiver";
#Override
public void onReceive(Context context, Intent intent) {
AnalyticsTrackerFactory.setApiKey("");
HashMap<String,String> values = new HashMap<String, String>();
try {
if (intent.hasExtra("referrer")) {
String referrers[] = intent.getStringExtra("referrer").split("&");
for (String referrerValue : referrers) {
String keyValue[] = referrerValue.split("=");
values.put(URLDecoder.decode(keyValue[0]), URLDecoder.decode(keyValue[1]));
}
}
} catch (Exception e) {
}
Log.d(TAG, "referrer: " + values);
AnalyticsTrackerFactory.getTracker(context).event("Installed", values); } }
I've found some of this code online but cannot figure out how to implement it correctly. Basically, I'm stuck at setting an API key and sending the values to Google Analytics.
Can anyone guide me into the right direction? Thanks.
Google Analytics provides referrer receiver implementation. You don't need to implement it yourself. The instruction for adding campaign attribution are in this dev guide https://developers.google.com/analytics/devguides/collection/android/v4/campaigns

Android referral removed in analytics v3?

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.

Categories

Resources