Android Guide

Integration Guide

Grow Android SDK integration guide – v1.0.3 (last updated September 8th, 2022)

To ensure optimal usage of the SDK and to allow you to leverage all its capabilities, you should perform all the following steps:

1 – SDK Installation

Add the Grow Nexus repository to your project:

  • If you use dependencyResolutionManagement, add the following to your settings.gradle file:
dependencyResolutionManagement {
    // ...
    repositories {
        // ...
        maven {
            url 'https://nexus.bryj.ai/repository/releases/'
        }
    }
}
  • If you don’t use dependencyResolutionManagement, add the following to your project-level build.gradle file:
allprojects {
    repositories {
        // ...
        maven {
            url 'https://nexus.bryj.ai/repository/releases/'
        }
    }
}

Add the GROW SDK dependency to your module-level build.gradle file:

dependencies {
    // ...
    implementation 'ai.bryj.grow:grow-sdk:1.0.3'
}

2 – SDK initialization

To initialize the SDK, call Grow.start(Context, Grow.Configuration) from your Application.onCreate() implementation. If you don’t have an Application class defined yet in your project, you have to create one and override its onCreate() method to initialize the SDK. The Grow.Configuration required to initialize the SDK is provided by the Grow.ConfigurationBuilder thanks the to build() method.

Initializing the SDK with the default Configuration

In the example below, a Grow.Configuration is instantiated with only the mandatory apiKey which must be retrieved from the platform in Admins → Your Project → Settings :

class MyApplication : Application() {
    
    override fun onCreate() {
        super.onCreate()
        
        Grow.start(
            applicationContext,
            Grow.ConfigurationBuilder(apiKey = "YOUR_API_KEY")
                .build()
        )
    }
}
public class MyApplication extends Application {
    
    @Override
    public void onCreate() {
        super.onCreate();
        Grow.start(getApplicationContext(),
                new Grow.ConfigurationBuilder("YOUR_API_KEY")
                        .build());
    }
}

AndroidManifest

Make sure your Application class is properly declared in AndroidManifest.xml:

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

Initializing the SDK with a custom Configuration

The Grow.Configuration describes to the SDK how it should behaves, by defining the following parameters:

ParameterTypeDefault ValueDescription
apiKeyStringThis mandatory parameter allows the SDK to authenticate with the platform.
isVerboseEnabledBooleanFalseThis controls which type of message the SDK can print to the console. You can check SDK messages thanks to the Android Studio console (Logcat) or thanks to logging tools like pidcat.

If this parameter is false, the SDK will only print Info, Error and Warning messages, which are general purpose messages with low level of detail.

If this parameter is true, the SDK will also print detailed Debug messages, additionally to Info, Error and Warning messages. Those Debug messages show SDK interaction with the platform, as well as internal SDK mechanism.
isAnalyticsEnabledByDefaultBooleanFalseThis defines whether the SDK will send send events and attributes to the platform.
It’s false by default, meaning events and attributes will not be sent to the platform, until the method Grow.Device.setAnalyticsEnabled(true) is called later in the app flow.
Having this parameter set to true means the SDK is allowed to send events and attributes to the platform since its very first initialization, until Grow.Device.setAnalyticsEnabled(false) is called later in the app flow.
notificationChannelNameStringYour application’s nameThis is the text displayed as the push notification channel name in the Android Notification Settings for your app.

In the example below, a Grow.Configuration is instantiated with the necessary parameters to let the SDK behaves as following:

  • Events and attributes are allowed to be sent since the very first SDK initialization
  • Detailed Debug messages will be printed
  • In the Android Notification Settings for this app, the Grow channel name will be “News”
class MyApplication : Application() {
    
    override fun onCreate() {
        super.onCreate()
        
        Grow.start(
            applicationContext,
            Grow.ConfigurationBuilder(apiKey = "YOUR_API_KEY")
                .setAnalyticsEnabledByDefault(true)
                .setIsVerboseEnabled(true)
                .setNotificationChannelName("News")
                .build()
        )
    }
}
public class MyApplication extends Application {
    
