The Acoustic Campaign Developer Hub

Welcome to the Acoustic Campaign developer hub. You'll find comprehensive guides and documentation to help you start working with Acoustic Campaign as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started    

Getting started with Mobile App Messaging in Android Apps that use Firebase Cloud Messaging (FCM)

Developers working with Android apps and Firebase Cloud Messaging (FCM) can follow the steps in this tutorial to implement mobile app messaging in their apps. The instructions describe how you can use the SDK’s Firebase message service or an external Firebase message service.

WARNING: When Acoustic Mobile App Messaging stores data that you send, the data is not encrypted. Acoustic Mobile App Messaging recommends that you do not transmit sensitive information in inbox, inapp, and mobile app messages. We do not encrypt the data in our databases or log files, or when stored on the device. If you must transmit sensitive information, encrypt the data before sending it and decrypt the data in memory on the device.

Prerequisites

To get started, you need:

  • An account with Acoustic Campaign.
    TIP: If you do not already have an Acoustic Campaign account, contact your Client Services representative or sales.
  • The latest stable version of the Mobile app messaging SDK for Android, which is available at https://github.com/Acoustic-Mobile-Push/android.
  • Information about supported platforms, sample app compatibility, and what’s new in the latest version of the Mobile app messaging SDK for Android. See Supported platforms.

Are you using Google Cloud Messaging (GCM)?

Do you have an existing project that uses GCM?
It is recommended that you migrate from GCM to FCM because Google has deprecated GCM. For information, see Migrating from Google Cloud Messaging (GCM) to Firebase Cloud Messaging (FCM) to get your code running under FCM.

Step-by-step

1. Create a Google API project 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.
  3. If you are using the application with FCM for the first time, click on Connect to Firebase and follow the instructions. Otherwise, skip to step 4.
  4. Click Add FCM to your app.
  5. Go to the Firebase Cloud Messaging console and click your app. You must be logged into your Google account. If you can’t find your app, click Add FCM to your app, as described in step 4, and then return to this page.
  6. Click the app’s options link and then select Settings.
  7. Use only the gms dependencies that are required for the SDK and the app, which include:
    • com.google.android.gms:play-services-base:<google play services version>
    • com.google.android.gms:play-services-location:<google play services version>
    • com.google.android.gms:play-services-maps:<google play services version>
    • com.google.android.firebase:firebase-messaging:<google play services version>
  8. 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.android.gms:play-services-location: 11.8.0
    • com.google.android.gms:play-services-maps: 11.8.0
    • com.google.firebase:firebase-messaging: 11.8.0
  9. Set messagingService to fcm in the MceConfig.json file.
"senderId":"",
 "messagingService": "fcm",
  1. Optional: If you are using an external Firebase messaging service instead of the SDK’s Firebase messaging service, you can use co.acoustic.mobile.push.sdk.api.fcm.FcmApi. This API provides two methods that let you pass fcm messages to the sdk:
    • public static boolean isFcmMessage(RemoteMessage remoteMessage)
      Checks if a remote message is a MCE remote message
    • public static void handleMceFcmMessage(Context context, RemoteMessage remoteMessage)
      Handles a MCE fcm message in the sdk

For example, add the following to the sample app:

package co.acoustic.mobile.push.samples.gcm;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import co.acoustic.mobile.push.sdk.api.fcm.FcmApi;

public class SampleFirebaseMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        if(FcmApi.isFcmMessage(remoteMessage)) {
            FcmApi.handleMceFcmMessage(getApplicationContext(), remoteMessage);
        }
    }
}

2. Register your Android application in Acoustic Campaign.

You must register your Android app with Acoustic Campaign.

For more information about adding your app in Acoustic Campaign, see Add and configure mobile developer apps.

Restriction: Acoustic Campaign documentation contains information for marketers, app developers, and organization administrators and requires a user name and password. If you need a user name and password, contact your Client Services representative.

3. Implement the SDK

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

TIP: It is not recommended to allow your app to be installed on external storage cards for several reasons that Google states on the developer site at http://developer.android.com/guide/topics/data/install-location.html#Should. Your app should instead be installed on internal memory.

  1. Download the Android SDK as described in the Prerequisites.
  2. Add the Android SDK to your Gradle project by copying the Android SDK JAR file to your libs folder. If you do not have a libs folder, create one next to your src folder. 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>'

If you use location:

implementation 'com.google.android.gms:play-services-location:<play-services version>'
  1. Optional: If you do not have a Gradle project, follow these steps.
    a. Create a folder in your project that is called libs, and move the SDK JAR file to it. You can find the SDK JAR file in the root directory after you extract the SDK package.
    b. Select your project.
    c. Right-click properties.
    d. Choose java build path.
    e. Select libraries tab.
    f. Choose Add JARs, and browse to Android SDK JAR file in the libs folder.

  2. Modify the AndroidManifest.xml file in the sample app. Follow these steps.
    a. 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, you can set Android SDK version to 16 or higher. The 3.x Android SDK is not supported with previous versions of Android. The target version should be the latest release version of Android.
    Note: For Android SDK versions 16, 17, and 18, ensure that location services are disabled.
    b. Beacons – if the customer does not use the beacons feature, the following can be added to the manifest:

<uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" tools:node="remove"/>

