Overview

The FollowAnalytics SDK allows to track events and attributes, receive and measure push and in-app messages, as well as benefit from deep-linking actions already implemented in the app.

The SDK supports Android API 9 as its minSdkVersion.

The current version is:4.2.0

It will work down to API 8 (no GCM, no geolocation/geofencing features, geolocation-free contextual campaigns) and API 7 (no GCM, no geolocation/geofencing nor contextual campaigns), but you may have to make an extra effort to build your app, since Play Services require API 9+.

SDK Integration

If you use gradle as your build system, you can fetch the library from our private nexus repository.

Add the FollowAnalytics repository to your build.gradle repositories.

repositories {
        ...
        maven {
            url 'http://nexus.follow-apps.com/nexus/content/repositories/releases/'
        }
    }

Add the FollowAnalytics SDK to your module's build.gradle dependencies.

dependencies {
    ...
    compile 'com.google.android.gms:play-services-gcm:8.4.0'
    compile 'com.google.android.gms:play-services-location:8.4.0'
    compile 'com.followapps.android:sdk:4.2.0@aar'
}

If you use Google Play Services with a version lower than 8.3.x (e.g. 7.8.0 or lower), you have to update to 8.3.0 or newer.

You can check FollowAnalytics SDK Integration for Gradle here: Sample AndroidManifest for gradle Integration

Using jar

If you are using any other build system, you need to download a .jar file containing the code of our SDK, import the Play Services, and add some extra lines to your AndroidManifest.xml.

1. In your application project, add the .jar file to the /libs directory. If your application does not have a /libs directory, place the .jar file in your application directory and add this directory to your Java CLASSPATH variable.

2. Copy the library project found in your Android SDK installation under extras/google/google_play_services/libproject/google-play-services_lib/ to the location where you maintain your Android app projects. You must import version 8.3.0 or newer.

3. Reference the google-play-services folder as a library project. If you are using Eclipse as an IDE, see Referencing a Library Project for Eclipse, otherwise see Referencing a Library Project on the Command Line for more information.

4. Finalize the play-services installation by adding the following tag in your AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    [...]
    <application ...>
        [...]
        <meta-data android:name="com.google.android.gms.version"
                   android:value="@integer/google_play_services_version" />
        [...]
    </application>
</manifest>

5. Add the following lines to the AndroidManifest.xml. It will specify the permissions the SDK needs and declare its components.

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    [...]
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

    <application...>
        [...]
        <service android:name="com.followapps.android.internal.service.StorageService" />
        <service android:name="com.followapps.android.internal.service.CampaignService" />
        <service android:name="com.followapps.android.internal.service.RequestService" />
        <service android:name="com.followapps.android.internal.service.GcmService" android:exported="false">
                    <intent-filter>
                        <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
                    </intent-filter>
        </service>
        <service android:name="com.followapps.android.internal.push.FollowInstanceIDListenerService"
                          android:exported="false">
                          <intent-filter>
                            <action android:name="com.google.android.gms.iid.InstanceID"/>
                          </intent-filter>
        </service>

        <receiver android:name="com.followapps.android.internal.listener.FaSdkReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>

        <activity android:name="com.followapps.android.internal.activities.RichCampaignActivity"
            android:theme="@android:style/Theme.Translucent.NoTitleBar"
            android:configChanges="keyboardHidden|orientation">
            <intent-filter>
                <action android:name="%YOUR_APP_PACKAGE_NAME%.RICH_CAMPAIGN_VIEW" />
                <category android:name="android.intent.category.BROWSABLE" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

         <activity
                  android:name="com.followapps.android.internal.activities.FaWebViewActivity"
                  android:configChanges="keyboardHidden|orientation"
         />

        <activity android:name="com.followapps.android.internal.activities.DialogActivity"
                  android:theme="@android:style/Theme.Translucent.NoTitleBar"
                  android:configChanges="keyboardHidden|orientation" />
    </application>
</manifest>

Where %YOUR_APP_PACKAGE_NAME% is your application package name.

You can check FollowAnalytics SDK Integration for Jar here: Sample AndroidManifest for Jar Integration

Migration from jar to gradle (aar)

