Prerequisites
Minimal version of Android
The current version of the FollowAnalytics SDK works with Android API level 16 (Jelly Bean) 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:
- Register your app and generate its API key by following the instructions here.
- Set the FCM server key in your app.
Set the FCM server key in 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:
- Add Firebase to your project
- Create Firebase project to Firebase console
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:
-
Select your project
-
In the project page, on the app, it is located under the title of with your project name
-
Click the Gear icons, this will open the "Settings" page
-
From the "Settings" page, click the second tab, it is called "Cloud Messaging"
-
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".
-
Paste the key in your app settings on the FollowAnalytics platform (Administration > Apps > YourApp) in the field entitled "Firebase Cloud Messaging (FCM) key"
-
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:
- Installing the SDK in your app
- Initializing the SDK using your API key
- Registering for notifications
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:
-
Fetch the library from the private nexus repository
-
Add the FollowAnalytics SDK repository to your project-level
build.gradle
file:allprojects { repositories { ... maven { url 'https://nexus.follow-apps.com/nexus/content/repositories/releases/' } } }
-
Add the FollowAnalytics SDK dependency to your module-level
build.gradle
file:dependencies { ... implementation "com.followapps.android:sdk:6.8.0" ... }
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 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.appcompat:appcompat:1.0.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.
Migration to AndroidX
Please note that the FollowAnalytics sdk uses AndroidX libraries. If your project does not use AndroidX, please make sure to migrate your project to use it. See this guide for more informations about the migration.
Permissions
Automatically added permissions
Using Gradle, the SDK automatically adds the following normal permissions to your app 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
- To use InApp template campaigns on devices running Android API level < 19, add the following permissions to your app manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- To use the geofencing feature, add the following permissions to your app manifest:
<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_FINE_LOCATION (for geofencing feature).
- android.permission.WRITE_EXTERNAL_STORAGE (for InApp template campaigns on devices running Android API level < 19).
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";
}
});
[...]
}
}
class MyAwesomeApplication : Application() {
override fun onCreate() {
[...]
FollowAnalytics.init(this.applicationContext, object : FollowAnalytics.Configuration() {
init {
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.
-
Add the library FCM to your
build.gradle
file in your application module.implementation "com.google.firebase:firebase-messaging:17.4.0"
-
Create a class that extends to
FirebaseMessagingService
and override the two methodsonMessageReceived
andonNewToken
.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){ } }
import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage class MyFirebaseMessagingService : FirebaseMessagingService() { /** * Every push notification will arrive through this method */ override fun onMessageReceived(remoteMessage: RemoteMessage) {} /** * Every new token will arrive through this method */ override fun onNewToken(s: String) {} }
-
Add the following service tag in your
AndroidManifest
application file. Be sure that the value inandroid: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
FollowAnalytics.setPushToken(String token)
is a function that passes a FCM token to FollowAnalytics SDK. Add it to the functiononNewToken
.
For example:
@Override
public void onNewToken(String s){
android.util.Log.d(TAG, "Token is : "+s);
FollowAnalytics.setPushToken(s); // <-- Insert this method
}
override fun onNewToken(s: String) {
Log.d(TAG, "Token is : " + s)
FollowAnalytics.setPushToken(s) // <-- Insert this method
}
Process Firebase Message
FollowAnalytics.processFirebaseMessage(Context context, RemoteMessage remoteMessage)
is a function that passes the push message notification to FollowAnalytics SDK.
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
}
override fun onMessageReceived(remoteMessage: RemoteMessage) {
FollowAnalytics.processFirebaseMessage(this, remoteMessage) // <-- Insert this method
}
Setup your Notification Channel name (Android 8.0 and above)
When you initialize the SDK, you can setup the name of the notification channel (whose id is default_notification_fa
as mentionned above) created by the SDK. This name will displayed to the user in your application's settings. To do so, you need to override the value of the notificationChannelName
attribute of the configuration
object that you pass to the FollowAnalytics.init(Context context, Configuration configuration)
method as below :
public class MyAwesomeApplication extends Application {
@Override
public void onCreate(){
[...]
FollowAnalytics.init(this.getApplicationContext(), new FollowAnalytics.Configuration() {
{
this.apiKey = "MY_API_KEY";
this.notificationChannelName = "MY_CHANNEL_NAME";
}
});
[...]
}
}
class MyAwesomeApplication : Application() {
override fun onCreate() {
[...]
FollowAnalytics.init(this.applicationContext, object : FollowAnalytics.Configuration() {
init {
apiKey = "MY_API_KEY"
notificationChannelName = "MY_CHANNEL_NAME"
}
})
[...]
}
}
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.
-
Remove any reference to GCM in your
build.gradle
file.dependencies { compile "com.google.android.gms:play-services-gcm:<VERSION>" }
-
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>
-
Migrate the code available in
InstanceIDListenerService
class toFirebaseMessagingService
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); } }
//BEFORE class MyInstanceIDListenerService : InstanceIDListenerService() { ... fun onTokenRefresh() { //Code available here } } //------------------------------------------------------------------------ //AFTER class MyFirebaseMessagingService : FirebaseMessagingService() { ... override fun onNewToken(s: String?) { //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
-
Migrate the code available in
GcmListenerService
class toFirebaseMessagingService
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); } }
//BEFORE class MyGcmListenerService : GcmListenerService() { ... fun onMessageReceived(from: String, data: Bundle) { ... //Code available here } } //------------------------------------------------------------------------ //AFTER class MyFirebaseMessagingService : FirebaseMessagingService() { ... override fun 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
-
Finally, delete
InstanceIDListenerService
andGcmListenerService
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 :
-
At runtime, look into your console logs, some FollowAnalytics SDK logs will appear just after the app launch.
For instance :
--------Checking FollowAnalytics SDK setup-------- Configuration OptInAnalyticsDefault : false Archive Push Messages : true Archive InApp Messages : true Notification Channel Name : My Channel IsDataWalletEnabled : true Default Policy File Path : null ✅ ApiKey : HF7naIcl4f Environment Protocol : https Environment Domain : follow-apps.com ApiMode : PROD IsVerbose : true MaxBackgroundTimeWithinSession : 120 Manifest ✅ Coarse location permission ✅ Fine location permission ✅ SDK services are all declared ✅ SDK receivers are all declared ✅ SDK activities are all declared
-
Call the following method to display the validator in a dialog :
FollowAnalytics.displaySDKValidatorDialog(Activity activity);
Analytics
To enrich User Analytics on the platform, FollowAnalytics SDK allows you to:
- Log your users events, errors and locations.
- Set attributes for your users.
Logs and attributes can also be used to target specific audiences when creating campaigns on the platform. You can find more information about the difference between logs and attributes here.
Our CSM team can help you creating relevant logs in your app. You can also find our recommendations here.
Logging Events and Errors
You can log Events and Errors in your app by calling the following methods:
static boolean logEvent(String name);
static boolean logError(String name);
static boolean logEvent(String name, String details);
static boolean logError(String name, String details);
static boolean logEvent(String name, Map<String, String> details);
static boolean logError(String name, Map<String, String> details);
Those methods return true
if the log is valid, otherwise false
is returned and an error description is printed to the console. If details
exceeds 60KB it will be considered as invalid. A valid log will be sent to the platform only if opt-in analytics is true
.
Use name
as a unique identifier for your log. Use details
to pass specific context to your log.
The following code shows an example of how you can log 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
FollowAnalytics.logEvent("Product view", "RF1672") // Product viewing
val details : HashMap<String, String> = HashMap<String, String>();
details.put("reference", "RF1672");
details.put("payment_mode", "credit_card");
details.put("color", "red");
FollowAnalytics.logEvent("Product purchased", details); // Product purchasing
Logging Locations
There are two ways for logging locations:
static boolean logLocation(double latitude, double longitude);
static boolean logLocation(Location location);
Those methods return true
if the log is valid, otherwise false
is returned and an error description is printed to the console:
- if the location distance from the last logged location is less than 100 meters, the log will be ignored and
logLocation
returnsfalse
. - if the location time interval from the last logged location is less that 1 hour, the log will be ignored and
logLocation
returnsfalse
.
A valid log will be sent to the platform only if opt-in analytics is true
.
One way to use the logLocation
method, is to implement a LocationCallback
in your application, request location updates and log the last location update. FollowAnalytics SDK will take care of ignoring a location log 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) {
Location location = locationResult.getLastLocation();
if (location != null) {
FollowAnalytics.logLocation(location);
}
}
};
client.requestLocationUpdates(locationRequest, locationCallback, null);
val locationRequest = LocationRequest.create()
.setFastestInterval(5 * 1000)
.setInterval(10 * 1000)
.setMaxWaitTime(30 * 1000)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
val client = LocationServices.getFusedLocationProviderClient(your_context)
val locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
val location = locationResult.lastLocation
if (location != null) {
FollowAnalytics.logLocation(location)
}
}
}
client.requestLocationUpdates(locationRequest, locationCallback, null)
Last known location logs
If you don't request location updates, and you don't send location logs you can still have location logged thanks to the configuration option lastKnownLocationEnabled
.
Enabling this option, by setting Configuration.lastKnownLocationEnabled
to true
, will allow the SDK to send a location logs whenever a new session is created and a valid location is available.
The SDK is started by default with Configuration.lastKnownLocationEnabled
set to false
.
User Attributes
A user can be defined by setting its identifier. This identifier is a string that you provide to the SDK to uniquely identify a user of your app. It can be an e-mail address, an identifier from your own backend (for instance a primary key), a phone number, or anything else that could allow you to uniquely identify a user.
Attributes (like first name, date of birth...) can be associated to a user if it's defined. Attributes are associated to the device when no user is defined.
When a user is defined, a user profile is created server-side and can be shared across apps.
You can set predefined as well as custom attributes.
Define a user
To define a user, set its user ID:
FollowAnalytics.setUserId("UniqueIdentifier");
To remove a user (for example in case of a sign out), just pass null
to setUserId
:
FollowAnalytics.setUserId(null);
Predefined attributes
To set predefined attributes, you can call the following methods on the UserAttributes
class provided by the SDK:
static boolean setFirstName(String firstName);
static boolean setLastName(String lastName);
static boolean setEmail(String email);
static boolean setDateOfBirth(Date birthDate);
static boolean setGender(Gender gender);
static boolean setCountry(String country);
static boolean setCity(String city);
static boolean setRegion(String region);
static boolean setProfilePictureUrl(String profilePictureUrl);
Those methods return:
true
, when the attribute has been successfully saved and will be sent to the platform.false
, if the passed argument is invalid or if opt-in analytics isfalse
. In this case the attribute is not sent to the platform.
For example, to set the user Joe's city to "Paris", you would proceed as follows:
FollowAnalytics.UserAttributes.setFirstName("Joe");
FollowAnalytics.UserAttributes.setCity("Paris");
Custom attributes
In addition to predefined attributes, you can set your own custom attributes.
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 tab in the Administration page on FollowAnalytics platform.
Set a custom attribute
To set custom attributes, you can call the following methods on the UserAttributes
class provided by the SDK:
static boolean setNumber(String key, Integer value);
static boolean setNumber(String key, Long value);
static boolean setNumber(String key, Double value);
static boolean setNumber(String key, Float value);
static boolean setNumber(String key, BigDecimal value);
static boolean setString(String key, String value);
static boolean setBoolean(String key, Boolean value);
static boolean setDate(String key, Date value);
static boolean setDateTime(String key, Date value);
Those methods return:
true
, when the attribute has been successfully saved and will be sent to the platform.false
, if the key or value is invalid or if opt-in analytics isfalse
. In this case the attribute is not sent to the platform.
For instance, to set the user's job:
FollowAnalytics.UserAttributes.setString("job", "Taxi driver");
Delete a custom attribute value
You can delete the value of an attribute using its key. For instance, to delete the user's job:
FollowAnalytics.UserAttributes.clear("job");
Set of attributes
You can add or remove an item to or from a set of attributes.
To add an item to a set:
FollowAnalytics.UserAttributes.addToSet("fruits", "apple"); // Adds "apple" to set "fruits"
FollowAnalytics.UserAttributes.addToSet("fruits", "strawberry"); // Adds "strawberry" to set "fruits"
FollowAnalytics.UserAttributes.addToSet("fruits", "lemon"); // Adds "lemon" to set "fruits"
// This is the equivalent, by using the variable number of arguments mechanism
FollowAnalytics.UserAttributes.addToSet("fruits", "apple", "strawberry", "lemon");
To remove an item from a set:
FollowAnalytics.UserAttributes.removeFromSet("fruits", "lemon"); // Removes "lemon" from set "fruits".
FollowAnalytics.UserAttributes.removeFromSet("fruits", "strawberry"); // Removes "strawberry" from set "fruits".
// This is the equivalent, by using the variable number of arguments mechanism
FollowAnalytics.UserAttributes.removeFromSet("fruits", "lemon", "strawberry");
To clear a set:
FollowAnalytics.UserAttributes.clearSet("fruits"); // Removes all items from set "fruits".
Opt-in Analytics
FollowAnalytics SDK opt-in analytics state define whether to send logs and attributes to the platform. Opt-in analytics is true
by default, meaning logs and attributes will be sent to FollowAnalytics platform.
You can set it to opt-in analytics to false
at SDK initialization by setting the optInAnalyticsDefault
parameter 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.
To change opt-in analytics state at runtime, use the setOptInAnalytics
method:
static void setOptInAnalytics(boolean state);
This value is persisted in memory and the opt-in analytics state is changed for all subsequent launch of your application, meaning optInAnalyticsDefault
is ignored.
To retrieve the current opt-in analytics state, use the getOptInAnalytics
method:
static boolean getOptInAnalytics();
GDPR
To request the data collected with FollowAnalytics SDK, call the following method on the GDPR
class provided by the SDK:
static void requestToAccessMyData()
To delete the data that has been collected with FollowAnalytics SDK, call the following method on the GDPR
class provided by the SDK:
static void 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 the FollowAnalytics.DefaultMessageHandler
class and override the method onPushMessageNotificationBuilding(...)
, which is called right before the notification is actually displayed to the user.
We do provide to you a FollowAnalytics.NotificationBuilder
object as an argument of this method. The FollowAnalytics.NotificationBuilder
class is a subclass of the NotificationCompat.Builder
class, so you can use its instances to customize the notifications, as you would do with typical NotificationCompat.Builder
instances, except for these few methods which will have no effect on the builder if you call them:
FollowAnalytics.NotificationBuilder.setContentIntent(PendingItent)
. You should rather implement the actual behaviour of the action on theonPushMessageClicked
callbacks which we will describe later.addAction(int icon, CharSequence title, PendingIntent intent)
addAction(NotificationCompat.Action action)
There you can see how to actually add action buttons to your notifications, and here is an example of how to extend the FollowAnalytics.DefaultMessageHandler
class :
public class FollowPushHandler extends FollowAnalytics.DefaultMessageHandler {
@Override
public void onPushMessageNotificationBuilding(Context context, FollowAnalytics.NotificationBuilder notificationBuilder, FollowAnalytics.Message message) {
//customize the notification
}
}
class FollowPushHandler : FollowAnalytics.DefaultMessageHandler() {
override fun onPushMessageNotificationBuilding(context: Context, notificationBuilder: FollowAnalytics.NotificationBuilder, message: FollowAnalytics.Message) {
//customize the notification
}
}
Please do not forget to 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, you can customize your notification under the method onPushMessageNotificationBuilding
, which is called right before the notification is actually displayed to the user.
Interactive notifications
An Interactive Notification is a notification containing custom action buttons that the user can access by revealing the notification:
When tapped, an action button will:
- Close the notification.
- Eventually launch your application in the foreground, if you specified it explicitly when creating the action (See details below). Otherwise your app is not opened.
- Execute the custom behavior you implemented for the notification tap.
To create a campaign with Interactive Notifications:
-
On the platform, create a Push Campaign and define a Category in the Interactive Notification section of the campaign editor. For our example, let's set this field to
"NewContent"
. -
In your app, define the action names you want for your notification, we will call them
actionIdentifiers
. Those identifiers will be displayed as is on the platform in the Push Opened stats:
static final String DELETE = "Delete";
static final String VIEW = "View";
static final String REMIND = "Remind me tomorrow";
val DELETE = "Delete"
val VIEW = "View"
val REMIND = "Remind me tomorrow"
If you want to add action buttons to your notification, you have to use the FollowAnalytics.NotificationBuilder.addAction(Context context, int icon, String actionLabel, String actionIdentifier)
method. The actionLabel
argument is your localized String that represents your action button's text and the actionIdentifier
should be used as a unique identifier for each of your action buttons. This identifier will be passed as an argument to the onPushMessageClicked
callback, which will be called whenever an action button is clicked on, so you can identify which action button has been clicked on.
An example of adding buttons to the notification is available below. Please note how the "NewContent" field defined above is used.
@Override
public void onPushMessageNotificationBuilding(Context context, FollowAnalytics.NotificationBuilder notificationBuilder, FollowAnalytics.Message message) {
if (message.getCategory().equalsIgnoreCase("NewContent")) {
notificationBuilder.addAction(context, android.R.drawable.ic_menu_send, context.getResources().getString(R.string.view), VIEW);
notificationBuilder.addAction(context, android.R.drawable.ic_menu_delete, context.getResources().getString(R.string.delete), DELETE);
notificationBuilder.addAction(context, android.R.drawable.ic_menu_agenda, context.getResources().getString(R.string.remind_me), REMIND);
}
}
override fun onPushMessageNotificationBuilding(context: Context, notificationBuilder: FollowAnalytics.NotificationBuilder, message: FollowAnalytics.Message) {
if (message.category.equals("NewContent", ignoreCase = true)) {
notificationBuilder.addAction(context, android.R.drawable.ic_menu_send, context.resources.getString(R.string.view), "view")
notificationBuilder.addAction(context, android.R.drawable.ic_menu_delete, context.resources.getString(R.string.delete), "delete")
notificationBuilder.addAction(context, android.R.drawable.ic_menu_agenda, context.resources.getString(R.string.remind_me), "remind")
}
}
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
}
...
}
object : FollowAnalytics.Configuration() {
...
override fun onNotificationReceived(message: FollowAnalytics.Message?) {
// YOUR BEHAVIOR
}
...
}
The onNotificationReceived
callback handles:
- Push notifications
- Contextual notifications
- Silent push notifications
Please note that if for some reason you need to dismiss the notification from your code, you can use the Message.cancelNotification(Context). Here is an example of how to use it :
new FollowAnalytics.Configuration() {
...
@Override
public void onNotificationReceived(Message message) {
// YOUR BEHAVIOR
message.cancelNotification(mContext);
}
...
}
object : FollowAnalytics.Configuration() {
...
override fun onNotificationReceived(message: FollowAnalytics.Message?) {
// YOUR BEHAVIOR
message.cancelNotification(mContext)
}
...
}
Opt-in Notifications
The FollowAnalytics SDK opt-in notifications status defines whether your app will receive notifications from your Push campaigns. Opt-in notifications is true
by default, meaning notifications from your Push campaigns will be received by your app. This status is independent from the Android system notification authorization, which is also needed by your app to display notifications.
Thanks to this opt-in notifications status, you can implement a UI in your app to allow to choose whether to receive notifications, without the need to go to the Android notification authorization settings. Note that the opt-in notifications status will have no effect if the Android system notification authorization is not allowed, and in this case, your app will not receive notifications from your Push campaigns, whatever the opt-in notifications status.
To update your app UI to reflect the current opt-in notifications status, use the getOptInNotifications
method:
static boolean getOptInNotifications();
To update the current opt-in notifications status upon UI change, use the setOptInNotifications
method:
static void setOptInNotifications(boolean state);
Handling transistion from opt-out to opt-in notifications
Just calling setOptInNotifications(true)
after the user interacts with your app UI to opts-in for notifications could be insufficient if the Android system notification authorization is not allowed. For this reason, we recommend to implement the following flow after the user opts-in for notifications in your app:
- Check the return value of
FollowAnalytics.isRegisteredForPushNotifications()
which istrue
only if Android system notification authorization AND the SDK opt-in notifications status aretrue
. - If
false
, display a message and button to invite your user to enable the Android system notification authorization. - Call
FollowAnalytics.openNotificationSettingsEventually()
when the user taps the button, to direct him to the Android notification settings screen.
Another possibility is to bypass the first two steps and only implement the last one. In this case the Android notification settings will be opened only if the system authorization was not allowed.
It's also possible to set the opt-in notifications status to false
at the SDK initialization by setting the optInNotificationsDefault
parameter to false
in the Configuration object passed to the initialization method. This is only used to set the default opt-in value at the first launch of the app. Note that calling setOptInNotifications()
will persist the opt-in notifications status for all subsequent launch of your application, meaning optInNotificationsDefault
will be ignored.
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.
App Links
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
}
/**
* This method is executed when an a user clicks on one of your notification's action button
*/
@Override
public void onPushMessageClicked(Context context, Map<String, String> map, String actionIdentifier) {
switch (actionIdentifier) {
case VIEW:
// Your behavior for a tap on the "View" action button
break;
case DELETE:
// Your behavior for a tap on the "Delete" action button
break;
case REMIND:
// Your behavior for a tap on the " Remind me tomorrow" action button
break;
}
}
/**
* This method is executed when an a user clicks on one of your notification's action button,
* and only if an App Link was set from the platform
*/
@Override
public void onPushMessageClicked(Context context, String dlURL, Map<String, String> map, String actionIdentifier) {
switch (actionIdentifier) {
case VIEW:
// Your behavior for a tap on the "View" action button
break;
case DELETE:
// Your behavior for a tap on the "Delete" action button
break;
case REMIND:
// Your behavior for a tap on the "Remind me tomorrow" action button
break;
}
}
@Override
public void onInAppMessageClicked(Context context, String buttonText, Map<String, String> data) {
// Same as the above method, but from a in-app message!
}
}
class CustomMessageHandler : FollowAnalytics.DefaultMessageHandler() {
/**
* This method is executed with no App Links. Only key-values were set.
*/
override fun onPushMessageClicked(context: Context, data: Map<String, String>) {
val value1 = data["a_custom_param_key"]
if (value1 != null && data[value1] == "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"
val intent = Intent(context, SpecificActivity::class.java)
intent.flags = 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 fun onPushMessageClicked(context: Context, url: String?, data: Map<String, String>) {
//Do something with the url
}
/**
* This method is executed when an a user clicks on one of your notification's action button
*/
override fun onPushMessageClicked(context: Context, map: Map<String, String>, actionIdentifier: String) {
when (actionIdentifier) {
VIEW -> {
// Your behavior for a tap on the "View" action button
}
DELETE -> {
// Your behavior for a tap on the "Delete" action button
}
REMIND -> {
// Your behavior for a tap on the "Remind me tomorrow" action button
}
}
}
/**
* This method is executed when an a user clicks on one of your notification's action button, and only if an App Link was set from the clients portal
*/
override fun onPushMessageClicked(context: Context, dlURL: String, map: Map<String, String>, actionIdentifier: String) {
when (actionIdentifier) {
VIEW -> {
// Your behavior for a tap on the "View" action button
}
DELETE -> {
// Your behavior for a tap on the "Delete" action button
}
REMIND -> {
// Your behavior for a tap on the "Remind me tomorrow" action button
}
}
}
override fun onInAppMessageClicked(context: Context, buttonText: String?, data: Map<String, String>) {
// 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:
- Campaign title:
title
- Campaign URL:
url
- Custom Parameters associated to the campaign:
customParams
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.
Archiving messages
FollowAnalytics SDK allows you to store campaigns's messages received by your app. This makes them available for custom usage, like building an inbox feature. Messages received by a device can be archived locally and accessed from the developer's code, formatted as a Message
object. In order for you to enable the message archiving, you need to set the following Configuration properties at SDK initialization:
protected boolean archivePushMessages;
protected boolean archiveInAppMessages;
You will find below all the methods you need to handle all the archived Message
.
FollowAnalytics.InApp.getAll() //Get all in-app messages
FollowAnalytics.Push.getAll() //Get all push messages
FollowAnalytics.InApp.get("MESSAGE_ID") //Get an in-app message
FollowAnalytics.Push.get("MESSAGE_ID") //Get a push message
FollowAnalytics.InApp.delete(message.getId()) //Delete an in-app message
FollowAnalytics.Push.delete(message.getId()) //Delete a push message
FollowAnalytics.InApp.markAsRead(message.getId()) //Mark an in-app message as read
FollowAnalytics.Push.markAsRead(message.getId()) //Mark push message as read
FollowAnalytics.InApp.markAsUnread(message.getId()) //Mark an in-app message as unread
FollowAnalytics.Push.markAsUnread(message.getId()) //Mark push message as unread
And here is a description of some of the Message
accessors:
Accessor | Return type | Description |
---|---|---|
isRead() |
boolean | Indicates if the message has been read or not. False at message reception. |
isNotificationDismissed() |
boolean | If the message comes from a Push campaign, this method returns true if the notification has been dismissed, false otherwise. |
isPush() |
boolean | Returns true if message comes from a Push campaign, false if it comes from a In-App campaign. |
isInApp() |
boolean | Returns true if message comes from a In-App campaign, false` if it comes from a Push campaign. |
isSilentPush() |
boolean | Returns true if message comes from a Push campaign with the "Silent" option enabled (silent push), false otherwise. |
getNotificationId() |
int | If message comes from a Push campaign, this is the Android notification identifier. |
getReceivedDate() |
date | If message comes from a Push campaign, this is the date at which the message is received on the device. If message comes from an In-App campaign, this is the start date of the campaign. |
getId() |
string | Unique message Identifier. If the message comes from a Push campaign, this also serves as the Android notification tag. |
getTitle() |
string | Text provided in the platform's "Title" field of the Push campaign editor. |
getBody() |
string | Text provided in the platform's "Content" field of the Push campaign editor. |
getUrl() |
string | Url provided in the platform's "URL" field of In-App Custom Web Page campaign editor. If the message comes from a Push campaign, this is the url of the Rich Media. |
getDeepLinkUrl() |
string | Url provided in the platform's "App Link" field of the Push campaign editor. |
getParams() |
dictionary | Key/Value pairs provided in the Push campaign editor. |
Web Views
If your app contains web views, you can use FollowAnalytics SDK from within your JavaScript code. This is possible using our FAWebView
to display your web pages, instead of the regular Android WebView.
FollowAnalytics JS interface not available on Android API level < 17
Using FollowAnalytics SDK from a web view is only possible on Android versions above 4.2 "Jelly Bean" (API level >= 17) in order to prevent a security flaw in Google's Android SDK. More details in Android documentation.
Using FAWebView
-
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>
-
In the corresponding activity which uses the
<layout>.xml
layout, retrieve theFAWebView
instance:FAWebView faWebView = (FAWebView) view.findViewById(R.id.fa_webview);
val faWebView = findViewById<FAWebView>(R.id.fa_webview)
-
Load your HTML page in the
FAWebView
by using theloadUrl
method:faWebView.loadUrl("file:///android_asset/webView.html");
faWebView.loadUrl("file:///android_asset/webView.html");
-
If your app's
minSdkVersion
is lower that 19, make sure to add the following script to your HTML page in order to have the FollowAnalytics JS interface properly initialised on devices running Android API level < 19:<script>window.addEventListener('DOMContentLoaded',function(e){if(typeof(FollowAnalytics)!=='undefined'){if(typeof(InApp)!=='undefined'){FollowAnalytics.InApp=InApp;}if(typeof(Push)!=='undefined'){FollowAnalytics.Push=Push;}if(typeof(UserAttributes)!=='undefined'){FollowAnalytics.UserAttributes=UserAttributes;}FollowAnalytics.Gender={REMOVE:0,MALE:1,FEMALE:2,OTHER:3};FollowAnalytics.UserAttributes.setDateOfBirth=function(value){if(Object.prototype.toString.call(value)==='[object Date]'){FollowAnalytics.UserAttributes.__setDateOfBirth(value.getTime());}else{FollowAnalytics.UserAttributes.clear('date_of_birth');}};FollowAnalytics.UserAttributes.setDateTime=function(key,value){if(Object.prototype.toString.call(value)==='[object Date]'){FollowAnalytics.UserAttributes.__setDateTime(key,value.getTime());}else{FollowAnalytics.UserAttributes.clear(key);}};FollowAnalytics.UserAttributes.setDate=function(key,value){if(Object.prototype.toString.call(value)==='[object Date]'){FollowAnalytics.UserAttributes.__setDate(key,value.getTime());}else{FollowAnalytics.UserAttributes.clear(key);}};}});</script>
FollowAnalytics SDK JS interface
Here are the SDK methods you can call from the JavaScript code:
-
Environment information and actions:
FollowAnalytics.getUserId(); FollowAnalytics.setUserId("aUserId"); FollowAnalytics.getSDKPlatform(); FollowAnalytics.getSDKVersion(); FollowAnalytics.getDeviceId(); FollowAnalytics.setOptInAnalytics(false); FollowAnalytics.getOptInAnalytics(); // Returns the string "true" if the opt-in analytics status is true, "false" otherwhise. FollowAnalytics.setOptInNotifications(false); FollowAnalytics.getOptInNotifications(); // Returns the string "true" if the opt-in notifications status is true, "false" otherwhise. FollowAnalytics.isRegisteredForPushNotifications() // Get the Push campaigns registration status. Will return "true" only if the Android system notification authorization is allowed AND the SDK opt-in notifications status is true. Otherwise, will return "false". FollowAnalytics.openNotificationSettingsEventually(); FollowAnalytics.setData("key", "value"); // To save and persist string data. FollowAnalytics.getData("key"); // To retrieve a previously saved string data from its key: note that "notificationAuthorization" is a reserved key returning // "true" if the Android system notification authorization is allowed, "false" otherwise, or null if not set.
-
Logging events/errors/locations:
FollowAnalytics.logEvent("anEventName"); FollowAnalytics.logEvent("anEventName", "anEventDetail"); FollowAnalytics.logError("anErrorName"); FollowAnalytics.logError("anErrorName", "anErrorDetail"); FollowAnalytics.logLocation(48.8410646, 2.3210844);
-
User attributes:
FollowAnalytics.UserAttributes.setFirstName("aFirstName"); FollowAnalytics.UserAttributes.setLastName("aLastName"); FollowAnalytics.UserAttributes.setEmail("something@domain.com"); FollowAnalytics.UserAttributes.setDateOfBirth(new Date("1998-08-01")); FollowAnalytics.UserAttributes.setGender(FollowAnalytics.Gender.MALE); // Can be MALE, FEMALE or OTHER FollowAnalytics.UserAttributes.setCountry("France"); FollowAnalytics.UserAttributes.setCity("Paris"); FollowAnalytics.UserAttributes.setRegion("Île-de-France"); FollowAnalytics.UserAttributes.setProfilePictureUrl("https://picture_url"); FollowAnalytics.UserAttributes.setNumber("aKey", 10.5); FollowAnalytics.UserAttributes.setDateTime("aKey", Date.now()); FollowAnalytics.UserAttributes.setDate("aKey", Date.now()); FollowAnalytics.UserAttributes.setString("aKey", "aString"); FollowAnalytics.UserAttributes.setBoolean("aKey", true); FollowAnalytics.UserAttributes.addToSet("aSetKey", "aSetElement"); FollowAnalytics.UserAttributes.removeFromSet("aSetKey", "aSetElement"); FollowAnalytics.UserAttributes.clear("aKey"); FollowAnalytics.UserAttributes.clearSet("aSetKey");
-
InApp campaigns archiving:
FollowAnalytics.InApp.markAsRead("campaignId1", "campaignId2"/*,..., "campaignIdN"*/); FollowAnalytics.InApp.markAsUnread("campaignId1", "campaignId2"/*,..., "campaignIdN"*/); FollowAnalytics.InApp.delete("campaignId1", "campaignId2"/*,..., "campaignIdN"*/); FollowAnalytics.InApp.get("aCampaignId"); // Returns an campaign Message json object as a String FollowAnalytics.InApp.getAll(); // Returns an array of campaign Message json object as a String
-
Push campaigns archiving:
FollowAnalytics.Push.markAsRead("campaignId1", "campaignId2"/*,..., "campaignIdN"*/); FollowAnalytics.Push.markAsUnread("campaignId1", "campaignId2"/*,..., "campaignIdN"*/); FollowAnalytics.Push.delete("campaignId1", "campaignId2"/*,..., "campaignIdN"*/); FollowAnalytics.Push.get("aCampaignId"); // Returns an campaign Message json object as a String FollowAnalytics.Push.getAll(); // Returns an array of campaign Message json object as a String
Make sure to test if FollowAnalytics object exists with if (typeof FollowAnalytics !== 'undefined')
. This way, you can reuse the exact same 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
:
- onVisibilityChanged()
- onAmbientModeChanged()
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();
...
}
...
}
override fun onAmbientModeChanged(inAmbientMode: Boolean) {
super.onAmbientModeChanged(inAmbientMode)
...
if (inAmbientMode) {
FollowAnalytics.WatchFace.enterForeground();
} else {
FollowAnalytics.WatchFace.enterBackground();
}
...
}
override fun onVisibilityChanged(visible: Boolean) {
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;
}
});
[...]
}
}
class MyAwesomeApplication : Application() {
var isPolicyCalled = false
override fun onCreate() {
[...]
FollowAnalytics.init(this.applicationContext, object : FollowAnalytics.Configuration() {
init {
apiKey = "API_KEY"
archiveInAppMessages = 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;
}
}
import com.followanalytics.FollowAnalytics
class MyConfiguration : FollowAnalytics.Configuration() {
init {
this.apiKey = "API_KEY"
this.archiveInAppMessages = 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());
[...]
}
}
class MyAwesomeApplication : Application() {
override fun onCreate() {
[...]
FollowAnalytics.init(this.applicationContext, 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 analytics behavior |
optInNotificationsDefault |
boolean | true | To choose your default opt-in / opt-out notifications behavior |
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 |
lastKnownLocationEnabled |
boolean | false | true to enable the logging of the last known location when the session starts. |
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.** { *; }
-keep class com.{path_to_your_custom_class}
Updating from older versions
Updating from 6.4 to 6.5
- Now, by default, the last known location is no longer logged when a session starts. Set the Configuration parameter
lastKnownLocationEnabled
totrue
if you want to enable this feature.
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 Logging Locations section.