Prerequisites

Minimal version of Android

The current version of the FollowAnalytics SDK works with Android API level 14 (Ice Cream Sandwich) and above.

In this section, we explain how to get started with the FollowAnalytics SDK for Android. Before you start to integrate the SDK into your app, you need to do the following on the FollowAnalytics platform:

Add Firebase Cloud Messaging key to your app

Get started with Firebase

Sending push notifications for Android requires Firebase Cloud Messaging, Google's standard messaging service. If you don't already use Firebase, you will need to do the following:

Before you start adding Firebase to your project, we recommend you take the time to familiarize yourself with firebase and its console. You will find this information (and much more) by referring to the Google documentation.

Add the FCM key

You will find the Firebase Cloud Messaging Key (FCM key) in the console of your app. To find the key in the console:

  1. Select your project

  2. In the project page, on the app, it is located under the title of with your project name

  3. Click the Gear icons, this will open the "Settings" page

  4. From the "Settings" page, click the second tab, it is called "Cloud Messaging"

  5. Copy the token for the key you wish to use. The FCM key can be either the "server key", or the "legacy server key". As it is mentioned in the bubble, it is recommended that you use the "server key".

  6. Paste the key in your app settings on the FollowAnalytics platform (Administration > Apps > YourApp) in the field entitled "Firebase Cloud Messaging (FCM) key"

  7. Save the changes

Now that you have added the FCM key, you will be able to send push notifications on Android.

Integration

Here are the minimal steps for integrating the SDK in your application:

Once the integration is finished, you can validate your setup, and start tagging events and saving attributes in your application.

Install using Gradle

The best way to install the SDK is with Gradle:

  1. Fetch the library from the private nexus repository

  2. Add the FollowAnalytics repository to your build.gradle repositories.

    repositories {
      ...
      maven {
        url 'https://nexus.follow-apps.com/nexus/content/repositories/releases/'
      }
    }
    
  3. Add the FollowAnalytics SDK to your module's build.gradle dependencies.

    dependencies {
      ...
      implementation "com.followapps.android:sdk:6.4.+"
      ...
    }
    

Once installation is over you will notice that dependencies and permissions are automatically added. For more information on dependencies and permissions, refer to the two subsections .

Dependencies

Using Gradle, dependencies will automatically be added while merging the manifest. The FollowAnalytics SDK depends on the following libraries:

implementation "com.android.support:support-v4:26.1.0"
implementation "com.android.support:cardview-v7:26.1.0"
implementation "com.google.android.gms:play-services-location:16.0.0"
implementation "com.google.firebase:firebase-messaging:17.4.0"
implementation "me.leolin:ShortcutBadger:1.1.19@aar"

ShortcutBadger dependency

The ShortcutBadger dependency allows devices to display the number of unread messages on the app icon. These are called badges and, unlike on iOS, they are automatically managed with this dependency.

Conflicts in dependencies

If your project doesn't use AndroidX and you implemented some com.android.support:* libraries in your app module dependencies, it's possible that they conflict with FollowAnalytics SDK dependencies.

For solving those conflicts, consider to add each conflicting library in your app module's build.gradle and to set the proper version for each of them.

Here is an example of possible fixes when you have com.android.support:appcompat-v7:28.0.0 in your dependencies, and compileSdkVersion set to 28:

implementation 'com.android.support:cardview-v7:28.0.0' // Do not forget to set the correct library version
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:animated-vector-drawable:28.0.0'
implementation 'com.android.support:support-media-compat:28.0.0'

Permissions

Automatically added permissions

Using Gradle, the SDK adds automatically the following permissions to your manifest.

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Additional permissions
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

Android M and permissions

The following permissions are labelled as dangerous since Android 6.0 Marshmallow (find more information about dangerous permissions here):

  • android.permission.ACCESS_COARSE_LOCATION
  • android.permission.ACCESS_FINE_LOCATION (for geofencing feature).

Permissions and user experience

Note that each permissions results in a dialog being shown to your user. Instead of having them appear at installation, you can have them appear at the most relevant location in your app during runtime. To include permissions and keep a good user experience, we recommend you to follow the Android guidelines described here.