If you're migrating from jar to gradle, please follow the steps below:

1. Remove the permissions, services and receivers related to the FollowAnalytics SDK (gradle will put them automatically).

2. If you use push or in-app messages, add the following permissions to your manifest:

<permission android:name="%YOUR_APP_PACKAGE_NAME%.permission.C2D_MESSAGE"
                android:protectionLevel="signature" />
 <uses-permission android:name="%YOUR_APP_PACKAGE_NAME%.permission.C2D_MESSAGE" />

and add the GCM Receiver:

<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"/>
            <!-- for Gingerbread GSF backward compat -->
            <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
            <category android:name=""%YOUR_APP_PACKAGE_NAME%"/>
        </intent-filter>
 </receiver>

3. Add the FollowAnalytics repository to your build.gradle repositories:

repositories {
        ...
        maven {
            url 'http://nexus.follow-apps.com/nexus/content/repositories/releases/'
        }
    }

4. Add the FollowAnalytics SDK to your module's build.gradle dependencies:

dependencies {
    ...
    compile 'com.google.android.gms:play-services:8.4.0'
    compile 'com.followapps.android:sdk:4.0.2@aar'
}

If you use Google Play Services with a version lower than 8.x.x (e.g. 7.8.0 or lower), we recommend to update to 8.x.x (ex : 8.3.0).

SDK configuration

Add your API Key