    @Override
    public void onCreate() {
        super.onCreate();
        Grow.start(getApplicationContext(),
                new Grow.ConfigurationBuilder("YOUR_API_KEY")
                        .setAnalyticsEnabledByDefault(true)
                        .setIsVerboseEnabled(true)
                        .setNotificationChannelName("News")
                        .build());
    }
}
To ensure our Customers comply with local data regulations. The SDK is by default opt-out analytics.
This means a minimal set of data will be sent to GROW until the end-users provides consent to be tracked. Please refer to the dedicated Analytics section in the Usage Guide to enable analytics.

3 – Push configuration

If you haven’t done so yet, you will need to register your project to Firebase. To do so, follow the instructions from the official Firebase documentation. If you haven’t done so yet, you will need to register your app with Firebase and add the Firebase configuration file to your project. To do so, follow the instructions from the official Firebase documentation.

  • Add the Firebase Cloud Messaging library dependency to your app-level build.gradle file:
plugins {
    // ...
    id 'com.google.gms.google-services'
}
dependencies {
    // ...
    implementation platform('com.google.firebase:firebase-bom:29.0.0')
    implementation 'com.google.firebase:firebase-messaging-ktx'
}
  • Create a class that extends FirebaseMessagingService and override onMessageReceived and onNewToken as follows:
class MyFirebaseMessagingService : FirebaseMessagingService() {

    override fun onNewToken(token: String) {
        Grow.Device.setFirebasePushToken(token)
    }

    override fun onMessageReceived(message: RemoteMessage) {
        Grow.Device.processFirebaseMessage(message)
    }
}
public class MyFirebaseMessagingService extends FirebaseMessagingService {
    
    @Override
    public void onNewToken(@NonNull String token) {
        super.onNewToken(token);
        Grow.Device.setFirebasePushToken(token);
    }
    
    @Override
    public void onMessageReceived(@NonNull RemoteMessage message) {
        super.onMessageReceived(message);
        Grow.Device.processFirebaseMessage(message);
    }
}
  • Add the service previously created to the AndroidManifest inside your <application> tag. Make sure to set android: name to the relative path to your service:
<service
    android:name=".MyFirebaseMessagingService"
    android:enabled="true"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

Verifying integration

To check the SDK is properly integrated and configured in your app, you can enable the Verbose mode at SDK initialization and look at the console logs while your app is running, thanks to Android Studio’s Logcat window (debug builds) or with the pidcat utility (release builds).

Enabling analytics

For reporting activity logs from the tagging plan (User Identifier, Attributes & Events), analytics must be enabled in the SDK.
By default, analytics are disabled, and can be turned on by changing the analytics state of the SDK.

This to enable analytics, please refer to the Analytics section in the Usage Guide

In the console logs you will be able to check:

In the console logs you will be able to check:

  • Whether configuration is OK
  • Whether push integration is OK

In the following snippets, we will consider the bundle id is com.company.myapp and the api key is UKoJbzWq5Fz5hA

Enabling verbose mode

Set isVerboseEnabled to true in on the Configuration when initialising the SDK:

class MyApplication : Application() {
    
    override fun onCreate() {
        super.onCreate()
        
        Grow.start(
            applicationContext,
            Grow.ConfigurationBuilder(apiKey = "UKoJbzWq5Fz5hA")
                .setIsTestModeEnabled(true) // Should be false for release to production
                .build()
        )
    }
}

Checking configuration

When the app is started, meaning it was not installed or completely closed/killed before opening, the following logs should be printed in the console:

-----------------------------------------------------
Grow SDK v1.0.2
Package name: com.company.myapp
Device id: c094d241-3781-4568-a1e2-635c196941d5
-----------------------------------------------------
[Grow.Configuration]
API Key: UKoJbzWq5Fz5hA
Url Protocol: https
Configuration Domain: valet.bryj.ai
Is Verbose Enabled: true
App Link Domains: null
Is Analytics Enabled By Default: false
-----------------------------------------------------

