Add the Android SDK to your app

Overview

You can implement mobile app messaging in your Android apps with Firebase Cloud Messaging (FCM).

Before you begin

Create a Google API project with Firebase Cloud Messaging

If you do not already have a Google API project, create one with Firebase Cloud Messaging.

  1. In your app’s project in Android Studio, go to the Tools menu and open Firebase. A Firebase Assistant pane opens.
  2. Select Cloud Messaging and then click Set up Firebase Cloud Messaging.

📘

Note:

If you are using the application with FCM for the first time, click Connect to Firebase.

  1. Click Add FCM to your app.
  2. Go to the Firebase Cloud Messaging console and click on your app while logged into your Google account.
  3. Click the app’s options icon and then select Project Settings.
  4. Open the Cloud Messaging tab, and from the Project Credentials section, copy the Server key.
  5. Provide this key when you configure the mobile apps in the Campaign user interface. For more information, see Add and configure mobile developer apps.

Configure the Android studio project

Set messagingService to FCM in the MceConfig.json file.

"messagingService": "fcm",

Download and add the SDK to your project

After you register your Android app, you must implement it so that you can start testing and creating notifications.

📘

TIP:

Google recommends not installing your app on external storage cards for several reasons, as stated on their developer site at App install location. You should instead install your app on the internal memory.

  1. Download the latest release of our Android SDK.
  2. Add the Android SDK to your project.

Add the Android SDK to your Gradle project by copying the Android SDK AAR file to your libs folder. If you do not have a libs folder, create one next to your src folder.

If you have your project does not use gradle, follow these steps.

  1. Create a folder in your project called libs, and move the SDK AAR file into it. You can find the SDK AAR file in the bin directory after you extract the SDK package.
  2. In Eclipse, select your project, right-click and select Properties.
  3. In the Properties window, select Java Build Path.
  4. Then open the Libraries tab and click ADD JARs.
  5. Browse to the Android SDK AAR file in the libs folder.

  1. Next, in your build.properties file, make sure that you have the following code in the dependencies section, where <play-services version> is the latest version of the play-services package.
dependencies {
 implementation fileTree(dir: 'libs', include: ['*.jar'])
 implementation fileTree(dir: 'libs', include: ['*.aar'])
 implementation 'com.google.android.gms:play-services-base:<play-services version>'
 implementation 'com.google.firebase:firebase-messaging:<play-services version>'

Additionally, if you intend to support location services, add the following line:

implementation 'com.google.android.gms:play-services-location:<play-services version>'

📘

Note:

Ensure that your gms dependencies and the FCM dependencies use the same version. For example, the following gms and FCM dependencies use 11.8.0.

  • com.google.android.gms:play-services-base: 11.8.0
  • com.google.firebase:firebase-messaging: 11.8.0
  • com.google.android.gms:play-services-location: 11.8.0

Update the SDK configuration

Modify the following in the AndroidManifest.xml file.

  1. Set the minimum Android SDK version to 19 (Android 4.4) or higher in your application’s build.gradle file or AndroidManifest.xml file. For simple push support (no inbox, no DLA, etc.), you can set the Android SDK version to 16 or higher. The 3.x Android SDK is not supported with API 15 or lower. The target version should be the latest release version of Android that we have tested against per the release notes.
  2. If you use our location support, add the required permissions and services to the SDK configuration for your app. For more information, see Configure the SDK for DLA
  3. The SDK sets the default application class to co.acoustic.mobile.push.sdk.api.MceApplication. If you want to replace it, you need to set android:name in the manifest and add android:name to tools:replace

If you implement your own application class, replace YOUR_APP_PACKAGE_NAME with your package name.

You can use the following as a template for your application class:

package YOUR_APP_PACKAGE_NAME;
import android.annotation.TargetApi;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Build;
import co.acoustic.mobile.push.sdk.api.MceApplication;
import co.acoustic.mobile.push.sdk.api.MceSdk;
import co.acoustic.mobile.push.sdk.api.notification.NotificationsPreference;
public class MyApplication extends MceApplication {
 public void onCreate() {
 super.onCreate();
 if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O) {
 createNotificationChannel(getApplicationContext());
 }
 }@
 TargetApi(26) private static void createNotificationChannel(Context context) {
 String MY_SAMPLE_NOTIFICATION_CHANNEL_ID = context.getString(R.string.notif_channel_id);
 NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
 NotificationChannel channel = notificationManager.getNotificationChannel(MY_SAMPLE_NOTIFICATION_CHANNEL_ID);
 if (channel == null) {
 CharSequence name = context.getString(R.string.notif_channel_name);
 String description = context.getString(R.string.notif_channel_description);
 int importance = NotificationManager.IMPORTANCE_HIGH;
 channel = new NotificationChannel(MY_SAMPLE_NOTIFICATION_CHANNEL_ID, name, importance);
 channel.setDescription(description);
 NotificationsPreference notificationsPreference = MceSdk.getNotificationsClient().getNotificationsPreference();
 notificationsPreference.setNotificationChannelId(context, MY_SAMPLE_NOTIFICATION_CHANNEL_ID);
 notificationManager.createNotificationChannel(channel);
 }
 }
}