The recommended way to add your API KEY (FAID) to your project is as follows: ``` [...] [...]

But for backward compatibility, you can still declare your FAID as a string in an XML file.

To do so, create a `favalue.xml` file in your project `/res/values` directory and add your API key in it (`YOUR_FAID` below):

      <?xml version="1.0" encoding="utf-8"?>
      <resources>
          <string name="faid">YOUR_FAID</string>
      </resources>

##Initializing the SDK
The FollowAnalytics SDK must be initialized in the `onCreate()` method of an `Application` class. This allows the SDK to be constantly initialized, whether the user launches the app himself, or if the Android system wakes any receiver or service of the application (for example for a push notification).

Open your Application subclass, or create a new one, and add the following lines to override the `onCreate` method:

    public class MyAwesomeApplication extends Application {
        [...]
        @Override
        public void onCreate() {
            super.onCreate();
            FollowApps.init(this);
            FollowApps.registerGcm();
            [...]
        }
        [...]
    }


By default, the `maximumBackgroundTimeWithinSession` is set to 120 seconds. You can modify it using the following method:

    FollowApps.setMaximumBackgroundTimeWithinSession(int second);

If you just created an Application subclass, do not forget to declare it in your `AndroidManifest.xml` file:

    <application
        android:name=".MyAwesomeApplication"
        [...] />

##Check your configuration

No matter whether you use _jar_ or _gradle_, you should check your configuration.
The SDK allows you to check it using two methods:

**1.** Show configuration checking in a dialog

     if(Configuration.isApplicationInDebug()){
            InstallationChecker.displaySDKConfigurationCheckingInDialog(ActivityContext);
     }

**2.** Show configuration checking in the console

        if(Configuration.isApplicationInDebug()){
                InstallationChecker.showSDKConfigurationInLog(this);
        }

#Push Notification
The FollowAnalytics SDK supports push notifications based on Google Cloud Messaging.

**1.** Add the following permissions to your manifest:

    <permission android:name="%YOUR_APP_PACKAGE_NAME%.permission.C2D_MESSAGE"
                    android:protectionLevel="signature" />
     <uses-permission android:name="%YOUR_APP_PACKAGE_NAME%.permission.C2D_MESSAGE" />

**2.** Add the GCM Receiver to your manifest

    <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"/>
                <!-- for Gingerbread GSF backward compat -->
                <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
                <category android:name=""%YOUR_APP_PACKAGE_NAME%"/>
            </intent-filter>
     </receiver>

  **3.** In your `Application` subclass

    public class MyAwesomeApplication extends Application {
          [...]
          @Override
          public void onCreate() {
              super.onCreate();
              FollowApps.init(this);
              FollowApps.registerGcm();
              [...]
          }
          [...]
     }

##Notification icon and color

 - Notification icon

By default the sdk uses your applications icon launcher as the notification icon.
If you want a custom icon for your FollowAnalytics notification, add a 
`ic_fa_notification.png` file in your drawable folders.


 - Notification color

By default the sdk does not set the background color for your notification. You can change this behavior by setting your custom color
Add to your file `color.xml` under the folder `values` the following line :

     <color name="ic_fa_notification_color">my-code-color</color>

For example to set your notification background color to red 

     <color name="ic_fa_notification_color">#ff0000</color>


##Deep linking

 In order to handle such use cases efficiently, FollowAnalytics
 campaigns let you define custom parameters associated to the notification.

 These custom parameters are retrieved with the notification.

 By default, a tap on the notification will start the main activity of your application with extra parameters.
 You can retrieve theses parameters using:

     @Override
     protected void onCreate(Bundle savedInstanceState) {
         Bundle extras = getIntent().getExtras();
         if (extras != null) {
             String value1 = extras.getString("a_custom_param_key");
             String value2 = extras.getString("another_key");
             // or retrieve all the pairs
             for (String key : extras.keySet()) {
                 Object value = extras.get(key);
                   // …
               }
              // doSomething
           }
       }

 However, this forces you to handle these events in your main activity, which could not suit your current app architecture.

 Therefore, you can alternatively implement the `MessageHandler` interface, like in the following example:

     public class CustomMessageHandler implements MessageHandler {

         @Override
         public void onPushMessageClicked(Context context, Map<String, String> data) {
             String value1 = data.get("a_custom_param_key");
             String value2 = data.get("another_key");

             // Silently do stuff ...
             // .. or start an activity

             Intent intent = new Intent(context, SpecificActivity.class);
             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             context.startActivity(intent);
         }

           @Override
             public void onPushMessageClicked(Context context, String url, Map<String, String> data) {
                //Do something with the url
             }

         @Override
         public void onInAppMessageClicked(Context context, String buttonText, Map<String, String> data) {
             // Same as the above method, but from a in-app message !
         }
     }

 If you define a custom `MessageHandler`, you must declare it in your Application, after the `FollowApps.init(this)` line:

     FollowApps.setMessageHandler(new CustomMessageHandler());

##Deeplinking URL

This feature requires the version 4.1.0 or greater of the SDK.
For more information, check the android official documentation:[Documentation android ](http://developer.android.com/training/app-indexing/deep-linking.html).
You have also this useful library to process deeplinking url: [Library Airbnb](https://github.com/airbnb/DeepLinkDispatch)

###Launch  activity from click notification
Rather than open the browser,we can set up an intent handler to appropriately direct the user to the screen associated with the provided scheme and host.
So for example the screen product detail  `ProductDetailActivity` can
be showed  when you receive the url [http://my_custom_product/product/detail?id=123](http://my_custom_product/product/detail?id=123)

    <activity
    android:name="....ProductDetailActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="http"
              android:host="www.my_custom_product"
              android:pathPrefix="/product" />
        <data android:scheme="myapp"
              android:host="product" />
    </intent-filter>
    </activity>

NB: All activity configured with these `intent-filter` will handle the url, **even not in your application**.

###Launch  activity from another application
Rather than open your activity, we can set up an intent handler to appropriately direct the user to the screen associated of another application with the provided scheme and host.
So for example the screen product detail  `MySeccondProductDetailActivity` can be showed  when you receive the url [http://my_custom_product/product/detail?id=123](http://my_custom_product/product/detail?id=123)

    <activity
    android:name="anotherapplication.package.....ProductDetailActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="http"
              android:host="www.my_custom_product"
              android:pathPrefix="/product" />
        <data android:scheme="myapp"
              android:host="product" />
    </intent-filter>
    </activity>

###Launch another application from click notification
To launch another application from the click on notification, you have to specify the `App Deeplink url` as following:

 `market://the_package.my_application`

This action opens the application if it's already installed or invite user to install from `Google Play Store`.

