Customization

All of Braze’s in-app message types are highly customizable across messages, images, Font Awesome icons, click actions, analytics, editable styling, custom display options, and custom delivery options. Multiple options can be configured on a per in-app message basis from within the dashboard. Braze additionally provides multiple levels of advanced customization to satisfy a variety of use cases and needs.

Key-Value Pair Extras

In-app message objects may carry key-value pairs as extras. They are specified on the dashboard under “Advanced Settings” when creating an in-app message campaign. These can be used to send data down along with an in-app message for further handling by the application.

Call the following when you get an in-app message object to retrieve its extras:

1
Map<String, String> getExtras()
1
extras: Map<String, String>

See the Javadoc for more information.

Custom Styling

Braze UI elements come with a default look and feel that matches the Android standard UI guidelines and provides a seamless experience. You can see these default styles in the Braze SDK’s styles.xml file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  <style name="Appboy"/>
    <!-- In-app Message -->
  <style name="Appboy.InAppMessage">
  </style>
  <style name="Appboy.InAppMessage.Header">
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_width">wrap_content</item>
    <item name="android:padding">0.0dp</item>
    <item name="android:background">@android:color/transparent</item>
    <item name="android:textColor">@color/com_appboy_inappmessage_header_text_light</item>
    <item name="android:textSize">19.0sp</item>
    <item name="android:layout_gravity">center</item>
    <item name="android:singleLine">true</item>
    <item name="android:textStyle">bold</item>
  </style>

If you would prefer, you can override these styles to create a look and feel that better suits your app.

To override a style, copy it in its entirety to the styles.xml file in your own project and make modifications. The whole style must be copied over to your local styles.xml file in order for all attributes to be correctly set. Please note that these custom styles are for changes to individual UI elements, not wholesale changes to layouts. Layout-level changes need to be handled with custom views.

Using Custom Styling to Set a Custom Font

Braze allows for setting a custom font using the font family guide. To use it, override the style for message text, headers, and/or button text and use the fontFamily attribute to instruct Braze to use your custom font family.

For example, to update the font on your in-app message button text, override the Appboy.InAppMessage.Button style and reference your custom font family. The attribute value should point to a font family in your res/font directory.

Here is a truncated example with a custom font family, my_custom_font_family, referenced on the last line:

1
2
3
4
5
6
7
  <style name="Appboy.InAppMessage.Button">
    <item name="android:layout_height">wrap_content</item>
    ...
    <item name="android:paddingBottom">15.0dp</item>
    <item name="android:fontFamily">@font/my_custom_font_family</item>
    <item name="fontFamily">@font/my_custom_font_family</item>
  </style>

Aside from the Appboy.InAppMessage.Button style for button text, the style for message text is Appboy.InAppMessage.Message and the style for message headers is Appboy.InAppMessage.Header. If you want to use your custom font family across all possible in-app message text, you can set your font family on the Appboy.InAppMessage style, which is the parent style for all in-app messages.

Setting Custom Listeners

Before customizing in-app messages with custom listeners, it’s important to understand the AppboyInAppMessageManager, which handles the majority of in-app message handling. As described in Step 1, it must be registered for in-app messages to function appropriately.

AppboyInAppMessageManager manages in-app message display on Android. It contains helper class instances that help it manage the lifecycle and display of in-app messages. All of these classes have standard implementations and defining custom classes is completely optional. However, doing so can add another level of control over the display and behavior of in-app messages. These customizable classes include:

Setting a Custom Manager Listener

The AppboyInAppMessageManager automatically handles the display and lifecycle of in-app messages. If you require more control over the lifecycle of a message, setting a custom manager listener will enable you to receive the in-app message object at various points in the in-app message lifecycle, allowing you to handle its display yourself, perform further processing, react to user behavior, process the object’s Extras, and much more.

Step 1: Implement an In-App Message Manager Listener

Create a class that implements IInAppMessageManagerListener.

The callbacks in your IInAppMessageManagerListener will be called at various points in the in-app message lifecycle.

For example, if you set a custom manager listener, when an in-app message is received from Braze, the beforeInAppMessageDisplayed() method will be called. If your implementation of this method returns InAppMessageOperation.DISCARD, that signals to Braze that the in-app message will be handled by the host app and should not be displayed by Braze. If InAppMessageOperation.DISPLAY_NOW is returned, Braze will attempt to display the in-app message. This method should be used if you choose to display the in-app message in a customized manner.

