Mobile SDK

Android SDK Integration Manual

The Messangi Android library is designed to work in an automated way, that simplifies its inclusion in projects in development or already developed without affecting the main development cycle.

The library is designed to work with a minimum API level of 15, so it works on more than 98% of current Android devices according to official statistics by Google.

The development of an application using this library requires Java version 8. To activate this, in the file build.gradle (Module: app) the field compileOptions must be added, it can be guided with the code below

    android {
        ...
        defaultConfig {  
            ....
        }

        compileOptions {  
            targetCompatibility 1.8  
            sourceCompatibility 1.8  
        }
    }

If your project was working with Java 7 don’t worry, everything will continue working. This requirement optimizes the code produced by the Java Virtual Machine (JVM) to get a more efficient code.

Once the project is configured to compile using Java 8, the library can be included. Messangi library works along with Google's Firebase platform, in order to deliver pushes to all Android devices associated with the app. Messangi library is distributed through JCenter, so it is available to any developer who wants to use it.

Add all dependencies in build.gradle (Module: app) as follows:

    ...  
    android {  
        ...  
    }  

    dependencies {  
        ...
        implementation 'com.google.firebase:firebase-core:16.0.8'
        implementation 'com.google.firebase:firebase-messaging:17.3.4'
        implementation 'com.ogangi.messangi.android.sdk:messangisdk:5.2.2'
        implementation 'com.ogangi.messangi.android.sdk:messangi-push:5.2.2'
        ...
    }
    ...

To configure the Firebase Cloud Messaging into your project, you need to perform a few basic tasks to prepare your Android Studio project.

First, add rules to your root-level build.gradle file, to include the google-services plugin and the Google and JCenter repositories (check first if they’re not already included)

    buildscript {  
        // ... 
        dependencies {  
            // ... 
            classpath 'com.google.gms:google-services:4.3.1' // google-services plugin  
        }
    }

    allprojects {
        // ... 
        repositories {
            google()
            jcenter()
            // ...
        }  
    }

Then, in your module Gradle file (usually the app/build.gradle), add the apply plugin line at the bottom of the file to enable the Gradle plugin:

    apply plugin:  'com.android.application'
    android {  
        // ...  
    }
    dependencies {  
        // ... 
    }  
    // ADD THIS AT THE BOTTOM
    apply plugin: 'com.google.gms.google-services'

To add Firebase to your app you'll need a Firebase project and a Firebase configuration file for your app.

  1. Create a Firebase project in the Firebase console, if you don't already have one. If you already have an existing Google project associated with your mobile app, click Import Google Project. Otherwise, click Add project.
  2. Click Add Firebase to your Android app and follow the setup steps. If you’re importing an existing Google project, this may happen automatically and you can just download the config file.
  3. When prompted, enter your app’s package name. It's important to enter the package name that your app is using; this can only be set when you add an app to your Firebase project.
  4. At the end, you’ll download a google-services.json file. You can download this file again at any time.
  5. If you haven’t done so already, copy that file into your project’s module folder, typically app/.

Note: If you have multiple build variants with different package names defined, each app must be added to your project in Firebase console.

Resources to share with us

To be able to send notifications through Firebase it is necessary to share the Server Key and Sender ID with the support team

  1. Open a Firebase project previously created in the Firebase console.
  2. In the top left corner of the screen, click on the little cogwheel and select Project settings
  3. On the new page, go to the Cloud Messaging tab. Your Sender ID and Server key are listed here. Please send to our support team the Server Key and the google-services.json file.

Messangi.xml file

The Support Team will send you back a file named messangi.xml, this must be added in the directory src/main/res/values of your app

The Messangi library initially provides an automatic user authentication method, this means that, when the application is started by the first time, it automatically creates an identifier for the device and for the user that make use of it. To access that information the class MessangiInstanceId has the following methods:

// Get the device identifier
MessangiInstanceId.getInstance().getDeviceID();  
 
// Get the User identifier  
MessangiInstanceId.getInstance().getUserID();
 
// Get the time when user was created  
MessangiInstanceId.getInstance().getCreationTime();