###Common application
The SDK handles other usage of deeplinking like `open url`, `make call`, `send sms` or `send email`
####Call
To make a call when you click on the notification, specify `App Deeplink url` as following: `tel://00111111111`
####SMS
To send sms when user click on the notification, specify `App Deeplink url` as following: `sms://00111111111`
####Email
To send mail when user click on the notification, specify `App Deeplink url` as following: `mailto://my_email@example.com`
####Open url
To open the browser when user click on the notification, specify `App Deeplink url` as following : http://google.com
Make sure the url is not the scheme defined inside your activity intent-filter

##Multiple GCM
If you are already using GCM in your application, you will have to check the sender of each notification, as it can now come from different back-ends (yours and FollowAnalytics).

###Let the FollowAnalytics do the process for you
To handle your push message inside the FollowAnalytics SDK, you have to extend the service `GcmService` of Follow and override its method `onPushMessageArrived` 

    import android.os.Bundle;

    public class OtherExternalPushService extends GcmService{

      @Override
      public void onPushMessageArrived(String from, Bundle data) {
        super.onPushMessageArrived(from, data);
        //process data not from Follow SDK
      }
    }

And declare the service in the manifest:

 ```
        <service
                android:name=".mypackage....OtherExternalPushService"
                android:exported="false"
                >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
            </intent-filter>
        </service>

Forward the push message to FollowAnalytics SDK

1. If you were implemented the BrodaCastReceiver you should proceed as following:

public class MyCustomReceiver extends GcmReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
        String from = intent.getStringExtra("from");
        if(FollowApps.isFollowAnalyticsPush(from)){
            FollowApps.onPushReceived(context,intent.getExtras(),from);
        }else{
         //DoSomething with it 
    }
}

And declare it in manifest

 <receiver
                android:name="mypackage_name.MyCustomReceiver"
                android:exported="true"
                android:permission="com.google.android.c2dm.permission.SEND"
                >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
                <!-- for Gingerbread GSF backward compat -->
                <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
                <category android:name="mypackage_name"/>
            </intent-filter>
        </receiver>

2. If you were implemented the GcmListenerService of Google you should proceed as followings also:

public class MyGcmListenerService extends GcmListenerService {

public MyGcmListenerService() {
    super();
}

@Override
public void onMessageReceived(String from, Bundle data) {
    super.onMessageReceived(from, data);
    if (FollowApps.isFollowAnalyticsPush(from)) {
        FollowApps.onPushReceived(this, data, from);
    } else {
        //DoSomething with it  
    }
}
}

And at the end declare it in manifest:

<service android:name=".mypackage....MyGcmListenerService" android:exported="false" > <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE"/> </intent-filter> </service>

Integration with Parse

If you'are using Parse in your application,to let work with FollowAnalytics, you can process as following:

1. Let's Parse register both

Parse uses its own senderId, and the other senderId must be added in the manifest as:

<meta-data android:name="com.parse.push.gcm_sender_id" android:value="id:147726633311" />;

2. Retrieve the token from Parse

    ParseInstallation.getCurrentInstallation().saveInBackground();

    Object deviceToken = ParseInstallation.getCurrentInstallation().get("deviceToken");
    if(deviceToken != null){
        FollowApps.setGcmToken(deviceToken.toString());
    }

Geofencing

To use the geofencing feature, you have to add the following permissions to your manifest:

<!-- Add this permission if you want geofencing-related features to work, and if you want more accurate location data -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

Let us know that you're using geofencing feature by adding the following code

FollowApps.enableService(FAService.GEOFENCING);

Android M and permissions

The SDK uses the following permissions (qualified by android M as dangerous):

            android.permission.ACCESS_COARSE_LOCATION
            android.permission.ACCESS_FINE_LOCATION  (if you use geofencing feature).

For best user experience, you should request theses permissions in your first Activity as described at the following link: http://developer.android.com/training/permissions/requesting.html

Debug and Release modes

The FollowAnalytics SDK has two modes to send data: debug and release.

The debug mode is intented to verify your SDK integration and separate production data from tests and development. This is useful for debugging calls to the FollowAnalytics SDK without polluting recorded data.

The release mode should be set when you are confident with your SDK integration and your app is ready to be deployed on the Play Store.

The mode that your app uses depends on your signing configuration (see next sections for details).

By default, the Android plugin automatically sets up the project to build both a debug and a release version of the application. For more information on android build types, see Gradle build System

Debug mode

Your data is sent in debug mode when your app is debuggable. This happens if:

Data sent in this mode will not be taken into account for stats on the FollowAnalytics dashboards.

You can check the logs received in this mode at https://api.follow-apps.com/logs.

By default on gradle, the commands assembleDebug and installDebug build the application in debug mode. Android Studio signs your app in debug mode automatically when you run or debug your project from the IDE.

Release mode

Your data is sent in release mode if your app is not debuggable. This happens when:

Data sent in this mode will be considered as release data and affect all dashboards and KPIs computed for the app.

You can check the sessions received in this mode at https://api.follow-apps.com/sessions.

APK built by commands assembleRelease and installRelease is by default in release mode. The release app is technically ready to be deployed on the store.

Check your environment

Sometimes, you can have other build types than release, or debug (for example dev, prod). You can always check whether your apk is debuggable or not using the following snippet code:

ApplicationInfo appInfo = ...;
boolean isDebuggable = appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE != 0

if(isDebuggable){

     your environment is debug
}
else {

 your environment is release

}

URL Scheme to allow full debugging

The FollowAnalytics platform enables you to test campaigns before publishing them. To do so, you need the ID of the device you'll use for the test.

Programmatically, you can just call:

FollowApps.getDeviceId()

However, if you want non-developer users to retrieve their device ID, edit your AndroidManifest.xml file to add this:

<activity android:name="com.followapps.android.internal.activities.DeviceIdActivity" >
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:host="followanalytics.com"
            android:path="/deviceId"
            android:scheme="%YOUR_APP_PACKAGE_NAME%" />
    </intent-filter>
</activity>

Once installed, your users can open in a browser (not Chrome ) this URI:

%YOUR_APP_PACKAGE_NAME%://followanalytics.com/deviceId

It will open an activity containing the deviceId.

Note that it does not work with Chrome, because it searches on Google instead of opening the URL. If you have no other browser installed, you can install Firefox.

Fetch tags from already integrated Analytics solution

The SDK has a feature called AdaptiveSDK: it allows to benefit from logs already in place and use them directly without having to implement a new tagging plan. The SDK currently supports SegmentIO, Mixpanel, Google Analytics, Localytics and Urban Airship.

All the events you save using the compatible Analytics SDKs will also be saved on FollowAnalytics. The event name will be prefixed with a two-character code identifying the source: UA for UrbanAirship, LL for Localytics, GA for Google Analytics and so on.

Just like for events tagged directly with our SDK, you can see logs in your developer console when a log is saved, so that you can check it is properly working.

No other code or API key are needed for this integration. If you use another analytics provider that we don’t support right now, reach out to us and we'll add it to the list.

The AdaptiveSDK feature only works with the _gradle implementation._

To support this feature, you have to process as follows.

1. Add the dependency:

compile 'com.followapps.adaptivesdk:adaptivesdk:3.4.0@aar'

2. Allow the FollowAnalytics SDK to start handling events: ````
FollowApps.startHandlingExternalEvent();

**3.** Add an external SDK to be handled :

Currently the Adaptive SDK supports: Mixpanel, Google Analytics, Localytics, Segment IO,Urban Airship, Google Tag Manager and Flurry.

You can select one or more of the following SDK:

    GOOGLE_ANALYTIC,
    URBAN_AIRSHIP,
    MIXPANEL,
    SEGMENT_IO,
    GOOGLE_TAG_MANAGER,
    LOCALYTICS,
    FLURRY,

For example to handle Mixpanel events:
FollowApps.addExternalSDK(ExternalSDK.MIXPANEL);
**4.** To stop handling all events:

 ````   
    FollowApps.stopHandlingExternalEvent();

Logging

Regular, native event logging

The SDK allows you to log specific custom events and errors in your code. The corresponding methods are:

// Log an event without details
FollowApps.logEvent(String eventName);
FollowApps.logError(String errorName);

// Log an event with String details
FollowApps.logEvent(String eventName, String details);
FollowApps.logError(String errorName, String details);

// Log an event with Map details
// This is useful to pass pairs of key-values into a single event
// Note that this Map should only contains basic types as values, including
// Integer, Long, Float, Double, String, Boolean
FollowApps.logEvent(String eventName, String details);
FollowApps.logError(String errorName, Map<String, ?> details);

Use the name variable as the unique identifier of your tag, use the details section to add information or context to your tag. In the FollowAnalytics interface, you'll be able to view the distribution of your events by details (in the following example, you'll be able to view the total number of Product Page Views and the distribution of products).

Example:

FollowApps.logEvent("Product Page", "Product 42"); 
FollowApps.logError("Error log", "This is an error!");

You may use a Map for details. In this case, the Map values should only contains basic java types, such as Integer, Long, Float, Double, String, Boolean…

Example:

HashMap<String, ?> detailsMap = new HashMap<String, Object>();
detailsMap.put("product_id", 141);
detailsMap.put("product_category", "Clothes");
FollowApps.logEvent("Add product to cart", detailsMap);

Logging from a web view

Scope of the feature: This feature is only activated for Android 4.2 (API Version >= 17) to prevent a security flaw in Google Android SDK, documented here by Google https://bit.ly/fa-android-sdk-1K1VSpT.

If you happen to use a web view to display elements of your app, you can also tag events and errors from within your HTML/JS code. To do so:

1. Use the following method calls in your web page code to save events. For instance, you can do:

<a onClick="if (typeof FollowApps !== 'undefined') {FollowApps.logEvent('My event');}">Send event without detail</a>
<a onClick="if (typeof FollowApps !== 'undefined') {FollowApps.logEvent('My event', 'My event details');}">Send event with detail</a>
<a onClick="if (typeof FollowApps !== 'undefined') {FollowApps.logError('fromWebView without detail');}">Send error without detail</a>
<a onClick="if (typeof FollowApps !== 'undefined') {FollowApps.logError('fromWebView with detail','Error detail'");}">Send error with detail</a>

2. In case you want to register for push through a webview, you need to call fARegisterForPush():

<a href="#" onClick="if (typeof FollowApps !== 'undefined') {FollowApps.faRegisterForPush();}">Register for push</a>

3. Make sure to test if FollowApps object exists with if (typeof FollowApps !== 'undefined'). This way, you can reuse the exact same HTML code for your mobile web site.

Cordova event logging

See our Cordova integration documentation.

User ID and attributes

If users can sign in somewhere in your app, you can specify their identifier to the SDK. This way, you will be able to relate crashes to specific users, link your users between FollowAnalytics and your CRM, and more.

To do so, use FollowApps.setCurrentIdentifier(String UserId);. You can get the current one with FollowApps.getCurrentIdentifier();.

If you want to remove the user identifier (in case of a sign out for instance), please use the method FollowApps.unsetCurrentIdentifier();.

Predefined attributes

The SDK allows to set values to both custom and predefined attributes.

For predefined attributes, the SDK has setter methods:

setLastName(String lastName);
setFirstName(String firstName);
setRegion(String region);
setCountry(String country);
setCity(String city);
setCountry(String country);
setEmail(String email);
...

They are "predefined" in the sense that they will be attached as default fields on your user profiles.

For example, to set city as Massy for user Bob, you would proceed as follows:

FollowApps.getAttributeManager().setCity("Massy");
FollowApps.getAttributeManager().setFirstname("Bob");

Custom attributes

To ensure the custom attributes you send using the SDK are stored server-side, you must validate them in the profile settings page on the FollowAnalytics product.

1. Set a custom attribute

To set your custom attributes, you can use one of these methods: setInt, setString,setBoolean, setDate, setDateTime and setDouble.

For example, to set the user's job:

FollowApps.getAttributeManager().setString("key_job", "Taxi driver");

2. Delete a custom attribute value

You can delete the value of an attribute by its key. For example, to delete the user's job

FollowApps.getAttributeManager().delete("key_job");

3. Set of Attributes

You can add or remove an item to or from a set of attributes.

To add an item:

FollowApps.getAttributeManager().add("key_language","English");
FollowApps.getAttributeManager().add("key_language","French");
FollowApps.getAttributeManager().add("key_language","Portuguese");

To remove an item:

FollowApps.getAttributeManager().remove("key_language","Portuguese");  #Removes item "Portuguese" from set of languages

And to clear a set:

FollowApps.getAttributeManager().empty("key_language");  #Removes all the items from the set and deletes it.

Conversation

Rich Campaign

Rich campaigns can be handled directly by your application code, instead of being showed automatically by the SDK. The behavior is defined when creating the campaign, using the "automatically display content" switch.

Automatic display

For campaigns where the content is handled by FollowAnalytics, the campaign will be shown when the app starts.

Custom display

However, you can prevent or delay this from the code thanks to the two following methods:

FollowApps.pauseRichCampaignDisplay();  # will pause rich campaign display

FollowApps.resumeRichCampaignDisplay();  # will resume rich campaign display

Custom Handling

If you want your application to be able to handle rich campaigns, you will need to extend com.followapps.android.CustomRichCampaignBaseReceiver and declare it in your AndroidManifest.xml. You'll need to use an intent-filter on BROADCAST_RICH_CAMPAIGNS_ACTION. For instance:

<receiver android:name=".RichCampaignDataReceiver" >
    <intent-filter>
        <action android:name="%YOUR_APP_PACKAGE_NAME%.BROADCAST_RICH_CAMPAIGNS_ACTION" />
    </intent-filter>
</receiver>

Where %YOUR_APP_PACKAGE_NAME% is your application package name.

The method onRichCampaignDataReceived must be overridden. Rich campaign parameters are provided as method arguments:

User opt-out

The FollowAnalytics SDK allows to handle opt-out states for different features.

Flags

The SDK supplies methods to change some authorization flags:

boolean authorized = true;

// authorized to log events
FollowApps.setCollectLogsAuthorization(authorized);

// authorized to log location events
FollowApps.setCollectLocationLogsAuthorization(boolean authorized);

// authorized to receive push notifications
FollowApps.setPushAuthorization(boolean authorized);

Note that for logging locations events, both the collect logs and collect location logs authorizations must be true. In practice, the location logs are collected if and only if FollowApps.canCollectLocationLogs() returns true.

Dialog

In addition to the direct access to the flag, the SDK supplies methods to ask the user whether they accept to collect logs or receive push notifications or not, using a dialog box.

For collecting logs

FollowApps.sendLogAuthorization(String title, 
    String message, 
    String positiveButtonTitle, 
    String negativeButtonTitle, 
    Activity activity);

Example (within an Activity):

FollowApps.sendLogAuthorization("Help Us Improve This App", 
    "Do you accept us to collect anonymous information on your application usage?", 
    "Accept", 
    "Decline", 
    this);

For collecting location logs

FollowApps.sendLocationAuthorization(String title, 
    String message, 
    String positiveButtonTitle, 
    String negativeButtonTitle, 
    Activity activity);

Example (within an Activity):

FollowApps.sendLocationAuthorization("Better experience!", 
    "This application would like to use your device location in order to provide you with localized content, do you agree?", 
    "Accept", 
    "Decline", 
    this);

Attribution Analytics

MobileAppTracking

Please refer to the MobileAppTracking documentation to integrate their SDK: http://developers.mobileapptracking.com/android-sdk/.

To link MobileAppTracking attribution data with usage data measured by FollowAnalytics, you need to set the MAT user ID with the FollowAnalytics device ID:

//Initialize FollowAnalytics SDK first
...

//Initialize MAT SDK
MobileAppTracker.init(getApplicationContext(), "your_advertiser_ID", "your_conversion_key");
mobileAppTracker = MobileAppTracker.getInstance();

.....
//set MAT userId with FA device ID
mobileAppTracker.setUserId(FollowApps.getDeviceId()); 
// and only then:
mobileAppTracker.measureSession();

Proguard

If you need to obfuscate and/or shrink your app before Google Play publication, be sure you protect the FollowAnalytics SDK, otherwise logs won't be sent.

Here is the ProGuard configuration:

-libraryjars libs
-keep class com.followapps.android** { *; }
-keep interface com.followapps.android.** { *; }