Then look for the api/configuration request response, it should be {"domain":"valet.bryj.ai"}:

Request POST /api/configuration - Response content {"domain":"valet.bryj.ai"}

This means the bundle id and the api key are known by the platform and the SDK has properly established communication with the server.

Checking push integration

To verify the push integration is OK, look for the api/deviceInfo request content, it should contain the pushToken field filled with a value:

Request POST https://valet-data.valet.bryj.ai/api/deviceInfo
{"type":"phone","manufacturer":"Google","model":"sdk_gphone64_x86_64","analyticsEnabled":0,"notificationsEnabled":1,"pushToken":"dp1NQjjGSKugdAQ3FM2xN_:APA91bF2vsyoSSof785NttFl0qCXHZADFIsFWvwmfNx6VcUiNrRqgkWKbUWvqV6GkMChPfeekj6ZkeRmC12U4G9fypKsY3cBP2-ZKuwr-epFaQFrWex6Yc1-h-kIEAKdMdYa-OeIQOTP","pushType":2,"osVersion":"12","lang":"eng","timeZone":7200,"timeZoneName":"Europe\/Paris","trackingAllowed":0}

This means the push token has been sent to the server and that the platform will be able to send push to this device as soon as the device id will be ingested.

Troubleshooting

1. No data in the GROW UI

If you notice your some dashboard cards related to app activity are not populated despite the fact you made some sessions:

  • Double check you are testing the correct app
  • Verify the device is opt-in analytics (Usage Guide – Analytics): an opt-out analytics will not send behavioral data

2. Request not Allowed

If you get, the “Request not allowed” error message in the console, this means the server has refused the SDK request at some point.

This can be for several reasons:

  • The app bundle id and the API key used in the SDK Configuration are not known by the platform. This message comes together with another message “either apiKey or applicationId doesn’t match an existing app on the Grow platform” which is printed only once by the SDK when it tries to retrieve the Server Configuration just after SDK is initialized. The SDK will retry to retrieve the Server Configuration from 4 hours after last retrieval attempt.
    To solve this, go to the Admins section on the platform, select your project and check that:
    • The bundle id is listed
    • The api key is the right one
    • Fix the problem and re-install the app to not have to wait for the 4 hours delay
  • The app requests limit has been reached. The SDK will retry to send requests from 24 hours after the first refused request.
  • The app has been revoked on the platform. The SDK will never retry to send any requests.

Advanced – Usage Guide

Device

These methods allow you to identify users and manage notification and tracking consent

From the Device interface you have access to:

  • User identifier
  • Device identifier
  • Analytics enabled
  • Open Notification Settings If Needed Get Notifications Allowed
  • Request Notifications Authorization (iOS only)
  • Request Provisional Notifications Authorization (iOS only)

Identify Users

The following methods allow you to retrieve or value an identifier.

The Device ID is generated by GROW. It is not editable.

Retrieving User Identifier

val userId = Grow.Device.getUserId()
String userId = Grow.Device.getUserId()

Updating User Identifier

Grow.Device.setUserId("new_user_id")
Grow.Device.setUserId("new_user_id");

Retrieving Device Identifier

val deviceId = Grow.Device.getDeviceId()
String deviceId = Grow.Device.getDeviceId()

Analytics

The following methods allow you to manage user analytics by GROW SDK.

For reporting activity logs from the tagging plan (User Identifier, Attributes & Events), analytics must be enabled in the SDK.

By default, analytics are disabled and can be turned on by changing the analytics state of the SDK

Retrieving Analytics Enabled Status

val analyticsEnabled = Grow.Device.getAnalyticsEnabled()
boolean analyticsEnabled = Grow.Device.getAnalyticsEnabled()

Updating Analytics Status

val enabled = true/false
Grow.Device.setAnalyticsEnabled(enabled)
boolean enabled = true/false;
Grow.Device.setAnalyticsEnabled(enabled);

Events

These methods are dedicated to the implementation of the tagging plan. They allow you to define events to track the activity of your users

These methods only will work with users who are “opt-in analytics”