However in some cases this is not enough and the developer wants to control life cycle of the user in application or use their own identifier. For these cases the library has the following methods:

  • Register User
    String userId = ...;
    MessangiApp.getInstance().login(userId);
  • Delete user registration (This will also remove all notifications, geofences and beacons registered in the device)
    MessangiApp.getInstance().logout();
  • Register with another ID
    MessangiInstanceId.getInstance().resetUserId();

If you want to avoid the predefined behavior of generating a unique random identifier for your user and set it yourself using login method, you must modify the auto_register field to false in the messangi.xml configuration file.

Finally, the developer can add an event listener to verify when the device is correctly registered and ready to receive push notifications. If it is ready when the listener is added, it will fire at once.

    MessangiInstanceId.getInstance().addOnDeviceReadyListener(() -> {  
       // Device ready to receive push notifications   
    });

If you don’t use any of these methods, the same system will receive push notifications making use of the autogenerated identifiers by the library.

Push Reception Library (Option 1)

If you use Messangi Push Library and need having information about the generation of the push token, you can use the class MessangiInstanceId and the following methods:

    // Get the last received push token (can be null)
    MessangiInstanceId.getInstance().getPushToken();  
 
    // Receives updates automatically when a token update occurs
    MessangiInstanceId.getInstance().addOnTokenRefreshListener(token -> {  
          log.d("token_update" , token);
    });

If you already have Push Notifications Reception implemented in your application, the inclusion of this Library is not necessary.

Self Implementation (Option 2)

If you already have your own implementation for push reception or you want to do it by your own, we provide the following methods, which should be called by your application:

  • Create or update push token

When the push token is created or updated, it must be notified to the library to keep it synchronized in the cloud. This is done by the following method:

    //Push Token Provided by Firebase Push Service 
    String token = FirebaseInstanceId.getInstance().getToken(); 
    MessangiInstanceId.getInstance().setPushToken(token);

MessangiInstanceId is the class for managing the push token on the server in order to receive push notifications.

  • Process a Push Notification When a Messangi Campaign Manager sends a Push Event to the application, it has a special format designed to be interpreted by the Messangi Library. The class MessangiEventManager is used for processing these remote events.
    @Override  
    public void onMessageReceived(RemoteMessage remoteMessage) { 
        // Handle data payload of FCM messages. 
        MessangiEvent event = 
            MessangiEvent.newBuilder()
                .withId(remoteMessage.getMessageId())  
                .withType(remoteMessage.getMessageType())  
                .withFrom(remoteMessage.getFrom())  
                .withSendTime(remoteMessage.getSentTime())  
                .withData(remoteMessage.getData())
                .build();
 
                MessangiEventManager.onEventReceived(getApplicationContext(), event);  
    }

In the example above we show the method that receives messages from Firebase Cloud Messaging, if you want to use some other Push Service, you must also build a MessangiEvent and add the payload of the notification with the method withData.

Displaying the Notifications

Messangi UI Library (Option 1)

The main Messangi Library processes, indexes and delivers notifications to the application that integrates it, but does not have tools to display notifications. For this purpose we provide Messangi UI Library, this library adds to your application the capability to show Messangi Notifications Events in devices' notification area.

To add this library, simply add it after the main libraries, in the file build.gradle (Module: app) at level of dependencies.

    dependencies {  
        ...
        implementation 'com.ogangi.messangi.android.sdk:messangisdk:5.2.2'
        implementation 'com.ogangi.messangi.android.sdk:messangi-push:5.2.2'
        implementation 'com.ogangi.messangi.android.sdk:messangi-ui:5.2.2'  
        ...
    }  

This library is currently in active development, so in the next release we’ll provide more customization and configuration possibilities.

Broadcast Receiver (Option 2)

If you don’t want to use the previous library or want to control the visual representation of your notifications at a higher level, you can add a Broadcast Receiver to your application. For doing this you must create a class that extends BroadcastReceiver.

The intent delivers to you a receiver, a json representation of the message.

    public class MessangiReceiver extends BroadcastReceiver {
         private static final String TAG = "MessangiReceiver";
 
         public MessangiReceiver() {
         }
 
         @Override
         public void onReceive(Context context, Intent intent) {
            // The intent delivers a json representation of the push notification
            String json = intent.getStringExtra("message");
 
         }
    }