<service android:name="co.acoustic.mobile.push.sdk.beacons.MceBluetoothScanner" tools:node="remove"/>
<service android:name="co.acoustic.mobile.push.sdk.beacons.BeaconsVerifier" tools:node="remove"/>

This will remove the beacons related sdk manifest entries.
c. Geofences- if the customer does not use the geofences feature, the following can be added to the manifest:

<receiver android:name="co.acoustic.mobile.push.sdk.location.GeofenceBroadcastReceiver" tools:node="remove"/>

This will remove the geofence related sdk manifest entries.
d. Location – if the customer does not use location at all, the following can be added to the manifest (in additionm to the geofences and beacons additions stated above):

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" tools:node="remove" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" tools:node="remove" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" tools:node="remove"/>

<receiver android:name="co.acoustic.mobile.push.sdk.location.LocationBroadcastReceiver" tools:node="remove"/>
<service android:name="co.acoustic.mobile.push.sdk.location.LocationRetrieveService" tools:node="remove"/>
<service android:name="co.acoustic.mobile.push.sdk.location.LocationEventsIntentService" tools:node="remove"/>
<service android:name="co.acoustic.mobile.push.sdk.location.LocationSyncAlarmListener" tools:node="remove"/>
<receiver android:name="co.acoustic.mobile.push.sdk.location.LocationUpdateCaller" tools:node="remove"/>

This will remove the location related sdk manifest entries.
e. 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, use the following instruction 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 class above refers to the following 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>

If you are targeting Android O or higher, you will have to set a default notification channel as well. Add this 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" /

f. If you implemented an MceBroadcastReceiver, be sure to add it to AndroidManifest.xml under the <application> node:

<receiver android:name=".MyMceBroadcastReceiver">

<intent-filter>

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

</intent-filter>

</receiver>

g. Configure your Android app not to back up inappropriate SDK files. See Automated Restores on Android.

  1. 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 via 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 by using the MceSdkConfiguration object, ensure that the application class is not an MceApplication and that you call the MceApplication init method with an MceSdkConfiguration object. If you do not set a config property, the default value is used.

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>";
 String senderId = "<YOUR SENDER ID>";
 MceSdkConfiguration mceSdkConfiguration = new MceSdkConfiguration(appKey, senderId);

 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 onStart(MceSdkConfiguration mceSdkConfiguration) {

 }
 });
 }
} 
  1. On new Android platforms, you will need to request some permissions explicitly. See Device Location Awareness (DLA) for details.

  2. 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);
 }
}

4. Set up your emulator for testing.

You can use the Android sample app in Android Studio to view and test the structure and features of the Android SDK. You use the sample app included in the SDK to teach you how to build a mobile app message and to show you the capabilities that are available. The sample app shows you the following information:

  • Credential and ID screens that display the following values: user ID, channel ID, development app key, and production app key.
  • A push action screen that displays the default and custom push actions that could be used when you send a mobile app message to your app users.
  • A custom action screen that displays details about the example categories you could use with the sample app.
  • Test events so you can send events to the server.
  • Test user attributes so you can send a user attribute to the server.

You can test the Android SDK by using either Eclipse ADT or Gradle.

  1. Go to acoustic-mobile-push-android-sdk-<version number>/samples/Demo. Make sure Demo is selected.
  2. Select the 1:Project tab.
  3. Set up your MceConfig.json to use your baseUrl, appKey, senderId and messagingService.
  4. If you’re not using the US server, go to app/assets/MceConfig.json and update your ‘baseUrl’ to your server’s URL. For example, eu is for European Union and a URL is for a different MCE server.
  5. When you create your Android Virtual Device (AVD), build a virtual device that is based on the
    Google Messaging API. A normal AVD results in silent failure.
    a. In Android Studio, select Tools > Android > SDK Manager, and make sure the “Google APIs” item is installed under the versions you are supporting.
    b. In Android Studio, select Tools > Android > AVD Manager.
    • Select New and enter a name.
    • Under Target, make sure to select an option that uses Google APIs, such as Google APIs (Google Inc.) – API Level 16.
    • After the device is created and started, you must also add an active Google account to the device through Settings > Accounts.
  6. Plug in an Android device into your machine, and run the app.
  7. Your emulator must be connected to a Google account for the FCM push to work. You can verify that the connection is initially working by sending an email to an account that was set up on your emulator.

5. To enable multiple FCM providers

  1. Add a class to support FCM messages: Example create
    class MyFirebaseMessagingService extends FirebaseMessagingService.

Add import co.acoustic.mobile.push.sdk.api.fcm.FcmApi;

Add the following code:

If (FcmApi.isFcmMessage(remoteMessage)) {
    FcmApi.handleMceFcmMessage(getApplicationContext(), remoteMessage);
    return;
}

To public void onMessageReceived(RemoteMessage remoteMessage) method.

  1. Replace FcmMessagingService in your manifest with your FCM message handler class. In this example it’s: MyFirebaseMessagingService.
<!-- FCM Messages -->
   <service
       android:name=".MyFirebaseMessagingService">
<!-- Rreplace 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, 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 came from Acoustic, the SDK handles the message and returns. Otherwise, the message is handled by MyFirebaseMessagingService.

Updated 10 days ago


Getting started with Mobile App Messaging in Android Apps that use Firebase Cloud Messaging (FCM)


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.