IInAppMessageManagerListener also includes delegate methods for clicks on the message itself or one of the buttons. A common use case would be intercepting a message when a button or message is clicked for further processing.

Step 2: Hook into In-App Message View Lifecycle Methods (Optional)

The IInAppMessageManagerListener interface has in-app message view methods that are called at distinct points in the in-app message view lifecycle. These methods are called in the following order:

  • beforeInAppMessageViewOpened - Called just before the in-app message is added to the Activity’s view. The in-app message is not yet visible to the user at this time.
  • afterInAppMessageViewOpened - Called just after the in-app message is added to the Activity’s view. The in-app message is now visible to the user at this time.
  • beforeInAppMessageViewClosed - Called just before the in-app message is removed from the Activity’s view. The in-app message is still visible to the user at this time.
  • afterInAppMessageViewClosed - Called just after the in-app message is removed from the Activity’s view. The in-app message is no longer visible to the user at this time.

For further context, the time between afterInAppMessageViewOpened and beforeInAppMessageViewClosed is when the in-app message view is on screen, visible to the user.

Step 3: Instruct Braze to use your In-App Message Manager Listener

Once your IInAppMessageManagerListener is created, call AppboyInAppMessageManager.getInstance().setCustomInAppMessageManagerListener() to instruct AppboyInAppMessageManager to use your custom IInAppMessageManagerListener instead of the default listener.

We recommend setting your IInAppMessageManagerListener in your Application.onCreate() before any other calls to Braze. This will ensure that the custom listener is set before any in-app message is displayed.

See InAppMessageTesterFragment.java in the DroidBoy sample app for an example implementation.

In-Depth: Altering In-App Messages Before Display

When a new in-app message is received, and there is already an in-app message being displayed, the new message will be put onto the top of the stack and can be displayed at a later time.

However, if there is no in-app message being displayed, the following delegate method in IInAppMessageManagerListener will be called:

1
2
3
4
@Override
public InAppMessageOperation beforeInAppMessageDisplayed(IInAppMessage inAppMessageBase) {
  return InAppMessageOperation.DISPLAY_NOW;
}
1
2
3
override fun beforeInAppMessageDisplayed(inAppMessageBase: IInAppMessage): InAppMessageOperation {
  return InAppMessageOperation.DISPLAY_NOW
}

The InAppMessageOperation() return value can be used to control when the message should be displayed. A suggested usage of this method would be to delay messages in certain parts of the app by returning DISPLAY_LATER when in-app messages would be distracting to the user’s app experience.

InAppMessageOperation return value Behavior
DISPLAY_NOW The message will be displayed
DISPLAY_LATER The message will be returned to the stack and displayed at the next available opportunity
DISCARD The message will be discarded
null The message will be ignored. This method should NOT return null

See InAppMessageOperation.java for more details.

On Android, this is done by calling logClick and logImpression on in-app messages, and logButtonClick on immersive in-app messages.

Setting a Custom View Factory

Braze’s suite of in-app messages types are versatile enough to cover the vast majority of custom use cases. However, if you would like to fully define the visual appearance of your in-app messages instead of using a default type, Braze makes this possible via setting a custom view factory.

Step 1: Implement an In-App Message View Factory