The application class refers to the following strings that you will need to add to strings.xml:

<string name="notif_channel_id">my-notification-channel</string>
<string name="notif_channel_name">My sample notification channel</string>
<string name="notif_channel_description">My sample notification channel description</string>
  1. You must set a default notification channel as well. Add the following to your <application> node in AndroidManifest.xml:
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/notif_channel_id" /

Optional: If you implemented a MceBroadcastReceiver, be sure to add it to AndroidManifest.xml below the <application> node:

<receiver android:name=".MyMceBroadcastReceiver">

<intent-filter>

<action android:name="co.acoustic.mobile.push.sdk.NOTIFIER" />

</intent-filter>

</receiver>
  1. If you intend to send push notifications of type DIAL or URL, add the following to your manifest at the same level as the node:
    <queries>
        <!-- Required for handling notifications that open the devices dialer app -->
        <intent>
            <action android:name="android.intent.action.DIAL" />
            </intent>   
        <!-- Required for handling notifications that open URLs -->
        <intent>
            <action android:name="android.intent.action.VIEW"/>
            <data android:scheme="https"/>
        </intent>
    </queries>
    
    You can selectively remove any of these nodes. If you remove a node and then send a push notification using the removed support, the push notification will only open the app. It will not invoke the expected action. This requirement was introduced by Android at API 31+.
  2. Configure your Android app not to back up inappropriate SDK files. For more information, see Automated Restores on Android.

Set the SDK properties

You have two options for setting properties: using the MceConfig.json properties file or the MceSdkConfiguration object. The most common way is by copying MceConfig.json from one of the sample apps in the SDK into your app/src/main/assets directory. We also provide a way to configure using API.

  • Using the MceConfig.json properties file - For more information, see Configuration (MceConfig.json).
  • Using the MceSdkConfiguration object - To set the SDK configuration in the application code using the MceSdkConfiguration object, ensure that the application class is not a MceApplication and that you call the MceApplication init method with a MceSdkConfiguration object. If you do not set a config property, the default value is used.
    For more information, see Modify the SDK initialization control for alternate Android integration.

📘

Note:

You can add encryption to the Android SDK database. for more information, see Android SDK Database Encryption.

Example for MceSdkConfiguration object:

