Mobile landings

Mobile Landings allow you to easily introduce continuity between your app, and your pushes: A user opening a push will be greeted by a rich message related to what they opened, rather than just ending up on your app's main menu.

They're included in the Startup,Business and Enterprise plans.

Mobile landings visual example

Displaying the message

Fully automatic mode

There's no code required to make mobile landings work in automatic mode once you satisfy the requirements: Just attach a landing to your push campaign, and Batch will display it.

You might want to go further into this documentation, setup your analytics listener or add some Custom Actions.

The automatic mode is only guaranteed to work properly if Batch is well integrated into ALL of your activities. Activities with special launchModes (such as singleTask, ...) might require a more manual integration due to platform limitations.

Automatic mode, with a custom receiver

If you're using a custom push receiver, Batch will automatically display landings when a notification is opened. However, landings will not appear when the app is in the foreground as opposed to the fully automatic mode.

For that, you'll need to implement foreground push yourself. Here's how Batch does it, which will probably work for you:

  • Track if your app is in the foreground or background. That's done by counting onPause and onResume events, using a ActivityLifecycleCallbacks implementation
  • In the push service, check this value. If the app is in the foreground and the push contains a landing, start an activity that will display the message. You can also use a LocalBroadcastManager to communicate with your foreground app.

The SDK comes with com.batch.android.MessagingActivity, which is a public api: feel free to use it. MessagingActivity.startActivityForMessage() is the static method used to correctly configure this activity and show it for a given landing message.

We'll soon provide sample code to do so, feel free to contact our support in the meantime!

Once that's handled, simply make sure you call Batch.Push.displayNotification() or Batch.Push.appendBatchData() depending on how custom your receiver is, and that Batch is started in the activity opened by the notification.

Manual mode

You may want to be in control of if, when and how the landings will be loaded and displayed. Batch allows you to disable automatic displaying, and handle loading and displaying of the fragment itself.

Most integrations do not need to use this mode unless the app you're integrating into has some specificities, such as: games, non native-frameworks, activities with special launchMode, etc. The Automatic mode, with a custom receiver section might be what you're looking for, rather than doing a fully manual integration.

First, you'll need to disable the automatic mode, in your Application class:

public class SampleApplication extends Application implements Messaging.LifecycleListener
{

	@Override
	public void onCreate()
	{
		super.onCreate();
		[...]
		Batch.Messaging.setAutomaticMode(false);
	}
}

Then, you need to ask Batch to load the right fragment or banner for the push payload (if applicable), and display it:

public class MainActivity extends FragmentActivity
{

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		[...]
		