Create a class that implements IInAppMessageViewFactory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class CustomInAppMessageViewFactory implements IInAppMessageViewFactory {
  @Override
  public View createInAppMessageView(Activity activity, IInAppMessage inAppMessage) {
    // Uses a custom view for slideups, modals, and full in-app messages.
    // HTML in-app messages and any other types will use the Braze default in-app message view factories
    switch (inAppMessage.getMessageType()) {
      case SLIDEUP:
      case MODAL:
      case FULL:
        // Use a custom view of your choosing
        return createMyCustomInAppMessageView();
      default:
        // Use the default in-app message factories
        final IInAppMessageViewFactory defaultInAppMessageViewFactory = AppboyInAppMessageManager.getInstance().getDefaultInAppMessageViewFactory(inAppMessage);
        return defaultInAppMessageViewFactory.createInAppMessageView(activity, inAppMessage);
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class CustomInAppMessageViewFactory : IInAppMessageViewFactory {
  override fun createInAppMessageView(activity: Activity, inAppMessage: IInAppMessage): View {
    // Uses a custom view for slideups, modals, and full in-app messages.
    // HTML in-app messages and any other types will use the Braze default in-app message view factories
    when (inAppMessage.messageType) {
      MessageType.SLIDEUP, MessageType.MODAL, MessageType.FULL ->
        // Use a custom view of your choosing
        return createMyCustomInAppMessageView()
      else -> {
        // Use the default in-app message factories
        val defaultInAppMessageViewFactory = AppboyInAppMessageManager.getInstance().getDefaultInAppMessageViewFactory(inAppMessage)
        return defaultInAppMessageViewFactory!!.createInAppMessageView(activity, inAppMessage)
      }
    }
  }
}

Step 2: Instruct Braze to use your In-App Message View Factory

Once your IInAppMessageViewFactory is created, call AppboyInAppMessageManager.getInstance().setCustomInAppMessageViewFactory() to instruct AppboyInAppMessageManager to use your custom IInAppMessageViewFactory instead of the default view factory.

In-Depth: Implementing a Braze View Interface

Braze’s slideup in-app message view implements IInAppMessageView. Braze’s full and modal type message views implement IInAppMessageImmersiveView. Implementing one of these classes will allow Braze to add click listeners to your custom view where appropriate. All Braze view classes extend Android’s View class.

Implementing IInAppMessageView allows you to define a certain portion of your custom view as clickable. Implementing IInAppMessageImmersiveView allows you to define message button views and a close button view.

Setting a Custom Animation Factory

In-app messages have preset animation behavior. Slideup type messages slide into the screen; full and modal messages fade in and out. If you would like to define custom animation behaviors for your in-app messages, Braze makes this possible via setting a custom animation factory.

Step 1: Implement an In-App Message Animation Factory

Create a class that implements IInAppMessageAnimationFactory

Step 2: Instruct Braze to use your In-App Message View Factory

Once your IInAppMessageAnimationFactory is created, call AppboyInAppMessageManager.getInstance().setCustomInAppMessageAnimationFactory() to instruct AppboyInAppMessageManager to use your custom IInAppMessageAnimationFactory instead of the default animation factory.

We recommend setting your IInAppMessageAnimationFactory in your Application.onCreate() before any other calls to Braze. This will ensure that the custom animation factory is set before any in-app message is displayed.

See InAppMessageTesterFragment.java in the DroidBoy sample app for an example implementation.

Setting a Custom HTML In-App Message Action Listener

The Braze SDK has a default AppboyDefaultHtmlInAppMessageActionListener class that is used if no custom listener is defined and takes appropriate action automatically. If you require more control over how a user interacts with different buttons inside a custom HTML in-app message, implement a custom IHtmlInAppMessageActionListener class.

Step 1: Implement a Custom HTML In-App Message Action Listener

Create a class that implements IHtmlInAppMessageActionListener.

The callbacks in your IHtmlInAppMessageActionListener will be called whenever user initiates any of the following actions inside HTML in-app message:

  • Clicks on close button.
  • Clicks on news feed button.
  • Fires a custom event.
  • Clicks on a URL inside HTML in-app message.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class CustomHtmlInAppMessageActionListener implements IHtmlInAppMessageActionListener {
  private final Context mContext;

  public CustomHtmlInAppMessageActionListener(Context context) {
    mContext = context;
  }

  @Override
  public void onCloseClicked(IInAppMessage inAppMessage, String url, Bundle queryBundle) {
    Toast.makeText(mContext, "HTML In App Message closed", Toast.LENGTH_LONG).show();
    AppboyInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false);
  }

  @Override
  public boolean onCustomEventFired(IInAppMessage inAppMessage, String url, Bundle queryBundle) {
    Toast.makeText(mContext, "Custom event fired. Ignoring.", Toast.LENGTH_LONG).show();
    return true;
  }

  @Override
  public boolean onNewsfeedClicked(IInAppMessage inAppMessage, String url, Bundle queryBundle) {
    Toast.makeText(mContext, "Newsfeed button pressed. Ignoring.", Toast.LENGTH_LONG).show();
    AppboyInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false);
    return true;
  }

  @Override
  public boolean onOtherUrlAction(IInAppMessage inAppMessage, String url, Bundle queryBundle) {
    Toast.makeText(mContext, "Custom url pressed: " + url + " . Ignoring", Toast.LENGTH_LONG).show();
    AppboyInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false);
    return true;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class CustomHtmlInAppMessageActionListener(private val mContext: Context) : IHtmlInAppMessageActionListener {

    override fun onCloseClicked(inAppMessage: IInAppMessage, url: String, queryBundle: Bundle) {
        Toast.makeText(mContext, "HTML In App Message closed", Toast.LENGTH_LONG).show()
        AppboyInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false)
    }

    override fun onCustomEventFired(inAppMessage: IInAppMessage, url: String, queryBundle: Bundle): Boolean {
        Toast.makeText(mContext, "Custom event fired. Ignoring.", Toast.LENGTH_LONG).show()
        return true
    }

    override fun onNewsfeedClicked(inAppMessage: IInAppMessage, url: String, queryBundle: Bundle): Boolean {
        Toast.makeText(mContext, "Newsfeed button pressed. Ignoring.", Toast.LENGTH_LONG).show()
        AppboyInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false)
        return true
    }

    override fun onOtherUrlAction(inAppMessage: IInAppMessage, url: String, queryBundle: Bundle): Boolean {
        Toast.makeText(mContext, "Custom url pressed: $url . Ignoring", Toast.LENGTH_LONG).show()
        AppboyInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false)
        return true
    }
}