From the Events interface, you have access to:

  • Custom events
  • Location events

Send a Simple Custom event

val name = "event_name"
Grow.Events.Custom.create(name).send()
String name = "event_name";
Grow.Events.Custom.create(name).send();

Send a Custom Event with a Parameter

val name = "event_name"
val value = "Parameter value"
val key = "a_key"

Grow.Events.Custom.create(name)
                  .put(key, value)
                  .send()
String name = "event_name";
String value = "Parameter value";
String key = "a_key";

Grow.Events.Custom.create(name)
                  .put(key, value)
                  .send();

Send a Location Event

If you wish, you can log the GPS coordinates of your users if they have their GPS enabled and the application is authorized to use these coordinates.
var location = Location("")
location.altitude = 0.1
location.longitude = 0.1
Grow.Events.Location.send(location)
Location location = new Location("");
location.setAltitude(0.1);
location.setLongitude(0.1);
Grow.Events.Location.send(location);

Attributes

These methods are dedicated to the implementation of the tagging plan. They allow you to define the status of a user based on its activity.

These methods will only work with users who are “opt-in analytics”.
Attributes require a defined user identifier.

From the Attributes interface, you have access to:

  • String attributes
  • Number attributes
  • Boolean attributes
  • Date attributes

String Attributes

Setting a String Attribute

val value = "Attribute value"
val key = "a_key"
Grow.Attributes.setString(key, value)
String value = "Attribute value";
String key = "a_key";
Grow.Attributes.setString(key, value);

Removing a String Attribute

val key = "a_key"
Grow.Attributes.setString(key, null)
String key = "a_key";
Grow.Attributes.setString(key, null);

Number Attributes

Setting a Number Attribute

val value = 10
val key = "a_key"
Grow.Attributes.setNumber(key, value)
Number value = 10;
String key = "a_key";
Grow.Attributes.setNumber(key, value);

Removing a Number Attribute

val key = "a_key"
Grow.Attributes.setNumber(key, null)
String key = "a_key";
Grow.Attributes.setNumber(key, null);

Boolean Attributes

Setting a Boolean Attribute

val value = true
val key = "a_key"
Grow.Attributes.setBoolean(key, value)
boolean value = true;
String key = "a_key";
Grow.Attributes.setBoolean(key, value);

Removing a Boolean Attribute

val key = "a_key"
Grow.Attributes.setBoolean(key, null)
String key = "a_key";
Grow.Attributes.setBoolean(key, null);

Date Attributes

Setting a Date Attribute

val value = Date()
val key = "a_key"
Grow.Attributes.setDate(key, value)
Date value = new Date();
String key = "a_key";
Grow.Attributes.setDate(key, value);

Removing a Date Attribute

val key = "a_key"
Grow.Attributes.setDate(key, null)
String key = "a_key";
Grow.Attributes.setDate(key, null);

Campaigns

The following methods allow you to pause and resume the display of in-apps in specific paths of your application.

Pausing Campaign Display

Grow.Device.pauseInAppDisplaying()
Grow.Device.pauseInAppDisplaying();

Resuming Campaign Display

Grow.Device.resumeInAppDisplaying()
Grow.Device.resumeInAppDisplaying();

Privacy

These methods allow you to manage the collection and deletion of your users’ data.

From the Privacy interface, you have access to:

  • Request to Collect Data
  • Request to Erase Data
  • Request to Remove Account
  • Set Tracking Allowed

Request to Collect Data

Grow.Privacy.requestToCollectData()
Grow.Privacy.requestToCollectData();

Request to Erase Data

Grow.Privacy.requestToEraseData()
Grow.Privacy.requestToEraseData();

Request to Remove Account

Grow.Privacy.requestToRemoveAccount()
Grow.Privacy.requestToRemoveAccount();

Set Tracking Allowed

The purpose of this method is to track the status of the device related to the consent of sharing data with third-parties.
val allowed = true/false
Grow.Privacy.setTrackingAllowed(allowed)
boolean allowed = true/false;
Grow.Privacy.setTrackingAllowed(allowed);