Initialize with your API key

Prepare your API key

Be sure to have your API key for this step of the configuration. If you are not sure where to find it, check instructions here.

To initialize the FollowAnalytics SDK, call FollowAnalytics.init(Context context, Configuration configuration) inside the onCreate() method of the Application class.

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(){
    [...]
    FollowAnalytics.init(this.getApplicationContext(), new FollowAnalytics.Configuration() {
      {
            this.apiKey = "MY_API_KEY";
      }
    });
    [...]
  }
}

If you just created an Application subclass, remember to declare it in your AndroidManifest.xml file:

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

Register for notifications

Important

Push notifications on debug mode don't work. If you wish to test your notifications, which is highly recommended, switch to release mode.

Notification channel for Android 8.0 (Oreo)

Since Google has refactored its "Notification system" for Android 8.0 ("Oreo"), (details here) FollowAnalytics SDK uses default_notification_fa as the id for the NotificationChannel object.

The FollowAnalytics SDK supports push notifications based on Firebase Cloud Messaging. If you haven't done so already, you will need to add your project to Firebase in order to continue in the following steps. In this section we will explain to you how to use Firebase Cloud Messaging (or FCM) with the FollowAnalytics SDK. This means that we will cover:

Install Firebase Cloud Messaging

Reminder: Get started with Firebase

If you haven't already, you need to create a Firebase account and add you app on the console. You can do this by following the steps here.

  1. Add the library FCM to your build.gradle file in your application module.

    implementation "com.google.firebase:firebase-messaging:17.4.0"
    
  2. Create a class that extends to FirebaseMessagingService and override the two methods onMessageReceived and onNewToken.

    import com.google.firebase.messaging.FirebaseMessagingService;
    import com.google.firebase.messaging.RemoteMessage;
    
    public class MyFirebaseMessagingService extends FirebaseMessagingService {
    
      /**
      * Every push notification will arrive through this method
      */
      @Override
      public void onMessageReceived(RemoteMessage remoteMessage) { }
    
    
      /**
      * Every new token will arrive through this method
      */
      @Override
      public void onNewToken(String s){ }
    }
    
  3. Add the following service tag in your AndroidManifest application file. Be sure that the value in android:name is the relative path to your new service previously created.

    <service
        android:name=".MyFirebaseMessagingService"> <!-- Relative path of service class-->
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT"/>
        </intent-filter>
    </service>
    

Verify your Google Services configuration

Be sure to check the configuration of Google Services as they have to be the following if you want the FollowAnalytics SDK and Firebase to work.

  • Version of Google Services that is at least 4.0.1
  • The JSON for Google Services in your application is correct. It is accessible by doing select Project > App > google-services.json) is the same as the one in Firebase (which you can download from the Firebase Console


Interacting Firebase Cloud Messaging with FollowAnalytics SDK

Prerequisites for using Firebase

Before you begin, you need to have Firebase Cloud Messaging (FCM) installed in your project. Then only you can proceed to the integration.

If your app already uses Google Cloud Messaging (GCM) for your push notifications, you will need to migrate to Firebase Cloud Messaging (FCM) after installation. You can skip this section and follow the instructions here.

Now that you have installed FCM, you need it to interact with the FollowAnalytics SDK. For this, access the your Firebase Cloud Messaging Service class (a class we previously called MyFirebaseMessagingService that was created and extended to FirebaseMessagingService).

Set push token

For example:

@Override
public void onNewToken(String s){
    android.util.Log.d(TAG, "Token is : "+s);
    FollowAnalytics.setPushToken(s); // <-- Insert this method
}
Process Firebase Message

This function must be added to onMessageReceived in cases to transmit the push notification to FollowAnalytics SDK.

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    FollowAnalytics.processFirebaseMessage(this, remoteMessage); // <-- Insert this method
}


Migrating from GCM to FCM

Prerequisites for using Firebase

Before you begin, you need to have Firebase Cloud Messaging (FCM) installed in your project. Then only you can proceed to the integration.