Step 2: Instruct Braze to use your HTML In-App Message Action Listener

Once your IHtmlInAppMessageActionListener is created, call AppboyInAppMessageManager.getInstance().setCustomHtmlInAppMessageActionListener() to instruct AppboyInAppMessageManager to use your custom IHtmlInAppMessageActionListener instead of the default action listener.

We recommend setting your IHtmlInAppMessageActionListener in your Application.onCreate() before any other calls to Braze. This will ensure that the custom action listener is set before any in-app message is displayed.

1
AppboyInAppMessageManager.getInstance().setCustomHtmlInAppMessageActionListener(new CustomHtmlInAppMessageActionListener(context));
1
AppboyInAppMessageManager.getInstance().setCustomHtmlInAppMessageActionListener(CustomHtmlInAppMessageActionListener(context))

Setting a Custom View Wrapper Factory

The AppboyInAppMessageManager automatically handles placing the in-app message model into the existing Activity view hierarchy by default using DefaultInAppMessageViewWrapper. If you need to customize how in-app messages are placed into the view hierarchy, you should use a custom IInAppMessageViewWrapperFactory.

Step 1: Implement an In-App Message View Wrapper Factory

Create a class that implements IInAppMessageViewWrapperFactory and returns an IInAppMessageViewWrapper.