Then in the AndroidManifest.xml you must add the following permission:

    <uses-permission android:name="${applicationId}.permission.pushReceive"/>

And also there, inside application tag, the reference to the broadcast receiver:

     <receiver
         android:name=".MessangiReceiver"
         android:enabled="true"
         android:exported="false">
         <intent-filter>
             <action android:name="com.ogangi.messangi.android.sdk.PUSH_NOTIFICATION" />
        </intent-filter>
     </receiver>

Now you have all the necessary information to customize your notification as you prefer.

Notification handling

The Messangi Library maintains a virtual inbox, it stores all the notifications received by the library, to manipulate this inbox we provide the class MessangiNotificationManager. The class has the following methods:

  • List all notifications on the inbox
    MessangiNotificationManager.getInstances().getNotifications();  
  • Delete a single notification (you must have an instance of it previously)
    MessangiNotificationManager.getInstances().deleteNotification(notification);  
  • Delete all notifications inside inbox
    MessangiNotificationManager.getInstances().clearNotifications();  
  • Force synchronization of notifications with the server
    MessangiNotificationManager.getInstances().syncronize();  

If you want to add a listener that notifies you when a notification arrives, you can use this method (only works when the app is running):

    MessangiNotificationManager.getInstances()
        .addOnNotificationReceiveListener(message -> {  
           Log.d("MESSAGE", message.toString());   
        });

The Campaign Manager can remotely remove notifications on the devices, so the removal process can be activated remotely by multiple triggers.

Android starting on version 6 (Marshmallow) adds a permissions policy that requires displaying a dialogue requesting permission to collect certain information from device sensors. For this reason if you want to use features such as Geofences, Geopush or obtain precise information regarding the location of the device, you must request the location permission, by adding it in your AndroidManifest.xml file:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package=...>
    ...
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    ...
    <application
        ...
    </application>
 
</manifest>

and using the following code:

    final int REQUEST_LOCATION = 99;
 
    if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        String[] permissions = new String[]{ android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}
        ActivityCompat.requestPermissions(this, permissions, REQUEST_LOCATION);  
    }

For more information about permissions you can consult the official documentation

Location

If you want to receive updates of the location or configure the refresh rate using the Messangi Library, you can use the MessangiLocationManager class

  • Receive Location Updates
    MessangiLocationManager.getInstance()
        .addOnLocationUpdateListener(location -> {  
            Log.d("LOCATION", location.toString());  
        });
  • Get the last known location
    Location location = MessangiLocationManager.getInstance().getLastKnownLocation();
  • Configure the location service
    // Element by Element
    MessangiLocationManager.getInstance().enableLocation(true);
    MessangiLocationManager.getInstance().setFasterInterval(30000);
    MessangiLocationManager.getInstance().setLocationPriority(1);
    MessangiLocationManager.getInstance().setLocationUpdateTime(60000);
 
    // Using a Configuration Object
    LocationOptions options = LocationOptions.newBuilder()  
            .setEnable(true)  
            .setFasterInterval(30000)  
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)  
            .setUpdateTime(60000)  
            .build();  
    MessangiLocationManager
        .getInstance()
        .updateLocationOptions(options);

Geofences

The geofences are regions that trigger an action when are traversed. When the device detects this trigger, it sends a notification to the Campaign Manager so it produces some action configured on it, so it’s required to have data connection at the time the event is triggered. To make use of it, the library has the class MessangiGeofenceManager and with it you can call the following methods:

  • Get all the geographic regions that are being monitored.
    MessangiGeofenceManager.getInstances().getGeofences();    
  • Synchronize the information between the Campaign Manager and the Device.
    MessangiGeofenceManager.getInstances().synchronize();
  • Restart monitoring of all regions
    MessangiGeofenceManager.getInstances().restartGeofences();  

Beacons

Beacons are devices that emit a signal around them in a small area that depends on the beacon itself. When the device detects this zone, it sends a notification to the Campaign Manager so that it produces some action configured on it, so it’s required have data connection at the time the event is triggered. For the management of these, the library provides the class MessangiBeaconManager with the following methods:

  • Get all Beacons that are being monitored
MessangiBeaconManager.getInstance().getBeacons()  
  • Get only the beacons based on Wifi technology