		final Bundle extras = getIntent().getExtras();
		if (extras != null)
		{
			try
            {
                BatchPushPayload pushPayload = BatchPushPayload.payloadFromBundle(extras);
                if (pushPayload.hasLandingMessage())
                {
                    try
                    {
                        BatchMessage message = pushPayload.getLandingMessage();
                        Batch.Messaging.show(context, msg);
                        
                        // Alternatively, you can load and show the message yourself
                        
                        switch (message.getFormat()) {
                            case FULLSCREEN:
                                Batch.Messaging.loadFragment(this, message)
                                        .show(getSupportFragmentManager(), "batch-landing");
                                break;
                            case BANNER:
                                Batch.Messaging.loadBanner(this, message)
                                        .show(this);
                                break;
                        }

                    }
                    catch (BatchMessagingException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
            catch (BatchPushPayload.ParsingException e)
            {
                e.printStackTrace();
            }
		}
	}
	
}

Note: You'll need to use the Support Fragment Manager to display the message fragment, rather than the standard one.

Controlling the display using "Do Not Disturb mode"

Batch 1.10 adds a "Do Not Disturb" (DnD) feature: It allows you to tell Batch to hold on a mobile landing for you, rather than display it without using the fully manual mode.
For example, if launching your app results in a splash screen or a fullscreen ad, you might find it undesirable to have Batch display something on top of it.

Turning on "Do Not Disturb" mode will make Batch enqueue the latest mobile landing, rather than display it.

Toggling DnD

Now, when you don't want Batch to automatically display, turn on Do Not Disturb:

Batch.Messaging.setDoNotDisturbEnabled(true)

Once you want to start showing landings automatically, call the method with false to turn it off.

Note: Disabling Do Not Disturb mode does NOT make Batch show the enqueued message

Displaying pending mobile landings

After coming back from DnD mode, you might want to show the enqueued message, as Batch will not do that automatically. Batch exposes two methods for managing the queue:

  • Batch.Messaging.hasPendingMessage() , allowing you to peek into the queue.
  • Batch.Messaging.popPendingMessage() , allowing you to fetch the pending message (if any). Since calling this makes Batch delete its reference to it to save memory, further calls might return null.

Here is a quick example of how they can be used:

public void splashScreenDismissed(Context context) {
	Batch.Messaging.setDoNotDisturbEnabled(false);
	BatchMessage msg = Batch.Messaging.popPendingMessage();
	if (msg != null) {
		Batch.Messaging.show(context, msg);
	}
}

Note: Only the latest message is queued: if a mobile landing arrives while one is still pending, it will overwrite the previous one.

Excluding activities

1.18.0 It is possible to mark activites as excluded from Batch's lifecycle handling to prevent them from displaying mobile landings temporarily: the landing will then be enqueued and displayed over the next activity.
For example, if launching your app results in a splash screen or a fullscreen ad, you might find it undesirable to have Batch display something on top of it.

To do so, add the following meta-data your AndroidManifest.xml :

<activity android:name=".MyActivity">
     ...
    <meta-data 
      android:name="com.batch.android.EXCLUDE_FROM_LIFECYCLE" 
      android:value="true" />
</activity>

Listening to lifecycle events and button callbacks

Setting up a listener

Batch's messaging module supports setting up a listener, which can be used for analytics purposes.

It can be any object that implements the Batch.Messaging.LifecycleListener interface, such as your application instance.

public class SampleApplication extends Application implements Batch.Messaging.LifecycleListener
{

	@Override
	public void onCreate()
	{
		super.onCreate();
		[...]
		Batch.Messaging.setLifecycleListener(this);
	}
	
}

Analytics listener

Batch can notify your listener of lifecycle events of the in-app messages:

public class SampleApplication extends Application implements Batch.Messaging.LifecycleListener
{

	@Override
	public void onBatchMessageShown(@Nullable String messageIdentifier)
	{
		Log.i("App", "onBatchMessageShown " + messageIdentifier);
	}

	@Override
	public void onBatchMessageClosed(@Nullable String messageIdentifier)
	{
		Log.i("App", "onBatchMessageClosed " + messageIdentifier);
	}
	
}

Since Batch 1.14, additional callbacks have been added to:

  • Track when a button has been pressed, along with the action that goes with it
  • Track when a message has been cancelled (close button/back button/swipe to dismiss)
  • Track when a message has been automatically closed due to the timer running out

To use them, simply implement the methods you need:

public class SampleApplication extends Application implements Batch.Messaging.LifecycleListener
{
	// [...]

	@Override
	public void onBatchMessageActionTriggered(@Nullable String messageIdentifier,
												int index,
												@NonNull BatchMessageAction action)
	{
		// A button or global tap action has been triggered
		
		// On templates that support a global tap action (like Image), the index will be a special value
		if (index == Batch.Messaging.GLOBAL_TAP_ACTION_INDEX) {
			// It was the global tap action
		} else {
			// If the action is a CTA (button), you can fetch the label
			if (action instanceof BatchMessageCTA) {
				String label = ( (BatchMessageCTA) action ).getLabel();
			}
		}
		
		// CTAs are allowed to simply be a "dismiss" action, in which case they
		// will not have any associated action name and arguments
		boolean isDismissAction = action.isDismissAction();
		if (!isDismissAction) {
			String actionName = action.getAction(); // not null
		}
	}

	@Override
	public void onBatchMessageCancelledByAutoclose(@Nullable String messageIdentifier)
	{
		// Message has been automatically closed after a delay
	}

	@Override
	public void onBatchMessageCancelledByUser(@Nullable String messageIdentifier)
	{
		// Message has been cancelled by either
		//  - Tapping the close button
		//  - A swipe to dismiss
		//  - Pressing the system's close button
	}
}

Customizing the landing

Setting a custom typeface

If you'd like to use a custom typeface (aka font) instead of the system's, Batch allows you to override the fonts it will use:


// Set a custom typeface

Typeface normalTypeface = Typeface.createFromAsset(getAssets(), "MyFont.ttf");
Typeface boldTypeface = Typeface.createFromAsset(getAssets(), "MyFont-Bold.ttf");
Batch.Messaging.setTypefaceOverride(normalTypeface, boldTypeface);

// Clear the custom typeface, and use the system one
Batch.Messaging.setTypefaceOverride(null, null);

Make sure you provide both a normal and a bold font, even if they are the same.

This assumes you've already know how to make custom Typefaces. It usually simply involves putting fonts in your assets folder.

Troubleshooting

Landings are not displayed, even after opening the notification

First, check your logcat to see if Batch is saying anything. Then, if you're using a custom receiver, you might want to double check that you're calling required Batch methods. Activities with custom launchModes can also interfere: make sure onNewIntent is implemented correctly if you're using a special launchMode.

If you still don't get landings, don't hesitate to hit us up at support@batch.com, or by using the support button on the lower right corner of this page.

Nothing happens when I press an actionable button

Take a look at your application logs in logcat (either in your Android Studio tab, or by running "adb logcat" in a terminal): the SDK might try to warn you about an issue.

If your action isn't a deeplink but a custom action, please continue to the Custom Actions documentation.