This section only applies to apps that already work with Google Cloud Messaging (GCM) and need to switch to Firebase Cloud Messaging. If you don't have GCM in you app, you need to do a standard integration, which is explained in the section above.

  1. Remove any reference to GCM in your build.gradle file.

    dependencies {
      compile "com.google.android.gms:play-services-gcm:<VERSION>"
    }
    
  2. Edit your app's manifest file by removing some required permissions and receiver functionality from GCM.

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <permission android:name="<PACKAGE_NAME>.permission.C2D_MESSAGE"
                android:protectionLevel="signature" />
    <uses-permission android:name="<PACKAGE_NAME>.permission.C2D_MESSAGE" />
    
    ...
    
    <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="<PACKAGE_NAME>" />
        </intent-filter>
    </receiver>
    ...
    <service
        android:name=".MyInstanceIDListenerService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.android.gms.iid.InstanceID" />
        </intent-filter>
    </service>
    ...
    <service
        android:name=".MyGcmListenerService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </service>
    
  3. Migrate the code available in InstanceIDListenerService class to FirebaseMessagingService class.

    //BEFORE
    public class MyInstanceIDListenerService extends InstanceIDListenerService {
    
      ...
    
      @Override
      public void onTokenRefresh() {
          //Code available here
      }
    }
    
    //------------------------------------------------------------------------
    
    //AFTER
    public class MyFirebaseMessagingService extends FirebaseMessagingService {
        ...
    
        @Override
        public void onNewToken(String s){
            //Migrate the code here and do not forget to refactor your code
            FollowAnalytics.setPushToken(s);
        }
    }
    

    Do not forget to refactor your code, due to Google API changes

  4. Migrate the code available in GcmListenerService class to FirebaseMessagingService class. Also do not forget to refactor your code, due to Google API changes.

    //BEFORE
    public class MyGcmListenerService extends GcmListenerService {
    
      ...
    
      @Override
      public void onMessageReceived(String from, Bundle data){
          .....
          //Code available here
      }
    }
    
    //------------------------------------------------------------------------
    
    //AFTER
    public class MyFirebaseMessagingService extends FirebaseMessagingService {
        ...
    
        @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
            //Migrate the code here and do not forget to refactor your code
            FollowAnalytics.processFirebaseMessage(this, remoteMessage);
        }
    }
    

    Do not forget to refactor your code, due to Google API changes

  5. Finally, delete InstanceIDListenerService and GcmListenerService class from your project.

Validate your setup

Validator

The SDK has a Validator that will ensure that everything is properly configured. To know more about what the validator can check and how, refer to its dedicated page.

Checking your SDK integration is valid can be done in two ways :

Analytics

The FollowAnalytics SDK allows you to tag both events and attributes. In this section, we explain how to use both of them in your app and benefit from analytics capabilities. If you are unsure about the difference, you may refer to the corresponding FAQ entry.

To successfully empower your team with FollowAnalytics make sure your logs are relevant, you can find our recommendations and tagging best practices in the FAQ.

Tagging Events and Errors

You can tag Events and Errors in your app by calling the related logging methods provided by the SDKs. These logs are then received and visible on the FollowAnalytics platform.

To tag Events and Errors, use the the following methods:

boolean FollowAnalytics.logEvent(String eventName);
boolean FollowAnalytics.logError(String errorName);

boolean FollowAnalytics.logEvent(String eventName, String details);
boolean FollowAnalytics.logError(String errorName, String details);

boolean FollowAnalytics.logEvent(String eventName, Map<String, String> details);
boolean FollowAnalytics.logError(String errorName, Map<String, String> details);

Those methods return true if the log is valid (i.e. will be sent to the platform), otherwise false is returned and an error description is printed to the console. If details exceeds 60KB it will be considered as invalid.

Use the name as the unique identifier for your tag. Use the details argument to pass specific context to your tag.

The following code shows how an example of how you can tag the viewing and the purchasing of a product:

FollowAnalytics.logEvent("Product view", "RF1672") // Product viewing

HashMap<String, String> details = new HashMap<String, String>();
details.put("reference", "RF1672");
details.put("payment_mode", "credit_card");
details.put("color", "red");
FollowAnalytics.logEvent("Product purchased", details); // Product purchasing