MessangiBeaconManager.getInstance().getWifiBeacons()  
  • Synchronize the information between the campaign manager and the device
MessangiBeaconManager.getInstance().synchronize();
  • Restart monitoring of all Beacons
    MessangiBeaconManager.getInstance().restartBeacons();  

Beacon technology constantly checks the environment of the device, so it can have quite strong battery costs. For this reason we provide a complete set of functions that configure the device refresh policy itself, in such a way that each application is the one that decides the level of impact it will have in battery consumption.

    // Creating an instance power saver class can improve battery life by 60% by slowing down scans when your app is in the background.
    MessangiBeaconManager.getInstance().setPowerSaver(false);
 
    // Allows devices with API 21+ will use the Android L APIs to scan for beacons, below 21 API use old Android Way
    MessangiBeaconManager.getInstance().useNewBeaconScanner(true);
 
    // Allow the library to use a tracking cache
    MessangiBeaconManager.getInstance().useTrackingCache(true);  
 
    // Set region exit period in milliseconds
    MessangiBeaconManager.getInstance().setRegionExitPeriod(30000);  
 
    // Turns on/off saving the state of monitored regions to persistent storage so it is retained over app restarts.
    MessangiBeaconManager.getInstance().useRegionStatePersistence(true);  
 
    // Enable or not automatically change between Background and Foreground modes. This method requires app restart.
    MessangiBeaconManager.getInstance().autoChangeScanMode(true);
 
    // This method notifies the beacon service that the application is either moving to background mode.
    MessangiBeaconManager.getInstance().scanInBackgroundMode();  
 
    // This method notifies the beacon service that the application is either moving to foreground mode.
    MessangiBeaconManager.getInstance().scanInForegroundMode();  
 
    /*
    * First parameter sets the duration in milliseconds of each Bluetooth LE scan cycle to look for beacons.  
    * Second parameter sets the duration in milliseconds between each Bluetooth LE scan cycle to look for beacons.
    */
    MessangiBeaconManager.getInstance().setForegroundPeriods(1500, 2000);  
 
    /*
    * First parameter sets the duration in milliseconds of each Bluetooth LE scan cycle to look for beacons.  
    * Second parameter sets the duration in milliseconds between each Bluetooth LE scan cycle to look for beacons.
    */
    MessangiBeaconManager.getInstance().setBackgroundPeriods(5000,10000);

Events can be generated in the Analytics platform via the MessangiAnalytics class. Please note Messangi Library automatically captures some events and sends them to the Platform.

You can access the MessangiAnalytics facility from any section of your app by using one of these methods:

    /*
     * This method adds any event you want to track on the platform. In the first parameter put the type, in the second a descriptive message and in the last a campaign name, this can be null.
     * The type is an enumeration class of the Messangi library, but the method is overloaded with a simple String type in case the programmer wishes to integrate his own events. 
     */
    MessangiAnalytics.getInstances().logEvent(eventType, message, campaignName);
 
    /*
     * This method informs a Crash in your application. In the first parameter put a descriptive message, in the second a campaign name and in the last the Exception raised.
     */
    MessangiAnalytics.getInstances().crashEvent(message, campaignName, exception);

These events will be shown along all the events being generated by the Library or the application itself in the corresponding dashboard.

EventType Description
INIT App was opened
ERROR Error was raised
PUSHRECEIVED Text Push Arrive
SUBSCRIBED_WORKSPACE The user join a workspace
UNSUBSCRIBED_WORKSPACE The user leave a workspace
SYNC_GEOFENCE When Geofences finished the synchronization
GEOFENCE_ENTER Trigger a Geofence Enter
GEOFENCE_ENTER_EXTRA_INFOContextual Device information on Enter
GEOFENCE_EXIT Trigger a Geofence Exit
GEOFENCE_EXIT_EXTRA_INFO Contextual Device information on Exit
WIFI_BEACON_CONNECT Trigger a Wifi Beacon Enter
WIFI_BEACON_DISCONNECT Trigger a Wifi Beacon Exit
BEACON_ENTER Trigger a BlueTooth Beacon Enter
BEACON_EXIT Trigger a BlueTooth Beacon Exit
PUSH_TOKEN_REGISTERED The user can start receiving Push on that device