In-App Messaging

Leanplum comes with a number of in-app messaging templates, including alerts, confirmation screens, popups, and full-screen interstitials. They are open source, so you can customize them however you want, and you can even create your own templates.

To enable in-app messaging, you'll need to integrate the Leanplum SDK and run your app at least once in development mode.

On the dashboard, you can set in-app messages to automatically appear when certain events occur or when the app starts. These events must be tracked with our SDK. There's no additional coding needed.

Push Notifications

Leanplum supports both Firebase Cloud Messaging (FCM) and Google Cloud Messaging (GCM), but you can only use one of them at a time to deliver push notifications from Leanplum.

Android Notification Channels

See our guide to Using Android Notification Channels.

Customizing Push Notifications

You can customize the appearance of notifications using LeanplumPushService.setCustomizer in your Application class's onCreate method. From there, you can perform any customizations you want to the NotificationCompat object. You can also use the customizer to easily be notified of incoming pushes from Leanplum. You can access some of the notification's properties, like the message, using bundle.getString("lp_message"), and any custom values you defined in Advanced Options > Data in the message config through the dashboard.

For a detailed example, see our guide on customizing push notifications.

It's a good practice to show additional information or navigate to the correct part of your app when users open your push notifications. You can do that using Leanplum's in-app messaging, which integrates nicely with push notifications.

Location-based Messaging

You can set up geofence regions as criteria to trigger in-app messages and push notifications, right from the dashboard. To enable this functionality in your app, you must add a few keys in your AndroidManifest.xml file:

  1. Add the permission <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>: (Required for geofencing)
  2. Link the Google Play services library to your project and add the metadata in the application tag. <meta-data android:name="" android:value="@integer/google_play_services_version" /> (Required for geofencing)

Note that due to a limitation in Android, you can only have 100 regions active for your app at any given time. Leanplum optimizes usage by not monitoring regions for message campaigns whose targeting criteria exclude particular users.

App Inbox

App Inbox is a standalone messaging channel that doesn't require push certificates and can store messages for long periods of time.

To enable Inbox messaging, you'll need to integrate Leanplum Android SDK version 2.1.0 or higher in your app (older versions use Newsfeed). After that, you can instantiate the LeanplumInbox object by calling:


Getting data from Leanplum

Messages and Inbox data are retrieved from Leanplum on Leanplum.start(). The start method returns data asynchronously, so you should add a changed handler with the provided callback InboxChangedCallback, which will be called automatically when updates to the inbox are finished loading from Leanplum.

Here is a simple example of how you can use the callback to update the number of unread messages:

Leanplum.getInbox().addChangedHandler(new InboxChangedCallback() {
  public void inboxChanged() {

Because messages are only retrieved on start, a user will not receive a new message until they begin a new session. You can, however, use forceContentUpdate to re-sync with Leanplum mid-session, which will fetch any new App Inbox messages, and automatically invoke callbacks you have registered.

forceContentUpdate will also update all of your variables, user attributes, messages and A/B tests, so it can (depending on how your app is setup to work with Leanplum) affect the functionality and UI of your app. For more on forceContentUpdate, including some precautions, see Syncing with Leanplum mid-session.

Inbox message counts

After data is finished loading from Leanplum, you can get the total and unread count of messages using the LeanplumInbox object:

LeanplumInbox inbox = Leanplum.getInbox(); // instantiate new Inbox object
int unread = inbox.unreadCount();
int total = inbox.count();

Inbox messages

After data is finished loading from Leanplum, you can use the LeanplumInbox methods allMessages or unreadMessages to get a List of Message objects, either all or just the user's unread messages. This method currently returns a list of NewsfeedMessage objects, which you'll need to cast to the new InboxMessage objects.

List all = inbox.allMessages();
List<LeanplumInboxMessage> messages = (List<LeanplumInboxMessage>) all;
// Do stuff with messages.

Alternatively, you could use messagesIds to get a List of all the message IDs, then loop through the returned List and call messageForId with each messageId to fetch each message:

LeanplumInbox inbox = Leanplum.getInbox(); // instantiate new Inbox object
List<String> messagesIds = inbox.messagesIds(); // get all message IDs
for (String messageId : messagesIds) {
    LeanplumInboxMessage message = inbox.messageForId(messageId);
    // Do stuff with the message.

Message attributes

Once you have the Message object, you can access its title, subtitle, and deliveryTimestamp for display.

LeanplumInboxMessage message = inbox.messageForId(messageId);
String title = message.getTitle();
String subtitle = message.getSubtitle();
Date timestamp = message.getDeliveryTimestamp();

You can also easily test if a LeanplumInboxMessage is read:

if (message.isRead()) {
  // Do something if the message has been read.

Message image

We also support sending images with Inbox messages, although the feature is currently in beta (contact your Customer Success Manager for details on getting whitelisted).

If you haven't disabled automatic image downloads (image prefetching), you can get the image path on the device:

String imageFilePath = message.getImageFilePath();
Bitmap bitmap = BitmapFactory.decodeFile(imageFilePath);

If you want to disable automatic image downloads on sync (image prefetching), you can do so with the static method disableImagePrefetching before calling Leanplum.start().


If you do so, you'll need to get the image URL for each message using the LeanplumInboxMessage method getImageUrl, and then download the files yourself later, or use a third-party solution to manage this for you. If prefetch is enabled or the image has already been downloaded, getImageUrl will return the URI to the file on the device.

// Get the Image URL for a single LeanplumInboxMessage.
URL url = message.getImageUrl();
// Use the URL to download the image.

Handling user interactions

After a user reads the message, you need to explicitly set the LeanplumInboxMessage as read.;

You also need to explicitly remove the message from the Inbox if they delete it.


Updating from Newsfeed to Inbox

In previous versions of our Android SDK (>= 1.2.17 < 2.1.0), App Inbox is called Newsfeed. We renamed the classes (and added a bit more functionality to the new classes) in Android 2.1.0. Newsfeed is now LeanplumInbox and NewsfeedMessage is now LeanplumInboxMessage.

To update your code, you simply need to instantiate the Inbox with the new class and update your object types. For handling updates, you also need to switch to the new addChangedHandler method with an InboxChangedCallback for callbacks (these replace addNewsfeedChangedHandler and NewsfeedChangedCallback).

Since the LeanplumInbox and LeanplumInboxMessage classes have the same methods as the previous Newsfeed and NewsfeedMessage classes, actions like getting messages, getting message counts, marking messages as read, removing messages, etc. can be done as before using the same methods on the new classes.

Custom In-App Messaging Templates

The built-in in-app messaging templates are open-source. You can modify them or create your own. The dashboard will reflect your new templates the next time you run your app in development mode.

  1. Download the Leanplum Android SDK zip archive, if you haven't already. Refer to the Setup page for Install the SDK manually and follow Step 1 to download.
  2. Unzip the archive and look for src/com/leanplum/customtemplates.
  3. Add all of these files to your project, preserving the directory structure com/leanplum/customtemplates.
  4. Initialize them in your Application class (and before calling Leanplum.start()):

Study the provided files to see how the messages are implemented. To define a new template, use the method Leanplum.defineAction(). Here's how it works:

  • name: The name of the action or message type you are defining.
  • kind: One or more action kinds OR'ed together. Leanplum.ACTION_KIND_MESSAGE will appear in the Message Type list for creating message campaigns. Leanplum.ACTION_KIND_ACTION will appear in the dropdown when choosing an action within a message.
  • args: An ActionArgs instance, defining the options that the marketer can fill out on the dashboard. For example, Title, Accept action, or Color.
  • responder: A callback that accepts an ActionContext and returns a boolean whether the action was handled or not. You may decide not to handle the action based on some additional logic defined in the responder. From the context, you can access the values for any argument you defined in the template, as well as some other special methods:
    • ActionContext.runActionNamed(): Runs another action when this action is done. The action name should correspond to a named action argument defined within ActionArgs.
    • ActionContext runTrackedActionNamed(): Runs another action and tracks an event that the action occurred.
    • ActionContext.track(): Tracks an event associated with the current action.
    • ActionContext.muteFutureMessagesOfSameKind(): Don't show the current message campaign again on this device. For example, if you have a survey popup every 10th session, you may want the ability for the user to decide to remind them later, which simply dismisses the message, or the option to never see this survey again.