Tagging Locations

There are two ways for tagging locations:

boolean FollowAnalytics.logLocation(double latitude, double longitude);
boolean FollowAnalytics.logLocation(Location location);

Those methods return true if the log is valid (i.e. will be sent to the platform), otherwise false is returned and an error description is printed to the console:

One way to use the logLocation method, is to implement a location listener in your application and tag every location update. FollowAnalytics SDK will take care of ignoring a location tag if this location is too close from the last one:

LocationRequest locationRequest = LocationRequest.create()
        .setFastestInterval(5*1000)
        .setInterval(10*1000)
        .setMaxWaitTime(30*1000)
        .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(your_context);
LocationCallback locationCallback = new LocationCallback() {
  @Override
  public void onLocationResult(LocationResult locationResult) {
    if (locationResult == null) {
      return;
    }
    for (Location location : locationResult.getLocations()) {
      FollowAnalytics.logLocation(location);
    }
  }
};
client.requestLocationUpdates(locationRequest, locationCallback, null);

User ID and Attributes

This section covers the integration of a user ID and customer attributes. The SDK allows you to set values for attributes FollowAnalytics has predefined as well as custom attributes which you can make yourself.

You don't need a user ID to set attributes

Attributes are tied to the device when no user ID is provided. If a user ID is set, a profile is created server side and can be shared across apps.

In both cases, attributes can be used in segments and campaigns to target users.

User ID

To register the user ID, use:

FollowAnalytics.setUserId(String UserId);

To remove the user identifier (for example in case of a sign out) use the following method:

FollowAnalytics.setUserId(null);

Predefined attributes

Predefined attributes are attributes that will be attached to default fields on your user profiles. FollowAnalytics SDK has the following properties for predefined attributes:

boolean FollowAnalytics.UserAttributes.setFirstName(String firstName);
boolean FollowAnalytics.UserAttributes.setLastName(String lastName);
boolean FollowAnalytics.UserAttributes.setEmail(String email);
boolean FollowAnalytics.UserAttributes.setDateOfBirth(Date birthDate);
boolean FollowAnalytics.UserAttributes.setGender(Gender gender);
boolean FollowAnalytics.UserAttributes.setCountry(String country);
boolean FollowAnalytics.UserAttributes.setCity(String city);
boolean FollowAnalytics.UserAttributes.setRegion(String region);
boolean FollowAnalytics.UserAttributes.setProfilePictureUrl(String profilePictureUrl);

For example, to set the user Joe's city to "Paris", you would proceed as follows:

boolean FollowAnalytics.UserAttributes.setCity("Paris");
boolean FollowAnalytics.UserAttributes.setFirstName("Joe");

All UserAttributes methods return:

Custom attributes

In addition to predefined attributes, you can add your own custom attributes to your code.

Always double check your custom attribute types

When a value for an unknown attribute is received by the server, the attribute is declared with the type of that first value.

If you change the type of an attribute in the SDK, values might be refused server-side. Ensure the attribute types match. This could be done by comparing with the ones you have in the profile data section of the product.

Set a custom attribute

To set your custom attributes, you can use the following methods:

boolean FollowAnalytics.UserAttributes.setNumber(String key, Integer value);
boolean FollowAnalytics.UserAttributes.setNumber(String key, Long value);
boolean FollowAnalytics.UserAttributes.setNumber(String key, Double value);
boolean FollowAnalytics.UserAttributes.setNumber(String key, Float value);
boolean FollowAnalytics.UserAttributes.setNumber(String key, BigDecimal value);
boolean FollowAnalytics.UserAttributes.setString(String key, String value);
boolean FollowAnalytics.UserAttributes.setBoolean(String key, Boolean value);
boolean FollowAnalytics.UserAttributes.setDate(String key, Date value);
boolean FollowAnalytics.UserAttributes.setDateTime(String key, Date value);

For example, to set the user's job:

boolean FollowAnalytics.UserAttributes.setString("occupation", "Taxi driver");
Delete a custom attribute value

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

boolean FollowAnalytics.UserAttributes.clear("occupation");
Set of attributes

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

To add an item:

boolean FollowAnalytics.UserAttributes.addToSet("fruits","apple");
boolean FollowAnalytics.UserAttributes.addToSet("fruits","strawberry");
boolean FollowAnalytics.UserAttributes.addToSet("fruits","lemon");
//or by using the variable number of arguments mechanism
boolean FollowAnalytics.UserAttributes.addToSet("fruits","apple","strawberry","lemon");

To remove an item:

boolean FollowAnalytics.UserAttributes.removeFromSet("fruits","lemon"); // Removes "lemon" from set of fruits.
//or by using the variable number of arguments mechanism
boolean FollowAnalytics.UserAttributes.removeFromSet("fruits","lemon","strawberry");

And to clear a set:

boolean FollowAnalytics.UserAttributes.clearSet("fruits");  // Removes all the items from the set.

For further information, refer to the SDK header file.

All UserAttributes methods return:

Opt-in Analytics

FollowAnalytics SDK is opt-in by default at the initialization. However you can set it to opt-out at initialization by setting the optInAnalyticsDefault flag to false in the FollowAnalytics.Configuration object passed to the initialization method. This is only used to set the default opt-in value at initialization. Moreover you can change the opt-in value at runtime.

At runtime, FollowAnalytics SDK uses the value returned by FollowAnalytics.getOptInAnalytics() to decide log collection. The default value of this property is explained in the previous subsection. Once changed, the new value is saved into persistent memory and remains the same at every launch of the application.

If you want to change the value of the opt-in state at runtime, use the setOptInAnalytics method:

FollowAnalytics.setOptInAnalytics(boolean state); // <- state set to true is equal to opt-in, but state set to false is equal to opt-out

In order to retrieve the value of the opt-in state that FollowAnalytics SDK is handling at runtime, use the getOptInAnalytics method:

FollowAnalytics.getOptInAnalytics();

GDPR

To request the data collected with FollowAnalytics SDK, use the following method :

FollowAnalytics.GDPR.requestToAccessMyData();

To delete the data that has been collected with FollowAnalytics SDK, use the following method :

FollowAnalytics.GDPR.requestToDeleteMyData();

Campaigns

In this section, we cover all you need for your app to receive the campaigns sent from the FollowAnalytics platform, and how you can add the features the fully take advantage of the SDK's capabilities.

Before you start, be sure that the SDK is properly initialized. This includes registration for push notifications, which is covered in the "Integration" section above.

Customize push notifications

Notification icon customization

The SDK will use your applauncher icon as default notification icon. You could change this by adding a ic_fa_notification.png file in your drawable folders. If you wish to have a custom background color on your notifications, you can add a value to your color.xml: <color name="ic_fa_notification_color">#ff0000</color>. Be sure to follow Google's guidelines for notification icons on Android.

If you need to customize your push notifications, you have to extend this class FollowAnalytics.DefaultMessageHandler and override the method onPushMessageNotificationBuilding(...) to the class that you created.

For example:

public class FollowPushHandler extends FollowAnalytics.DefaultMessageHandler {

    @Override
  public void onPushMessageNotificationBuilding(Context context, NotificationCompat.Builder notificationBuilder,  FollowAnalytics.Message message) {
       //customize the notification
  }
}

Then, add to the manifest file the path of the class that extends FollowAnalytics.DefaultMessageHandler as a meta-data tag under the application tag. For example:

<meta-data android:name=“com.followanalytics.deeplinking.handler” android:value=“the_full_path_of_your_message_FollowPushHandler”/>

Now that everything is set up, customize your notification under the method onPushMessageNotificationBuilding.

An example of adding buttons to the notification is available below.

@Override
public void onPushMessageNotificationBuilding(Context context, NotificationCompat.Builder notificationBuilder, FollowAnalytics.Message message) {
  super.onPushMessageNotificationBuilding(context, notificationBuilder, message);
  if (message.getCategory().equalsIgnoreCase("social")) {
      PendingIntent pendingIntentActions1 = null; //your pendingIntent when user click on button like
      PendingIntent pendingIntentActions2 =  null; //your pendingIntent when user click on button comment
      NotificationCompat.Action action1 = new NotificationCompat.Action.Builder(android.R.drawable.ic_menu_send, "Like", pendingIntentActions1).build();
      NotificationCompat.Action action2 = new NotificationCompat.Action.Builder(android.R.drawable.ic_menu_help, "comment", pendingIntentActions2).build();
      notificationBuilder.addAction(action1);
      notificationBuilder.addAction(action2);
  }
}