This factory is called immediately after the in-app message view is created. The easiest way to implement a custom IInAppMessageViewWrapper is just to extend the default DefaultInAppMessageViewWrapper.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class CustomInAppMessageViewWrapper extends DefaultInAppMessageViewWrapper {
  public CustomInAppMessageViewWrapper(View inAppMessageView,
                                       IInAppMessage inAppMessage,
                                       IInAppMessageViewLifecycleListener inAppMessageViewLifecycleListener,
                                       AppboyConfigurationProvider appboyConfigurationProvider,
                                       Animation openingAnimation,
                                       Animation closingAnimation, View clickableInAppMessageView) {
    super(inAppMessageView,
        inAppMessage,
        inAppMessageViewLifecycleListener,
        appboyConfigurationProvider,
        openingAnimation,
        closingAnimation,
        clickableInAppMessageView);
  }

  @Override
  public void open(@NonNull Activity activity) {
    super.open(activity);
    Toast.makeText(activity.getApplicationContext(), "Opened in-app message", Toast.LENGTH_SHORT).show();
  }

  @Override
  public void close() {
    super.close();
    Toast.makeText(mInAppMessageView.getContext().getApplicationContext(), "Closed in-app message", Toast.LENGTH_SHORT).show();
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class CustomInAppMessageViewWrapper(inAppMessageView: View,
                                    inAppMessage: IInAppMessage,
                                    inAppMessageViewLifecycleListener: IInAppMessageViewLifecycleListener,
                                    appboyConfigurationProvider: AppboyConfigurationProvider,
                                    openingAnimation: Animation,
                                    closingAnimation: Animation, clickableInAppMessageView: View) : 
    DefaultInAppMessageViewWrapper(inAppMessageView, 
        inAppMessage, 
        inAppMessageViewLifecycleListener, 
        appboyConfigurationProvider, 
        openingAnimation, 
        closingAnimation, 
        clickableInAppMessageView) {

  override fun open(activity: Activity) {
    super.open(activity)
    Toast.makeText(activity.applicationContext, "Opened in-app message", Toast.LENGTH_SHORT).show()
  }

  override fun close() {
    super.close()
    Toast.makeText(mInAppMessageView.context.applicationContext, "Closed in-app message", Toast.LENGTH_SHORT).show()
  }
}

Step 2: Instruct Braze to use your Custom View Wrapper Factory

Once your IInAppMessageViewWrapper is created, call AppboyInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory() to instruct AppboyInAppMessageManager to use your custom IInAppMessageViewWrapperFactory instead of the default view wrapper factory.

We recommend setting your IInAppMessageViewWrapperFactory in your Application.onCreate() before any other calls to Braze. This will ensure that the custom view wrapper factory is set before any in-app message is displayed.

1
AppboyInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory(new CustomInAppMessageViewWrapper());
1
AppboyInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory(CustomInAppMessageViewWrapper())

Setting Fixed Orientation

To set a fixed orientation for an in-app message, first set a custom in-app message manager listener. Then, call setOrientation() on the IInAppMessage object in the beforeInAppMessageDisplayed() delegate method.

1
2
3
4
5
public InAppMessageOperation beforeInAppMessageDisplayed(IInAppMessage inAppMessage) {
  // Set the orientation to portrait
  inAppMessage.setOrientation(Orientation.PORTRAIT);
  return InAppMessageOperation.DISPLAY_NOW;
}
1
2
3
4
5
override fun beforeInAppMessageDisplayed(inAppMessage: IInAppMessage): InAppMessageOperation {
  // Set the orientation to portrait
  inAppMessage.orientation = Orientation.PORTRAIT
  return InAppMessageOperation.DISPLAY_NOW
}

For tablet devices, in-app messages will appear in the style of the user’s preferred orientation regardless of actual screen orientation.

GIFs

Braze requires an external image library to display animated GIFs with in-app messages.

Custom Image Library Integration

Braze offers the ability to use a custom image library to display animated GIFs with in-app messages.

Note: Although the example below uses Glide, any image library that supports GIFs is compatible.

Step 1: Creating the Image Loader Delegate

The Image Loader delegate must implement the following methods:

The integration example below is taken from the Glide Integration Sample App included with the Braze Android SDK.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class GlideAppboyImageLoader implements IAppboyImageLoader {
  private static final String TAG = GlideAppboyImageLoader.class.getName();

  private RequestOptions mRequestOptions = new RequestOptions();

  @Override
  public void renderUrlIntoCardView(Context context, Card card, String imageUrl, ImageView imageView, AppboyViewBounds viewBounds) {
    renderUrlIntoView(context, imageUrl, imageView, viewBounds);
  }

  @Override
  public void renderUrlIntoInAppMessageView(Context context, IInAppMessage inAppMessage, String imageUrl, ImageView imageView, AppboyViewBounds viewBounds) {
    renderUrlIntoView(context, imageUrl, imageView, viewBounds);
  }

  @Override
  public Bitmap getPushBitmapFromUrl(Context context, Bundle extras, String imageUrl, AppboyViewBounds viewBounds) {
    return getBitmapFromUrl(context, imageUrl, viewBounds);
  }

  @Override
  public Bitmap getInAppMessageBitmapFromUrl(Context context, IInAppMessage inAppMessage, String imageUrl, AppboyViewBounds viewBounds) {
    return getBitmapFromUrl(context, imageUrl, viewBounds);
  }

  private void renderUrlIntoView(Context context, String imageUrl, ImageView imageView, AppboyViewBounds viewBounds) {
    Glide.with(context)
        .load(imageUrl)
        .apply(mRequestOptions)
        .into(imageView);
  }

  private Bitmap getBitmapFromUrl(Context context, String imageUrl, AppboyViewBounds viewBounds) {
    try {
      return Glide.with(context)
          .asBitmap()
          .apply(mRequestOptions)
          .load(imageUrl).submit().get();
    } catch (Exception e) {
      Log.e(TAG, "Failed to retrieve bitmap at url: " + imageUrl, e);
    }
    return null;
  }

  @Override
  public void setOffline(boolean isOffline) {
    // If the loader is offline, then we should only be retrieving from the cache
    mRequestOptions = mRequestOptions.onlyRetrieveFromCache(isOffline);
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class GlideAppboyImageLoader : IAppboyImageLoader {
  companion object {
    private val TAG = GlideAppboyImageLoader::class.qualifiedName
  }

  private var mRequestOptions = RequestOptions()

  override fun renderUrlIntoCardView(context: Context, card: Card, imageUrl: String, imageView: ImageView, viewBounds: AppboyViewBounds) {
    renderUrlIntoView(context, imageUrl, imageView, viewBounds)
  }

  override fun renderUrlIntoInAppMessageView(context: Context, inAppMessage: IInAppMessage, imageUrl: String, imageView: ImageView, viewBounds: AppboyViewBounds) {
    renderUrlIntoView(context, imageUrl, imageView, viewBounds)
  }

  override fun getPushBitmapFromUrl(context: Context, extras: Bundle, imageUrl: String, viewBounds: AppboyViewBounds): Bitmap? {
    return getBitmapFromUrl(context, imageUrl, viewBounds)
  }

  override fun getInAppMessageBitmapFromUrl(context: Context, inAppMessage: IInAppMessage, imageUrl: String, viewBounds: AppboyViewBounds): Bitmap? {
    return getBitmapFromUrl(context, imageUrl, viewBounds)
  }

  private fun renderUrlIntoView(context: Context, imageUrl: String, imageView: ImageView, viewBounds: AppboyViewBounds) {
    Glide.with(context)
        .load(imageUrl)
        .apply(mRequestOptions)
        .into(imageView)
  }

  private fun getBitmapFromUrl(context: Context, imageUrl: String, viewBounds: AppboyViewBounds): Bitmap? {
    try {
      return Glide.with(context)
          .asBitmap()
          .apply(mRequestOptions)
          .load(imageUrl).submit().get()
    } catch (e: Exception) {
      Log.e(TAG, "Failed to retrieve bitmap at url: $imageUrl", e)
    }

    return null
  }

  override fun setOffline(isOffline: Boolean) {
    // If the loader is offline, then we should only be retrieving from the cache
    mRequestOptions = mRequestOptions.onlyRetrieveFromCache(isOffline)
  }
}

Step 2: Setting the Image Loader Delegate

The Braze SDK will use any custom image loader set with setAppboyImageLoader. Note that we recommend setting the custom image loader in a custom application subclass.

1
2
3
4
5
6
7
public class GlideIntegrationApplication extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    Appboy.getInstance(context).setAppboyImageLoader(new GlideAppboyImageLoader());
  }
}
1
2
3
4
5
6
class GlideIntegrationApplication : Application() {
  override fun onCreate() {
    super.onCreate()
    Appboy.getInstance(context).appboyImageLoader = GlideAppboyImageLoader()
  }
}

Fresco Migration

Fresco is no longer supported as a GIF loading library in version 3.0.0 of the Braze Android SDK. A custom image loader, such as Glide, must be used in order to display GIFs.

The usage of Fresco with IAppboyImageLoader is not supported since Fresco requires Drawee views to work.

Android Dialogs

Braze doesn’t support displaying in-app messages in Android Dialogs at this time.

Youtube in HTML in-app messages

Starting in Braze Android SDK version 2.0.1, Youtube and other HTML5 content can play in HTML in-app messages. This requires hardware acceleration to be enabled in the Activity where the in-app message is being displayed, please see the Android developer guide for more details. Also that hardware acceleration is only available on API versions 11 and above.

WAS THIS PAGE HELPFUL?
New Stuff!