import co.acoustic.mobile.push.sdk.api.MceApplication;
import co.acoustic.mobile.push.sdk.api.MceSdkConfiguration;
import co.acoustic.mobile.push.sdk.api.SdkInitLifecycleCallbacks;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class SampleApplication extends Application {

 @Override
 public void onCreate() {
 super.onCreate();
 String appKey = "<YOUR APP KEY>";
 MceSdkConfiguration mceSdkConfiguration = new MceSdkConfiguration(appKey,"");

 mceSdkConfiguration.setBaseUrl("<YOUR BASE URL>");

 mceSdkConfiguration.setMessagingService(MceSdkConfiguration.MessagingService.fcm);
 mceSdkConfiguration.setGroupNotificationsByAttribution(true);

 mceSdkConfiguration.setLogBufferSize(10);
 mceSdkConfiguration.setLogFile(true);
 mceSdkConfiguration.setLogIterationDurationInHours(1);
 mceSdkConfiguration.setLogLevel(Logger.LogLevel.error);

 mceSdkConfiguration.setMetricTimeInterval(300);

 mceSdkConfiguration.setSessionsEnabled(true);
 mceSdkConfiguration.setSessionTimeout(20);
 mceSdkConfiguration.setUseFileImageCache(true);
 mceSdkConfiguration.setUseInMemoryImageCache(true);
 mceSdkConfiguration.setFileImageCacheCapacityInMB(200);
 mceSdkConfiguration.setInMemoryImageCacheCapacityInMB(20);
 
 
MceSdkConfiguration.LocationConfiguration.SyncConfiguration syncConfiguration = mceSdkConfiguration.getLocationConfiguration().getSyncConfiguration();
 try {
 syncConfiguration.setProviderPreferences(new JSONArray("[\"gps\", \"network\"]"));
 } catch (JSONException e) {
 }
 syncConfiguration.setLocationResponsiveness(300);
 syncConfiguration.setSyncInterval(300);
 syncConfiguration.setSyncRadius(100000);
 syncConfiguration.setMinLocationsForSearch(1);
 syncConfiguration.setMaxLocationsForSearch(20);

 MceSdkConfiguration.LocationConfiguration.IBeaconConfiguration iBeaconConfiguration = mceSdkConfiguration.getLocationConfiguration().getiBeaconConfiguration();
 iBeaconConfiguration.setUuid("<YOUR UUID>");
 iBeaconConfiguration.setBeaconForegroundScanDuration(5);
 iBeaconConfiguration.setBeaconForegroundScanInterval(30);
 iBeaconConfiguration.setBeaconBackgroundScanDuration(30);
 iBeaconConfiguration.setBeaconBackgroundScanInterval(300);


 MceApplication.init(this, mceSdkConfiguration, new SdkInitLifecycleCallbacks() {
 @Override
 public void handleMetadata(Bundle bundle) {

 }

 @Override
 public void onPluginActionLoad(JSONObject jsonObject) {

 }
   
 @Override
 public void onPluginNotificationTypeLoad(JSONObject jsonObject) {

 }

 @Override
 public void onStart(MceSdkConfiguration mceSdkConfiguration) {

 }
   
 @Override
 public void onSdkReinitializeNeeded(Context context) {

 }  
 });
 }
}

📘

Note:

You will need to request some permissions explicitly. See Device Location Awareness (DLA) for details.

Monitor events in the Android SDK

Implement MceBroadcastReceiver if you want to monitor events in the Android SDK, such as SDK registration, FCM registration, and notification received. Create a new MceBroadcastReceiver implementation class. The following example shows how to create a new MceBroadcastReceiver implementation class with FCM:

package YOUR_APP_PACKAGE;
import android.content.Context;
import java.util.Date;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import co.acoustic.mobile.push.sdk.api.MceBroadcastReceiver;
import co.acoustic.mobile.push.sdk.api.attribute.AttributesOperation;
import co.acoustic.mobile.push.sdk.api.event.Event;
import co.acoustic.mobile.push.sdk.api.notification.NotificationDetails;
import co.acoustic.mobile.push.sdk.location.MceLocation;
import co.acoustic.mobile.push.sdk.api.broadcast.EventBroadcastUtil;
import java.util.List;
public class MyMceBroadcastReceiver extends MceBroadcastReceiver 
	{
	@Override
 public void onSdkRegistered(Context context) {
 // Handle the SDK registration event
 // context - The application context
 }
	@Override
 public void onMessagingServiceRegistered(Context context) {
 // Handle the FCM registration event
 // context - The application context
 }
	@Override
 public void onSdkRegistrationChanged(Context context) {
 // context - The application context
 }
	@Override
 public void onSdkRegistrationUpdated(Context context) {
 // context - The application context
 }
	@Override public void onMessage(Context context, NotificationDetails notificationDetails, Bundle extraPayload) {
 // Handle the notification received event
 // context - The application context
 // notificationDetails - The received notification
 // extraPayload- Additional payload that arrived with the notification
 }
	@Override
 public void onSessionStart(Context context, Date sessionStartDate) {
 // context - The application context
 // sessionStartDate- The new session start time
 }
	@Override
 public void onSessionEnd(Context context, Date sessionEndDate, long sessionDurationInMinutes) {
 // context - The application context
 // sessionEndDate- The session end time
 // sessionDurationInMinutes - The session duration in minutes 
 }
	@Override
 public void onNotificationAction(Context context, Date actionTime, String pushType, String actionType, String actionValue) {
 // context - The application context 
 // actionTime- The time the action was clicked on
 // pushType - always "simple"
 // actionType - The type of the action
 // actionValue - the value of the "value" key in the payload.
 }
	@Override
 public void onAttributesOperation(Context context, AttributesOperation attributesOperation) {
 // context - The application context
 // attributesOperation - The operation that was executed
 }
	@Override
 public void onEventsSend(Context context, List < Event > list) {
 // context - The application context
 // events- The events that were sent 
 }
	@Override
 public void onIllegalNotification(Context context, Intent intent) {
 // context - The application context
 // intent- The intent that contains the illegal notification
 }
	@Override
 public void onNonMceBroadcast(Context context, Intent intent) {
 // context - The application context
 // intent- The intent that contains the non MCE broadcast
 }
 /**
 * This method is called when a location event occurs
 * @param location The related location
 * @param locationType The related location type
 * @param locationEventType The related location event type
 */
 public void onLocationEvent(Context context, MceLocation location, LocationType locationType, LocationEventType locationEventType) {
 // do something interesting with the location event
 };
 /**
 * This method is called when the device location is updated
 * @param context The application's context
 * @param location The device location
 */
 public void onLocationUpdate(Context context, Location location) {
 // do something interesting with the location update
 }
	@Override
 public void onReceive(Context context, Intent intent) {
 Log.i(getClass().getSimpleName(), "Received intent: " + intent.toString());
 if (intent == null || intent.getAction() == null) {
 return;
 }
 try {
 EventBroadcastUtil.handleBroadcast(context, intent, this);
 } catch (Throwable t) {
 Log.e(getClass().getSimpleName(), "Unexpected error on receive: ", t);
 }
 }
	@Override
 public void onC2dmError(Context context, String errorId) {
 Log.i(getClass().getSimpleName(), "C2DM errorId: " + errorId);
 }
}

Enable multiple FCM providers

If your app must support push notifications from two sources (Acoustic and another source), then you can implement the following code to allow both push services to co-exist within your app.

  1. Add a class to support FCM messages: For example create
    class MyFirebaseMessagingService extends FirebaseMessagingService.
  2. Add import co.acoustic.mobile.push.sdk.api.fcm.FcmApi;
  3. Add the following code to public void onMessageReceived(RemoteMessage remoteMessage) method.:
If (FcmApi.isFcmMessage(remoteMessage)) {
    FcmApi.handleMceFcmMessage(getApplicationContext(), remoteMessage);
    return;
}
else {
// this is not sdk message. Handle it here
}
  1. Replace FcmMessagingService in your manifest with your FCM message handler class. In this example, it’s MyFirebaseMessagingService.
<!-- FCM Messages -->
   <service
       android:name=".MyFirebaseMessagingService">
<!-- replace android:name="co.acoustic.mobile.push.sdk.fcm.FcmMessagingService" With
  android:name=".MyFirebaseMessagingService"
-->
       <intent-filter>
           <action android:name="com.google.firebase.MESSAGING_EVENT"/>
       </intent-filter>
   </service>

When FCM notification arrives,

  • The OS calls MyFirebaseMessagingService::onMessageReceived().
  • The code checks if the message is from Acoustic. A message from Acoustic has “alert”: in the sub-document message payload.
  • If the payload is from Acoustic, the SDK handles the message and returns it. Otherwise, the message is handled by MyFirebaseMessagingService.

For more information, see Android SDK messaging API.