Handling notifications

FollowAnalyticsSDK provides you a way to handle notification events thanks to callbacks.

Notification reception

You can handle the reception of a notification by implementing the onNotificationReceived callback in FollowAnalytics.Configuration. This allows you to access notification information like deep-link url or key/value pairs and perform specific actions accordingly.

new FollowAnalytics.Configuration() {
        ...
        @Override
        public void onNotificationReceived(Message message) {
          // YOUR BEHAVIOR
        }
        ...
}

The onNotificationReceived callback handles:

Deep-linking: URL, Parameters

Push notification campaigns created through FollowAnalytics allow to deep link to content in an app (not limited to your own). You can use either an App Link, or use a customized key-value parameters that are forwarded to your code.

SDK behavior

The SDK manages automatically App-Links. Be sure to follow the google documentation for internal deep-links of the application.

The SDK introduced the possibility to use direct App Links like twitter://messages, which will send you to the corresponding screen inside of the Twitter application.

You're able to access the functionality by enabling the Deep Linking on the platform, when creating a campaign. There you'll find the field App Link that expects you to enter these type of URL schemas. It can either be an URL schema to an external app or for your own application.

Customizing deep-linking parameters

Customizing deep-linking parameters

Google provides it's own recommendations for implementing deep-linking which you can find here. If you wish to implement it differently, please read the content below.

In FollowAnalytics campaigns through the platform, you can specify deep-linking parameters, e.g. in your push messages or for in-app button actions.

These parameters are given to the developer code by the SDK. It is then up to the developer to implement the deep-links in the app (specific path of screens, format of the arguments, etc.).

To obtain these parameters, extend the FollowAnalytics.DefaultMessageHandler class, like in this example:

public class CustomMessageHandler extends FollowAnalytics.DefaultMessageHandler {

     /**
     * This method is executed with no App Links. Only key-values were set.
     **/
     @Override
     public void onPushMessageClicked(Context context, Map<String, String> data) {
         String value1 = data.get("a_custom_param_key");
         if(value1 !=null && data.get(value1).equals("a_custom_param_value_expected")){
             //Execute the code for the customized deep-link with a key : "a_custom_param_key" and a value : "a_custom_param_value_expected"
             Intent intent = new Intent(context, SpecificActivity.class);
             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             context.startActivity(intent);
         }else{
            //Let the SDK handle the notification
            super.onPushMessageClicked(context, data);
         }

     }

    /**
     * This method is executed when an App Link was, at least, set (through the clients portal)
     **/
     @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 chose to define a custom MessageHandler, you must declare it in your app manifest as meta-data:

<application>
    [...]
    <meta-data android:name="com.followanalytics.deeplinking.handler" android:value="fully_qualified_identifier_to_your_class"/>
    [...]
</application>

Through the key value format, FollowAnalytics supports both standardized deep-linking (by defining the key you'll always use to give the path), and more direct parameter passing for simpler use cases integrations.

Regular deep-link is usually implemented using a Router, that will handle the URL called on the app and translate it into the display of the right page, with the right content.

Custom Handling of Rich Campaigns

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

For campaigns where the content is not handled by FollowAnalytics, 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 example:

<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 app package name.

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

Pausing and resuming in-app campaigns

To pause and resume campaigns, add the following methods in you code at the location you wish the pause and resume to take effect:

FollowAnalytics.InApp.pauseCampaignDisplay();  // will pause campaign display
FollowAnalytics.InApp.resumeCampaignDisplay(); // will resume campaign display

Create safe spaces for you in-app messages

Rather than pause everywhere you have an important screen or process, you can pause right at the initialization of the SDK and resume in the areas you think it is safe for in-app messages to be displayed.

Enable campaign archiving

FollowAnalytics SDK allows you to store all campaigns and push notifications received by your application. This makes them available for custom usage, like building an inbox. To enable this feature, add the following line in the app manifest under the tag application.

Data Wallet

The Data Wallet is one of the more advanced features provided by FollowAnalytics. In order to proceed you need to activate it in the Configuration object passed to the initialization.

Local Policy

FollowAnalytics SDK offers you the possibility to add a default policy file.

When no other policy is yet available, the SDK returns a default empty policy having version 0.0.

Follow these steps below in order to add the policy file in your project:

  1. Create an assets folder in your app project.

  2. Add the policy file in the assets folder (policy file downloaded from the platform).

  3. Initialize dataWalletDefaultPolicyPath in the configuration, with the path of the policy file. The path must be a relative path from the assets folder.

For instance :

[...]
FollowAnalytics.init(this.getApplicationContext(), new FollowAnalytics.Configuration() {
  {
    this.dataWalletDefaultPolicyPath = "FollowAnalytics/Policy.config"; // <- Path of the default policy file
  }
});
[...]

Callback Policy

FollowAnalytics SDK has a callback method that is triggered whenever a significant policy version is retrieved (for instance, going from version 1.8 to 2.4). The method is triggered when the leftmost digit of the version is increased.

Read status

The read status of the policy is always set to false whenever the callback method is triggered. A new major version of the policy has to be accepted again by the users of the app, even if they accepted a previous version.

Override onDataWalletPolicyChanged() in Configuration to interact with the newest and significant updated policy in your application.

[...]
FollowAnalytics.init(this.getApplicationContext(), new FollowAnalytics.Configuration() {
  @Override
  public void onDataWalletPolicyChanged(){
      //insert code to interact with your application
  }
});
[...]

Policy methods

Get Policy

To access the latest available policy, call the method getPolicy :

FollowAnalytics.DataWallet.getPolicy();

This method returns an object called Policy. Policy allows you to acquire and process the information related to the policy set in the Data Wallet (version, legal texts, data categories, etc).

Policy status

To check the read status of the policy, use the following method :

FollowAnalytics.DataWallet.isRead();

This method returns a boolean value.

To change the read status of the policy, use the method setIsRead(boolean read) with a boolean value as parameter.

FollowAnalytics.Datawallet.setIsRead(boolean read);

The policy is read when the boolean parameter is true and is not read when it is false.

Web Views

Using FollowAnalytics SDK from a web view is only possible for Android versions above 4.2 "Jelly Bean" (API Version >= 17) in order to prevent a security flaw in Google's Android SDK. You may find more details in the Android documentation.

If your app contains web views, you can use FollowAnalytics SDK from within your HTML/JS code. This is possible thanks to the class named FAWebView, which you can use by following those steps:

  1. Declare the FAWebView element into your <layout>.xml. For instance:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:padding="20dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <com.followapps.android.FAWebView
            android:layout_width="match_parent"
            android:id="@+id/fa_webview"
            android:layout_height="match_parent"/>
    
    </LinearLayout>
    
  2. In the corresponding activity which uses the <layout>.xml layout, retrieve the ID associated with FAWebView element integrated in the layout. For instance:

    FAWebView faWebView = (FAWebView) view.findViewById(R.id.fa_webview);
    
  3. Inject the HTML file/page to the FAWebView element by using the loadUrl method.

    faWebView.loadUrl("file:///android_asset/webView.html");
    

Tagging events/errors/locations, setting user attributes and controlling InApp campaigns can be performed in the HTML file by using the following methods:

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

Watch face

Initialize FollowAnalytics SDK

Do not forget to initialize FollowAnalytics SDK by doing those steps:

Follow Analytics SDK can be used with a watch face.

The watch face architecture has a different approach relatively to Android architecture with their lifecycle that needs to be settle down.

Two different types of background and foreground states exist in CanvasWatchFaceService.Engine.class:

The method onVisibilityChanged() will be executed whenever the watch face becomes visible or hidden in the smartwatch.

However, the method onAmbientModeChanged() will be executed whenever the device enters or exits ambient mode (this mode will switch to a black (hidden seconds) and white display (displayed seconds)).

Now in order to use watch face with FollowAnalytics SDK, two methods are available :

FollowAnalytics.WatchFace.enterForeground();
FollowAnalytics.WatchFace.enterBackground();

The function FollowAnalytics.WatchFace.enterForeground() triggers the information of entering in foreground.

The function FollowAnalytics.WatchFace.enterBackground() triggers the information of entering in background.

Those methods must be added in two different places :

@Override
 public void onAmbientModeChanged(boolean inAmbientMode) {
     super.onAmbientModeChanged(inAmbientMode);

     ...

     if (inAmbientMode) {
         FollowAnalytics.WatchFace.enterBackground();
     } else {
         FollowAnalytics.WatchFace.enterForeground();
     }
     ...
 }

@Override
public void onVisibilityChanged(boolean visible) {
    super.onVisibilityChanged(visible);

    if (visible) {
        ...
        FollowAnalytics.WatchFace.enterForeground();
    } else {
        FollowAnalytics.WatchFace.enterBackground();
        ...
    }
    ...
}

Configuration

In order to customize the behavior of FollowAnalytics SDK, it is possible to change the default configuration by creating your own configuration in the project.

It can be achieved by creating an anonymous FollowAnalytics.Configuration, see all parameters here.

public class MyAwesomeApplication extends Application {
  public static boolean isPolicyCalled = false;

  @Override
  public void onCreate(){
    [...]
    FollowAnalytics.init(this.getApplicationContext(), new FollowAnalytics.Configuration() {
            {
              this.apiKey = "API_KEY";
              this.archiveInAppMessages = true;
            }

            @Override
            public void onDataWalletPolicyChanged() {
                isPolicyCalled = true;
            }

        });
    [...]
  }
}

Or it can be achieved by creating a class that extends FollowAnalytics.Configuration, see all parameters here.

import com.followanalytics.FollowAnalytics;

public class MyConfiguration extends FollowAnalytics.Configuration {
    public static boolean isPolicyCalled = false;

    public MyConfiguration(){
      this.apiKey = "API_KEY";
      this.archiveInAppMessages = true;
    }

    @Override
    public void onDataWalletPolicyChanged(){
        isPolicyCalled = true;
    }
}

And then, you can initialize FollowAnalytics SDK with instantiating and passing the configuration object. For Instance:

public class MyAwesomeApplication extends Application {
  @Override
  public void onCreate(){
    [...]
    FollowAnalytics.init(this.getApplicationContext(), new MyConfiguration());
    [...]
  }
}

Parameters

A description table with the properties that can be modified with FollowAnalytics.Configuration.

Parameter Type Default Value Description
apiKey String "" Your app api key to use our SDK
isVerbose boolean false To see internal logs made by the SDK through Logcat
apiMode enum ApiMode.PROD To avoid sending irrelevant logs to the production server
environment String "" If you want to use a custom environment
environmentDomain String "follow-apps.com" If you want to use a custom domain
environmentProtocol String "https" By default we use https, you can change it to http
optInAnalyticsDefault boolean true To choose your default opt-in / opt-out behavior
isDataWalletEnabled boolean false To enable or disable the DataWallet
dataWalletDefaultPolicyPath String null To determine the path of your local dataWallet policy
onDataWalletPolicyChange callback -- Called when a new significant version of dataWallet policy is available
archivePushMessages boolean false To choose if you want to archive push messages or not
archiveInAppMessages boolean false To choose if you want to archive inApp messages or not
maxBackgroundTimeWithinSession int 120 To determine the lifetime of a session when in background (between 15 and 3600)
onConsoleLog callback -- Called when new logs are made internally in FollowAnalytics SDK
onNotificationReceived callback -- Called when a notification is received by the app

Advanced Use Cases

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:

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

Updating from older versions

Updating from 6.3 to 6.4

Prior to version 6.4.0, for apps that had the fine location permission, the SDK was requesting periodic location updates internally and was sending locations logs to the FollowAnalytics platform. Since version 6.4.0, it's the responsibility of the developer to send location logs to the platform by using the new logLocation() methods, as explained in the Tagging Locations section.