Initial SDK Setup

Installing the Appboy SDK will provide you with basic analytics functionality as well as a working in-app slideup message with which you can engage your users.

Time Estimate: 10-15 Minutes

Android SDK Integration

Note: Appboy is in the process of sunsetting formal support for the Eclipse IDE as Google is sunsetting support for the Eclipse Android Developer Tools Plugin. If you need assistance with your Eclipse integration prior to migration please contact your Customer Success Manager or email support@appboy.com for assistance.

Step 1: Integrate the Appboy Library

The Appboy Android SDK can optionally be integrated without UI components. However, In-App Messaging, the News Feed, and Feedback will be rendered inoperable unless you pass the custom data to a UI solely of your design. Additionally, push notifications will not work because our BroadcastReceiver that handles push is in the UI library. Please note that these UI elements are open source and fully customizable. We strongly recommend integration of these features. Please refer to the Appboy Academy for the benefits of using the Appboy News Feed, In-App Message, and Feedback UI.

Basic Integration

In order to access Appboy’s messaging features, you must integrate the UI library. Please see the following directions to integrate the UI library depending on your IDE:

Using Android Studio

Step 1: Add our repository

In your top-level project build.gradle, add:

maven { url "http://appboy.github.io/appboy-android-sdk/sdk" }

as a repository under allprojects -> repositories. MavenScreen1

Note: Alternatively, you may install the android-sdk-ui as an AAR file to your local maven repository. See the SDK Readme for details.

Step 2: Add Appboy dependency

See the following example in our Hello Appboy example project:

The below example shows where to place the dependency line in your build.gradle. Note that the version used in the example below uses an old version. Please visit Appboy Android SDK Releases for the most up to date version of the Appboy Android SDK.

MavenScreen2

Step 3: Perform Gradle Sync

Be sure to perform a Gradle Sync to build your project and incorporate the dependency additions noted above.

GradleSync

Step 2: Configure the Appboy SDK in appboy.xml

Now that the libraries have been integrated, you have to create an appboy.xml file in your project’s res/values folder. The contents of that file should resemble the following code snippet:

Note: Be sure to substitute the API key found within the App Settings page of the Appboy dashboard for REPLACE_WITH_YOUR_API_KEY.

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="com_appboy_api_key">REPLACE_WITH_YOUR_API_KEY</string>
</resources>

Step 3: Add Required Permissions to Android Manifest

Now that you’ve added your API key, you need to add the following permissions to your AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Note: With the release of Android M, Android switched from an install-time to a runtime permissions model. However, both of these permissions are normal permissions and are granted automatically if listed in the app manifest. For more information, visit Android’s permission documentation.

Implementation Example

See the appboy.xml in the Droidboy sample app for an implementation example.

Step 4: Tracking User Sessions in Android

Activity Lifecycle Callback Integration (API 14+)

This feature is supported on API 14 and above. Calls to openSession(), closeSession(),ensureSubscribedToInAppMessageEvents(), and InAppMessageManager registration are optionally handled automatically. See the HelloAppboy sample application for a full example.

Instructions

Add the following code to the onCreate() method of your Application class:

registerActivityLifecycleCallbacks(new AppboyLifecycleCallbackListener());

You may refer to the following example inside Hello Appboy:

ActivityLifecycleCallbackIntegration

The first argument instructs the listener to handle openSession() and closeSession() calls. The second argument instructs the listener to handle registerInAppMessageManager() and unregisterInAppMessageManager() calls.

See the javadoc for more information.

API 13 and Lower

If your application supports devices running API 13 or lower, you’ll need to add the following calls to the onStart() and onStop() lifecycle methods of every Activity class in your app to enable tracking of user sessions and the gathering of basic user data.

See the Manual Session Integration sample for a complete code sample.

public void onStart() {
    super.onStart();
    Appboy.getInstance(YOUR_ACTIVITY.this).openSession(YOUR_ACTIVITY.this);
}
public void onStop() {
    super.onStop();
    Appboy.getInstance(YOUR_ACTIVITY.this).closeSession(YOUR_ACTIVITY.this);
}
Notes:
  1. Please see the section on the Activity Lifecycle Callback Integration for an automatic integration instead of this step.
  2. You must put these method calls in every Activity in your app. You can choose to add these method calls to a base Activity class from which all your other Activity classes inherit (if applicable). Failure to call these methods will cause inaccurate session data.
  3. Ensure that these methods are not called anywhere except the onStart() and onStop() lifecycle methods of an activity. Calling these methods within fragments, or UI elements will cause inaccurate session data.

SDK Integration Complete

Appboy should now be collecting data from your application and your basic integration should be complete. Please see the following sections in order to enable custom event tracking, push messaging, the news-feed and the complete suite of Appboy features.

Test your Basic Integration

Confirm Session Tracking is Working

At this point you shoud have session tracking working in your Appboy integration. To test this, go to the App Usage section of your dashboard, select your application from the select box (defaulted to All Apps), and set Display Data For to be Today. Then open your app and refresh the page - your main metrics should all have increased by 1.

Sessions working

You should continue to test your integration by navigating through your application and ensuring that only one session has been logged. Then, background the app for at least 10 seconds and bring it to the foreground again - by default a new session is created if the app is foregrounded after more than 10 seconds not in the foreground (backgrounded or closed). Once you’ve done this, confirm that another session was logged.

Debugging Session Tracking

If session tracking is behaving unexpectedly, turn on Verbose Logging and observe your app while you reproduce session triggering steps. Observe Appboy statements in the logcat to detect where you may have missed logging openSession and closeSession calls in your activities.

Confirm Device Data is Collected

At this point you should also have default device data collection working in your app. To observe this working correctly navigate to the Devices & Carriers section of your dashboard, select your application from the select box (defaulted to All Apps), and set Display Data For to be Today.

Android Device Data

Additional Customization and Configuration

Using Proguard with Appboy

Proguard configuration is automatically included with your Appboy integration.

Note: Appboy Android SDK v.1.14.0 removes keep rules from consumerProguardFiles automatic Proguard configuration. Client apps that Proguard Appboy code must store release mapping files for Appboy to interpret stack traces. If you would like to continue to keep all Appboy code, add the following to your Proguard configuration:

-keep class bo.app.** { *; }
-keep class com.appboy.** { *; }

If you are integrating Baidu Cloud Push with Appboy, add:

-dontwarn com.baidu.**
-keep class com.baidu.** { *; }

If using Fresco, add the latest Proguard rules from the Fresco Library Documentation.

Appboy Log Level

The default Log Level for the Appboy Android SDK is INFO. This level includes push payload logs and basic Appboy server communication logs.

To change the Appboy Log Level, call AppboyLogger.setLogLevel() with one of the android.util.Log priority constants or AppboyLogger.SUPPRESS. For example:

// Change log level to VERBOSE
AppboyLogger.setLogLevel(Log.VERBOSE);

// Suppress logs
AppboyLogger.setLogLevel(AppboyLogger.SUPPRESS);

Verbose Logging

When debugging Appboy behavior, set the Log level to Verbose before your first call to Appboy, preferably in your Application.onCreate(). This Log level contains every log made by the Appboy SDK. This is only intended to be used in development environments and should not be set in a released application.

Note: If the Appboy API Key from the “App Settings” page is not present in appboy.xml then an error message is logged to the Android logcat.

Note: If required permissions ACCESS_NETWORK_STATE and INTERNET are not declared in the manifest, an error message is logged to the Android logcat.

Multiple API Keys

The most common usecase for multiple API keys is separating API keys for debug and release build variants.

To easily switch between multiple API keys in your builds, we recommend creating a separate appboy.xml file for each relevant build variant. A build variant is a combination of build type and product flavor. Note that by default, a new Android project is configured with debug and release build types and no product flavors.

For each relevant build variant, create a new appboy.xml for it in src/<build variant name>/res/values/:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="com_appboy_api_key">REPLACE_WITH_YOUR_BUILD_VARIANT_API_KEY</string>
</resources>

When the build variant is compiled, it will use the new API key.

Push Notifications

Overview

A push notification is an out-of-app alert that appears on the user’s screen when an important update occurs. Push notifications are a valuable way to provide your users with time-sensitive and relevant content or to re-engage them with your app.

Sample push notification:

Sample Push

Check out Appboy Academy for additional best practices.

Appboy sends push notifications to Android devices using Google Cloud Messaging (GCM) or Firebase Cloud Messaging (FCM).

Note: Push notifications for Amazon FireOS use the Amazon Device Messaging (ADM) service rather than GCM or FCM. See the FireOS Push Integration instructions for details on enabling push notifications for FireOS apps.

Note: For devices without Google services installed, Appboy offers the option to send push through Baidu Cloud Push. Visit Baidu Cloud Push instructions for more details.

Registering for Push

Time Estimate: 7 Minutes

To register for push you can use either Firebase or GCM. Below are instructions for both methods; ensure you only implement one style of push registration.

Firebase Integration

Appboy recommends the use of the Firebase Cloud Messaging (FCM) for push, as it is more robust than GCM. Apps already using any of the Firebase SDKs must use the Firebase Messaging SDK to receive Appboy pushes. This is because Firebase is not guaranteed to be compatible with GCM in all versions of Google Play Services.

For a full sample of using Firebase with the Appboy Android SDK, see our Firebase Push sample app.

If not using Firebase, please skip ahead to Appboy GCM Integration.

Step 1: Enable Firebase

To use Firebase Messaging, follow the instructions at Add Firebase to Your Android Project.

Next, add the Firebase Messaging dependency to your module’s build.gradle:

compile "com.google.firebase:firebase-messaging:<YOUR_PLAY_SERVICES_VERSION>"

Note: Firebase Messaging is the only Firebase dependency that Appboy requires for push messaging.

Step 2: Configure Token Registration

Use the Appboy.registerAppboyPushMessages() method to pass your user’s Firebase token to Appboy, either manually or using a Firebase Instance Id Service.

Note: Make sure to use your project number, not the project ID. The project number is also known as the Firebase sender ID.

Option 1: Instance Id Service Registration

Firebase tokens can be passed to Appboy using a Firebase Instance Id Service.

To register the service, add the following lines to the application element of your AndroidManifest.xml:

<service
    android:name=".AppboyFirebaseInstanceIdService">
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
    </intent-filter>
</service>

Next, obtain a Firebase token inside your service.

public class AppboyFirebaseInstanceIdService extends FirebaseInstanceIdService {
  @Override
  public void onTokenRefresh() {
    try {
      String token = FirebaseInstanceId.getInstance().getToken("<YOUR_SENDER_ID>", "FCM");
      Appboy.getInstance(getApplicationContext()).registerAppboyPushMessages(token);
    } catch (Exception e) {
      Log.e(TAG, "Exception while automatically registering Firebase token with Appboy.", e);
    }
  }
}
Option 2: Manual Registration

While use of the Firebase Instance Id Service is recommended, your Firebase token can be passed to Appboy anywhere in your code. Appboy push messages won’t work until the Firebase token is sent.

See the snippet below for an example:

try {
  Appboy.getInstance(this).registerAppboyPushMessages(FirebaseInstanceId.getInstance().getToken("<YOUR_SENDER_ID>", "FCM"));
} catch (Exception e) {
  Log.e(TAG, "Exception while automatically registering Firebase token with Appboy.", e);
}

Step 3: Migrate from GCM (Optional)

If migrating from using GCM to using Firebase with Appboy, visit the GCM Migration Guide for instructions on how to properly switch to using Firebase in your app.

Step 4: Set Your Firebase Credentials

You need to input your Firebase Server Key and Sender ID into the Appboy dashboard:

  • On the app settings page (where your API keys are located), select your Android app.
  • Enter your Firebase Server Key in the field labeled “Cloud Messaging API Key” under the Push Notification Settings section.
  • Enter your Firebase Sender ID in the field labeled “Cloud Messaging Sender ID” under the Push Notification Settings section.

GCMKey

If you’re not familiar with the location of your Firebase Server Key and Sender ID, follow these steps:

  1. Login to the Firebase Developers Console

  2. Select your Firebase project

  3. Select Cloud Messaging under Settings and copy the Server Key and Sender ID: FirebaseServerKey

Step 5: Remove Old Permissions

  • Appboy no longer requires the following permissions if using Firebase:

    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <permission android:name="YOUR-APPLICATION-PACKAGE-NAME.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
    <uses-permission android:name="YOUR-APPLICATION-PACKAGE-NAME.permission.C2D_MESSAGE" />
    

Step 6: Turn Off GCM Registration

Firebase Messaging handles registration automatically, so make sure that Appboy’s automatic GCM registration is turned off.

To turn off automatic GCM registration, add the following configuration to your appboy.xml file:

<!-- Whether or not Appboy should handle registering the device to receive push notifications. Default is false. -->
<bool name="com_appboy_push_gcm_messaging_registration_enabled">false</bool>

GCM Integration

Appboy also supports Google Cloud Messaging (GCM) for sending push notifications.

Note: If using Firebase for push notifications, this integration should be skipped.

Step 1: Enable GCM

If you do not already have a Google API project with GCM messaging enabled, follow this wizard to create a Google API project. Please note the following items as you will have to reference them during this integration:

  • Project Number
  • GCM API Key

Note: When generating your GCM API Key ensure that you leave the IP field blank. This will allow any IP to utilize your GCM API Key so Appboy can send push notifications appropriately.

Step 2: Configure your Application

Once you have setup your Google API project, it is time to configure your app.

  • Add the following permissions to your AndroidManifest.xml

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    
  • An additional special permission is required in your AndroidManifest.xml to ensure that push notifications are being sent to your app and that no other app can receive your push notifications.

    <permission android:name="YOUR-APPLICATION-PACKAGE-NAME.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
    <uses-permission android:name="YOUR-APPLICATION-PACKAGE-NAME.permission.C2D_MESSAGE" />
    

Note: With the release of Android M, Android switched from an install-time to a runtime permissions model. To enable push on devices running Ice Cream Sandwich and below, the app must explicitly receive the GET_ACCOUNTS permission from the user (Appboy will not do this). This is because GCM required a Google account on pre-Jelly Bean devices. Note that GET_ACCOUNTS is not required for devices running Jelly Bean and above. All other permissions listed above are normal permissions and are granted automatically if listed in the app manifest. For more information, visit Android’s permission documentation.

Implementation Example

See AndroidManifest.xml in the Droidboy sample app.

Step 3: Enable Automatic Registration

In order for a device to receive push notifications, it must register with the Google GCM server. The Appboy SDK can handle the registration process for you.

  • To tell Appboy to handle GCM registration, add the following configuration to your appboy.xml:

    <!-- Whether or not Appboy should handle registering the device to receive push notifications. Default is false. -->
    <bool name="com_appboy_push_gcm_messaging_registration_enabled">true</bool>
    
  • Add the following configuration element to your appboy.xml and replace YOUR-GOOGLE-API-PROJECT-NUMBER with your Google API project number:

    <!-- Replace with your Google API project number -->
    <string name="com_appboy_push_gcm_sender_id">YOUR-GOOGLE-API-PROJECT-NUMBER</string>
    

    Note: Make sure to use your project number, not the project ID. The project number is also known as the GCM sender ID.

Implementation Example

Step 4: Set Your Google Project API Key

You need to input your Google Project API key into the Appboy dashboard. On the app settings page (where your API keys are located), select your Android app. Enter your Google Project API key in the field labeled GCM (Google Cloud Messaging) API Key under the Push Notifications section.

GCMKey

After completing the Google GCM Getting Started page ensure that you’re using the API key for server applications. If you’re not familiar with the location of that key follow these steps:

  1. Login to the Google Developers Console

  2. Select your GCM project

  3. Select Credentials under APIs & auth:
    • GCMCredentials
  4. Copy your API key for server applications:
    • GCMKeyConsole

Testing Push Registration

Once you’ve registered for push via GCM or FCM integration you should be able to see your user as registered for push notifications in the Appboy dashboard. However, your will still not be able to receive and display push notifications sent by Appboy. To complete your integration, see our section on Displaying Push.

To test push registrations, launch your app with push registration integrated and then find your user in the Appboy dashboard using the User Search feature. Under the Engagement tab on their user profile you should see Push Registered For under the application you are integrating.

Android push registration

For issues related to push registration, see our Troubleshooting Guide.

Manual Push Registration (GCM Only)

Using Appboy’s automatic GCM registration feature is recommended for most GCM integrators. However, if you need to handle GCM registration manually or are using a separate service to register in a side-by-side integration with Appboy, you will need to do the following:

<bool name="com_appboy_push_gcm_messaging_registration_enabled">false</bool>
Appboy.getInstance(this).registerAppboyPushMessages(registrationId);

Note: Manual GCM registration is most commonly required when using a separate push service to register with GCM in a side-by-side integration. Aside from this usecase, we recommend users use Appboy’s automatic GCM registration feature.

Displaying Push (GCM/FCM)

Note that this section applies to both GCM and FCM integrations. After completing this section, you should be able to receive and display push notifications sent by Appboy.

Step 1: Register Appboy GCM Receiver

Appboy includes a GcmReceiver to handle push receipt and open intents. Our GcmReceiver class will need to be registered in your AndroidManifest.xml.

  • Add AppboyGcmReceiver to your AndroidManifest.xml. The category should be set to your application package name:

    <receiver android:name="com.appboy.AppboyGcmReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
     <intent-filter>
       <action android:name="com.google.android.c2dm.intent.RECEIVE" />
       <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
       <category android:name="YOUR-APPLICATION-PACKAGE-NAME" />
     </intent-filter>
    </receiver>
    

Note: Appboy’s notification code also uses the AppboyGCMReceiver.java to handle open and click action tracking. This receiver must be registered in the AndroidManifest.xml in order for that to function correctly. Also, keep in mind that Appboy prefixes notifications from our system with a unique key and ensures that our broadcast receivers only render notifications sent from Appboy’s systems. You may register additional receivers separately in order to render notifications sent from other GCM services.

Note: If you are handling registration manually, the <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> action should be removed from the AppboyGcmReceiver intent filter. However, the top-level AppboyGcmReceiver element should never be entirely removed from the AndroidManifest.xml.

Implementation Example

Step 2: Configure Notification Icons

Specifying Icons in appboy.xml
  • Appboy allows you to configure your notification icons by specifying drawable resources in your appboy.xml:
<drawable name="com_appboy_push_small_notification_icon">REPLACE_WITH_YOUR_ICON</drawable>
<drawable name="com_appboy_push_large_notification_icon">REPLACE_WITH_YOUR_ICON</drawable>

Setting a small notification icon is required. If you do not set one, Appboy will default to using the application icon as the small notification icon which may look suboptimal.

Setting a large notification icon is optional but recommended.

Specifying Icon Background Color
  • The notification icon background color can be overriden in your appboy.xml. If the color is not specified, the default background color is the same gray Lollipop uses for system notifications. Please see the example color override below:
<integer name="com_appboy_default_notification_accent_color">0xFFf33e3e</integer>
Notification Icon Design Guidelines

For general information about Android notification icons, please see the Anatomy of a Notification section from the Android developer documentation.

Android’s Design Guidelines require small notification icons to be all white on a transparent background. If you do not comply, your icons may look suboptimal when displayed by the Android system.

The icons pictured below are examples of properly designed icons:

Android Icon Example

To enable Appboy to automatically open your app and any deep links when a push notification is clicked, set com_appboy_handle_push_deep_links_automatically to true in your appboy.xml:

<bool name="com_appboy_handle_push_deep_links_automatically">true</bool>

Note: If you would like to custom handle deep links, you will need to create a BroadcastReceiver that listens for push received and opened intents from Appboy. See our section on Custom Handling Push Receipts and Opens for more information.

Please follow the instructions found within the Android Developer Documentation on Deep Linking if you have not already added deep links to your app. For information regarding what a deep link is, please see our FAQ Section.

The Appboy dashboard supports setting deep links or web URLs on push notifications that will be opened when the notification is clicked.

Deep_Link_Dash_Example

Step 4: Test Notification Display and Analytics

Testing Display

At this point you should be able to see notifications sent from Appboy. To test this, go to the Campaigns section of your Appboy dashboard and create a Push Notification campaign. Choose Android Push and design your message. Then click the eyeball in the composer to get the test sender. Enter the user id or email address of your current user and click Send Test. You should see the push show up on your device.

Android push test

For issues related to push display, see our Troubleshooting Guide.

Testing Analytics

At this point you should also have analytics logging for push notification opens. To test this, see our Academy Page on creating a push campaign. Clicking on the notification when it arrives should result in the Direct Opens on your campaign results page to increase by 1.

For issues related to push analytics, see our Troubleshooting Guide.

Testing From Command Line

If you’d like to test in-app and push notifications via the command-line, you can send a single notification through the terminal via cURL and the Messaging API. You will need to replace the following fields with the correct values for your test case:

curl -X POST -H "Content-Type: application/json" -d "{\"app_group_id\":\"YOUR_APP_GROUP_ID\",\"external_user_ids\":[\"YOUR_EXTERNAL_USER_ID\"],\"messages\":{\"android_push\":{\"title\":\"Test push title\",\"alert\":\"Test push\",\"extra\":{\"YOUR_KEY1\":\"YOUR_VALUE1\"}}}}" https://api.appboy.com/messages/send

Customizing Your Integration

Custom Displaying Notifications

Step 1: Create your Custom Notification Factory

In some scenarios you may wish to customize push notifications in ways that would be cumbersome or unavailable server side. To give you complete control of notification display, we’ve added the ability to define your own IAppboyNotificationFactory to create notification objects for display by Appboy.

If a custom IAppboyNotificationFactory is set, Appboy will call your factory’s createNotification() method upon push receipt before the notification is displayed to the user. Appboy will pass in a Bundle containing Appboy push data and another Bundle containing custom key/value pairs sent either via the dashboard or the messaging APIs:

// factory method implemented in your custom IAppboyNotificationFactory
createNotification(AppboyConfigurationProvider appConfigurationProvider, Context context, Bundle notificationExtras, Bundle appboyExtras) {
  // example of getting notification title
  String title = notificationExtras.getString(Constants.APPBOY_PUSH_TITLE_KEY);
}

You can return null from your custom createNotification() method to not show the notification at all, use AppboyNotificationFactory.getInstance().createNotification() to obtain Appboy’s default notification object for that data and modify it before display, or generate a completely separate notification object for display.

Note: Appboy push data keys are documented here.

Step 2: Set your Custom Notification Factory

To instruct Appboy to use your custom notification factory, use the method on the Appboy interface to set your IAppboyNotificationFactory:

setCustomAppboyNotificationFactory(IAppboyNotificationFactory appboyNotificationFactory);

The recommended place to set your custom IAppboyNotificationFactory is in the Application.onCreate() application lifecycle method (not activity). This will allow the notification factory to be set correctly whenever your app process is active. See DroidboyApplication.java for an example.

Note: Creating your own notification from scratch is an advanced use case and should be done only with thorough testing and deep understanding of Appboy’s push functionality (you must, for example, ensure your notification logs push opens correctly).

Custom Handling Push Receipts, Opens, and Key-Value Pairs

Appboy broadcasts custom intents when push notification are received or opened. If you have a specific use case for these scenarios (such as the need to listen for custom key-value pairs, proprietary handling of deep links, or uninstall tracking logic), you will need to listen for these intents by creating a custom BroadcastReceiver.

Step 1: Register your BroadcastReceiver

Register your custom BroadcastReceiver to listen for Appboy push opened and received intents in your AndroidManifest.xml.

<receiver android:name="YOUR-BROADCASTRECEIVER-NAME" android:exported="false" >
  <intent-filter>
    <!-- Replace YOUR-APPLICATION-PACKAGE-NAME with the package name of your app -->
    <action android:name="YOUR-APPLICATION-PACKAGE-NAME.intent.APPBOY_PUSH_RECEIVED" />
    <action android:name="YOUR-APPLICATION-PACKAGE-NAME.intent.APPBOY_NOTIFICATION_OPENED" />
  </intent-filter>
</receiver>

Step 2: Create your BroadcastReceiver

Your receiver should handle intents broadcast by Appboy and launch your activity with them:

  • It should subclass BroadcastReceiver and override onReceive().
  • The onReceive() method should listen for intents broadcast by Appboy.
    • An APPBOY_PUSH_RECEIVED intent will be received when a push notification arrives.
    • An APPBOY_NOTIFICATION_OPENED intent will be received when a push notification is clicked by the user.
  • The receiver should perform your custom logic for each of these cases. If your receiver will open deep links, be sure to turn off automatic deep link opening by setting com_appboy_handle_push_deep_links_automatically to false in your appboy.xml.

For a detailed custom receiver example, see AppboyBroadcastReceiver.java in our DroidBoy sample app. Visit this page for a basic tutorial on creating broadcast receivers: Android Receiver Help

Note: With notification action buttons, APPBOY_NOTIFICATION_OPENED intents fire when buttons with opens app or deep link actions are clicked. Deep link and extras handling remains the same. Buttons with close actions don’t fire APPBOY_NOTIFICATION_OPENED intents and dismiss the notification automatically.

Step 3: Access Custom Key/Value Pairs

Custom key/value pairs sent either via the dashboard or the messaging APIs will be accessible in your custom broadcast receiver for whatever purpose you choose:

// intent is the Appboy push intent received by your custom broadcast receiver.
String deepLink = intent.getStringExtra(Constants.APPBOY_PUSH_DEEP_LINK_KEY);

// The extras bundle extracted from the intent contains all custom key/value pairs.
Bundle extras = intent.getBundleExtra(Constants.APPBOY_PUSH_EXTRAS_KEY);

// example of getting specific key/value pair from the extras bundle.
String myExtra = extras.getString("my_key");

Note: Appboy push data keys are documented here.

Baidu Integration

Appboy is capable of sending push notifications to Android devices using Baidu Cloud Push. Our Baidu push sample app, China Push Sample, provides a full implementation example.

Note: Using Baidu Cloud Push does not require you to distribute your apps via the Baidu App Store.

Time Estimate: 60 Minutes

Step 1: Create a Baidu Account

  1. Visit the Baidu Portal. You will see a homepage similar to the following. Click 登录 (Log In) among the menu options on the top right to bring up a dialog that will allow you to log in or create a new account. Baidu Portal

  2. To create a new account, in the log-in dialog, click 立即注册 (New Account) directly to the bottom right of the large blue 登录 (Log In) button. Baidu Login Dialog

  3. Enter an email address, password, and captcha in the account creation page. Accept the license agreement and click 注册 (Create Account) to register. Baidu Sign-up Page

  4. You will recieve an email from Baidu. Follow the verification link. Make sure to follow the verification link within 48 hours. Baidu Verification Email

  5. On the following page, you will complete an SMS verification. Choose your country code (美国 in the example image denotes the United States). Enter your phone number and click 发送验证短信 (Send SMS). You should receive a text message containing a six-digit number, which you will enter in the 验证码 (Verification Code). Make sure to enter your verification code within 30 minutes. Click 提交 (Submit) to submit. Congratulations! You now have a Baidu account. Baidu Verification SMS

Step 2: Register as a Baidu Developer

  1. Visit the Baidu Developer Portal. Open the dropdown menu in the top right of the screen. Choose 注册开发者 (Create New Developer Account) to begin registration. Baidu Developer Portal

  2. On the registration page, choose your account type (个人 for personal, 公司 for business) and developer type (Developer is preselected and correct for most cases). Enter your name, a bio, and phone number with country code in parenthesis (For example, (1)xxxxxxxxxx). Click 发送验证码 (Send Verification Code) and enter the verification code in the following line. The next two fields, developer website and developer logo, are optional. Accept the license agreement and click 提交 (Submit) to submit. Congratulations! You now have a Baidu developer account. Baidu Developer Registration

Step 3: Register your Application with Baidu

  1. Visit the Baidu Project Portal. Click 创建工程 (Create Project). Baidu Project Portal

  2. On the following page, enter your application name. The following two checkboxes are to activate additional Baidu services. In most cases, these should be left blank. Baidu App Name

  3. Upon setting up your application, you will be taken to a console which displays information about your app, including the API Key. Click on the cloud push link in the menu on the left hand side of the console. On the following page, click 推送设置 (Set Up Push). Baidu App Console Baidu Continue

  4. On the following page, enter your app package name (e.g. com.appboy.sample) and specify whether to cache messages, and if so, how long. This indicates to Baidu how long to continue to attempt to send messages to offline users. Click 保存设置 (Save Settings) to save. Baidu Configure Cloud

Step 4: Add Baidu to your Application

  • Visit the Baidu Push SDK Portal and download the latest Baidu Cloud Push Android SDK. Baidu SDK Portal

  • Inside the SDK, you will find the push service jar and platform specific native libraries. Integrate these into your project. There is also a Baidu demo push application which can be used as a reference along with our sample Baidu push application. Make sure your app targets the highest SDK version currently supported by Baidu. This documentation is current for Baidu Cloud Push Android SDK version 4.6.2.38.

  • Add the following required Baidu permissions to your application’s AndroidManifest.xml. See our sample app’s AndroidManifest.xml for a sample implementation.

      <uses-permission android:name="android.permission.READ_PHONE_STATE" />
      <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
      <uses-permission android:name="android.permission.WRITE_SETTINGS" />
      <uses-permission android:name="android.permission.VIBRATE" />
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
      <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
      <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    
  • Baidu’s library contains broadcast receivers which handle incoming push messages. Declare the internal Baidu receivers in your application’s AndroidManifest.xml inside the <application> element.

    <!-- 用于接收系统消息以保证 PushService 正常运行 -->
        <receiver
          android:name="com.baidu.android.pushservice.PushServiceReceiver"
          android:process=":bdservice_v1">
          <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
            <action android:name="com.baidu.android.pushservice.action.notification.SHOW"/>
            <action android:name="com.baidu.android.pushservice.action.media.CLICK"/>
          </intent-filter>
        </receiver>
        <!-- Push 服务接收客户端发送的各种请求-->
        <!-- 注意:RegistrationReceiver 在 2.1.1 及之前版本有拼写失误,为 RegistratonReceiver ,用 新版本 SDK 时请更改为如下代码-->
        <receiver
          android:name="com.baidu.android.pushservice.RegistrationReceiver"
          android:process=":bdservice_v1">
          <intent-filter>
            <action android:name="com.baidu.android.pushservice.action.METHOD"/>
            <action android:name="com.baidu.android.pushservice.action.BIND_SYNC"/>
          </intent-filter>
          <intent-filter>
            <action android:name="android.intent.action.PACKAGE_REMOVED"/>
            <data android:scheme="package"/>
          </intent-filter>
        </receiver>
        <!-- Push 服务 -->
        <!-- 注意:在 4.0 (包含)之后的版本需加上如下所示的 intent-filter action -->
        <service
          android:name="com.baidu.android.pushservice.PushService"
          android:exported="true"
          android:process=":bdservice_v1">
          <intent-filter >
            <action android:name="com.baidu.android.pushservice.action.PUSH_SERVICE"/>
          </intent-filter>
        </service>
    
  • You will also need to create a broadcast receiver which listens for incoming push messages and notifications. Declare your own receiver in your application’s AndroidManifest.xml, inside the <application> element. This receiver will need to extend com.baidu.android.pushservice.PushMessageReceiver and implement methods that receive event updates from the Baidu push service. See our sample app’s receiver for a sample implementation.

        <receiver android:name=".MyPushMessageReceiver">
          <intent-filter>
            <action android:name="com.baidu.android.pushservice.action.MESSAGE"/>
            <action android:name="com.baidu.android.pushservice.action.RECEIVE"/>
            <action android:name="com.baidu.android.pushservice.action.notification.CLICK"/>
          </intent-filter>
        </receiver>
    
  • In your main activity’s onCreate() method, add the following line, which will register your application with Baidu and begin listening for incoming push messages. Make sure to replace “Your-API-Key” with your project’s Baidu API Key.

    PushManager.startWork(getApplicationContext(), PushConstants.LOGIN_TYPE_API_KEY, "Your-API-Key");
    
  • Finally, you will need to register your users with Appboy. In the onBind() method of the Baidu broadcast receiver that you created in part 5, send the channelId to Appboy using Appboy.registerAppboyPushMessages(channelId). See our sample app’s main activity for a sample implementation.

    Appboy.getInstance(context).registerAppboyPushMessages(channelId);
    

Step 5: Registering Push Opens

  • Baidu supports sending extra key value pairs with push messages in JSON format. Your broadcast receiver’s public void onNotificationClicked(Context context, String title, String description, String customContentString) method will be called whenever a user clicks an incoming push message. The parameter customContentString contains the extras in JSON format. All messages from Appboy will contain the following two key value pairs:

    {
      "source": "Appboy",
      "cid": "your-campaign-Id"
    }
    
  • Whenever onNotificationClicked is called your Baidu receiver, your receiver should send an Intent to your application containing customContentString. Your application will log the click to Appboy using the customContentString. See our sample app’s main activity for a sample implementation.

  • The following sample code passes customContentString to Appboy and logs a click.

    String customContentString = intent.getStringExtra(ChinaPushMessageReceiver.NOTIFICATION_CLICKED_KEY);
    AppboyNotificationUtils.logBaiduNotificationClick(mApplicationContext, customContentString);
    

Step 6: Extras

  • Aside from reserved keys used by Appboy, the parameter customContentString will also contain all user defined custom key value pairs. To extract your key value pairs, wrap customContentString in a JSONObject and retrieve your extras.

    try {
        JSONObject myExtras = new JSONObject(customContentString);
        String myValue = myExtras.optString("my_key", null);
      } catch (Exception e) {
        Log.e(TAG, String.format("Caught an exception processing customContentString: %s", customContentString), e);
      }
    

Step 7: Set Up Baidu Keys

You need to input your Baidu API Key and Baidu Secret Key into the Appboy dashboard. Both keys are available from the [Baidu application console][52].

On the app settings page (where your API keys are located), select your Android China app. Enter your Baidu API Key and Baidu Secret Key in their respective fields in the Push Notifications section.

APIKey

Resources

Troubleshooting

Understanding the Appboy/GCM Workflow

The Google Cloud Messaging (GCM) service is Google’s infrastructure for push notifications sent to Android applications. Here is the simplified structure of how push notifications are enabled for your users’ devices and how Appboy is able to send push notifications to them:

Step 1: Configuring Your Google Cloud API Key

In the development of your app, you’ll need to provide the Appboy Android SDK with your Google Project Number (also referred to as the Sender ID). Additionally, you’ll need to provide an API Key for server applications to the Appboy dashboard. Appboy will use this API key when we attempt to send messages to your devices. You will need to ensure that GCM service is enabled in the Google Developer’s console as well. More information about completing these steps is found in our Enabling Messaging Channels documentation for Android. Note: A common mistake in this step is using an API key for Android applications. This is a different, incompatible API key for the type of access Appboy needs.

Step 2: Devices Register for GCM and Provide Appboy with Push Tokens

In typical integrations, the Appboy Android SDK will handle the process of registering devices for GCM capability. This will usually happen immediately upon opening the app for the first time. After registration, Appboy will be provided with a GCM Registration ID, which is used to send messages to that device specifically. We will store the Registration ID for that user and that user will become “Push Registered” if they previously did not have a push token for any of your apps.

Step 3: Launching an Appboy Push Campaign

When a push campaign is launched, Appboy will make requests to GCM to deliver your message. Appboy will use the API key copied in the dashboard to authenticate and verify that we are allowed to send push notifications to the push tokens provided.

Step 4: Removing Invalid Tokens

If GCM informs us that any of the push tokens we were attempting to send a message to are invalid, we remove those tokens from the user profiles they were associated with. If that user has no other push tokens, they will no longer show up as “Push Registered” under the Segments page.

Google has more details about GCM in their Developers page.

Utilizing the Push Error Logs

Appboy provides a log of Push Notification Errors within the Message Activity Log. This error log provides a variety of warnings which can be very helpful for identifying why your campaigns aren’t working as expected. Clicking on an error message will redirect you to relevant documentation to help you troubleshoot a particular incident.

Push Error Log

Troubleshooting Scenarios

No “Push Registered” Users Showing in the Appboy Dashboard (Prior to Sending Messages)

Ensure that your app is correctly configured to allow push notifications. Common failure points to check include:

1. Incorrect Google Project Number

Ensure that the correct Google Project Number is included in the appboy.xml file. An incorrect Project Number will lead to MismatchSenderID errors reported in the dashboard’s Message Activity Log.

  • Additionally, in the Google Developers Console, under “APIs & auth” > “APIs”, make sure that “Google Cloud Messaging for Android” is set to “ON”. You will need to use the API Key found under “APIs & auth” for that specific project. GCMon
2. Appboy Registration Misconfigured (GCM only)

For users using GCM automatic registration by Appboy, Appboy must be set up to register devices for push notifications.

  • Ensure the AppboyGcmReceiver is properly registered in AndroidManifest.xml with an intent filter for: <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

Note: It may be useful to monitor your device’s logcat while opening the app for the first time to verify that registration was completed on your device. You should be looking for a message such as:

I/Appboy v1.x.x .com.appboy.Appboy( 5083): Google Cloud Messaging found.  Setting up Google Cloud Messaging

or

E/Appboy v1.x.x .com.appboy.Appboy(27790): Did not find support for Google Cloud Messaging or Amazon Device Messaging

These messages can help you interpret whether GCM registration is occuring properly on your device.

3. Appboy Registration Not Occurring (FCM only)

Since FCM registration is handled outside of Appboy, failure to register can only occur in two places:

  1. During registration with FCM
  2. When passing the FCM-generated push token to Appboy

We recommend setting a breakpoint or logging to ensure that the FCM-generated push token is being sent to Appboy. If a token is not being generated correctly or at all, we recommend consulting the FCM documentation.

4. Google Play Services not present

For GCM/FCM push to work, Google Play Services must be present on the device. If Google Play Services isn’t on a device, push registration will not occur.

Note: Google Play Services is not installed on Genymotion emulators or Android emulators without Google APIs installed.

5. Device not connected to internet

Ensure your device has good internet connectivity and that it isn’t sending network traffic through a proxy.

Push Notifications Bounced

If a push notification isn’t delivered, make sure it didn’t bounce by looking in the developer console. The following are descriptions of common errors that may be logged in the developer console:

Error: MismatchSenderID

MismatchSenderID indicates an authetication failure. Ensure sure your senderId and GCM API key are correct. See our section on debugging push registration for more information.

Error: InvalidRegistration

InvalidRegistration can be caused by a malformed push token.

  1. (FCM only) Make sure to pass a valid push token to Appboy from FCM by calling FirebaseInstanceId.getToken().

  2. (GCM only) If you are using Appboy side-by-side with another service that registers for push using GCM, ensure that only one service is registering for push and receiving push tokens. If you are using the other service to register for push, remove the following intent filter action from the AppboyGcmReceiver declaration in your AndroidManifest.xml: <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

Error: NotRegistered
  1. NotRegistered typically occurs when an app has been deleted from a device. Appboy uses NotRegistered internally as a signal that an app has been uninstalled from a device.

  2. NotRegistered may also occur when multiple registrations are occurring and a second registration is invalidating the first token.

Push Notifications Sent But Not Displayed on Users’ Devices

There are a few reasons why this could be occurring:

1. Application was Force Quit

If you force-quit your application through your system settings, your push notifications will not be sent. Launching the app again will re-enable your device to receive push notifications.

2. AppboyGCMReceiver Not Registered

The AppboyGcmReceiver must be properly registered in AndroidManifest.xml for push notifications to appear:

  <receiver android:name="com.appboy.AppboyGcmReceiver" android:permission="com.google.android.c2dm.permission.SEND">
  <intent-filter>
    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
    <category android:name="Your Application's Package Name" />
  </intent-filter>
</receiver>

For an implementation example, please check out our sample application’s AndroidManifest.xml

3. Firewall is Blocking Push

If you are testing push over Wi-Fi, your firewall may be blocking ports necessary for GCM to receive messages. Please ensure that ports 5228, 5229 and 5230 are open. Additionally, since GCM doesn’t specify its IPs, also allow your firewall to accept outgoing connections to all IP addresses contained in the IP blocks listed in Google’s ASN of 15169.

4. Custom Notification Factory Returning Null

If you have implemented a custom notification factory, ensure that it is not returning null. This will cause notifications not to be displayed.

“Push Registered” Users No Longer Enabled After Sending Messages

There are a few reasons why this could be happening:

1. Application was Uninstalled

Users have uninstalled the application. This will invalidate their GCM push token.

2. Invalid GCM API Key

The GCM API key provided in the Appboy dashboard is invalid. You will need to verify:

  • The API key is for server applications. It should look like this in your Google Developers Console: Server apps key

  • The API key provided is for the same Google Project that is referenced in your app’s appboy.xml file. Make sure that the Project Number matches what you entered in appboy.xml. Google Project Number

Push Clicks Not Logged

Appboy logs push clicks automatically, so this scenario should be comparatively rare.

If push clicks are not being logged, it is possible that push click data has not been flushed to Appboy’s servers yet. Appboy throttles the frequency of its flushes based on the strength of the network connection. With a good network connection, push click data should arrive at the server within a minute in most circumstances.

Deep links can be tested with ADB. We recommend testing your deep link with the following command:

adb shell am start -W -a android.intent.action.VIEW -d "THE_DEEP_LINK" THE_PACKAGE_NAME

If the deep link fails to work, the deep link may be misconfigured. A misconfigured deep link will not work when sent through Appboy push.

2. Verify Custom Handling Logic

If the deep link works correctly with ADB but fails to work from Appboy push, check whether any custom push open handling has been implemented. If so, verify that the custom handling code is properly handling the incoming deep link.

Silent Push Notifications

Silent notifications (AKA “Send to Sync messages”) allow you to notify your app when important events occur. You might have new instant messages to deliver, new issues of a magazine to publish, breaking news alerts to send, or the latest episode of your user’s favorite TV show ready for him or her to download for offline viewing. Silent notifications are great for sporadic but immediately important content, where the delay between background fetches might not be acceptable.

Silent notifications are available through our Messaging RESTful API. You need only set the send_to_sync flag to true within the Android Push Object. You should ensure there are no title or alert fields set within the Android Push Object as it will cause errors when send_to_sync is set to true. You can however still include data extras within the Android Push Object.

Silent notifications are also available within the dashboard. In order to send a silent notification, you need only to ensure the title and body fields of the notification are blank as pictured below:

Android Silent Push Example

This message will cause an intent to be received with an action .intent.APPBOY_PUSH_RECEIVED. Handling of this intent to cause any action such as a refresh of app content must be defined within the broadcast receiver you defined in Step 4 of Enabling Push Notifications - Android. Please see AppboyBroadcastReceiver.java for an example of this receiver.

Advanced Settings

There are many advanced settings available for Android and Fire OS push notifications sent through the Appboy dashboard. This article will describe these features and how to use them successfully.

Advanced Settings

Notification Priority

Specifying a priority level for Android and Fire OS notifications is possible via the Appboy dashboard and Messaging API. The priority level of a push notification affects how your notification is displayed in the notification tray relative to other notifications. It can also affect the speed and manner of delivery, as normal and lower priority messages may be sent with slightly higher latency or batched to preserve battery life whereas high priority messages are always sent immediately.

This feature is useful for differentiating your messages based on how critical or time-sensitive they are. For example, a notification about dangerous road conditions would be a good candidate to receive a high priority, while a notification about an ongoing sale should receive a lower priority. You should consider whether or not using a disruptive priority is actually necessary for the notification that you are sending as constantly taking the top spot in your users’ inbox or interrupting their other activities may have a negative impact.

The priority levels that you can set on Android or Fire OS push notifications are:

Priority Description/Intended Use priority value (for API messages)
Max Urgent or time-critical messages 2
High Important communication, such as a new message from a friend 1
Default Most notifications - use if your message doesn’t explicitly fall under any of the other priority types 0
Low Information that you want users to know about, but does not require immediate action -1
Min Contextual or background information. -2

For more information, please consult Google’s documentation on Android notifications.

Delivery Options

Both Google and Amazon’s push messaging services (GCM and ADM, respectively) allow you to set additional parameters for when and how your messages are delivered. GCM and ADM both follow roughly the same pattern in how these options are structured and utilized. The default behavior of these services is to send messages to devices as soon as they are received for delivery. However, depending on the use case, this may not be the best way to communicate to your users. To provide you with precise control over when your push messages are delivered, we have implemented ways to use GCM and ADM delivery options with Appboy campaigns.

For example, say that a user of a sports news app had their device offline the duration of a football game. The app sends out updates after one of the competing teams score, for a total of 10 push notifications over that duration. When the user reconnects to the messaging service, we would not want them to receive 10 redundant notifications. We have a few tools available to solve this problem.

  • The “Delay While Idle” value (Android only) specifies whether or not you’d like to delay sending the message until a user’s device is online. This can be used to ensure delivery of all of your push notifications, even if the end user is offline. When used in conjunction with a unique “Collapse Key”, “Delay While Idle” can prevent sending outdated information and clogging up the user’s notification inbox.

  • A “Collapse Key” is a unique identifier for a message category of your choosing that informs the messaging service to only respect the most recent message from that ID. Setting a collapse key allows you to send just the most recent and relevant message, rather than a stack of outdated, irrelevant ones. However, if the phone correctly receives the original push notifications, then the collapse key will not replace the already delivered notification.

    Note: GCM has a limit of 4 collapse keys per app. If you use more than 4 collapse keys, GCM does not make any guarantees as to which ones will be respected. Appboy uses 2 of these by default for campaigns and feedback responses, so make sure to specify only up to 2 additional collapse keys for Android messages.

  • The “Time to Live” field allows you to set a custom length of time to store messages with the push messaging service. Appboy’s default values for time to live are 4 weeks for GCM and 31 days for ADM. If the hypothetical user from the example above were to reconnect their device 4 weeks after the game with the time to live set to the default, then those messages would have already expired in the messaging service and would not be delivered.

For more information on these delivery options, please see the Google Cloud Messaging and Amazon Device Messaging documentation.

Summary Text

Summary text allows you to set additional text in the “Expanded Notification” view. It also serves as a caption for notifications with images.

Summary Text Example

The summary text will display below the body of the message in the expanded view.

For push notifications that include images, the message text will be shown in the collapsed view, while the summary text will be displayed as the image caption when the notification is expanded. See the animation below for an example of this behavior.

Summary Text Behavior

Custom URIs

The “Custom URI” feature allows you to specify a Web URL or an Android resource to navigate to when the notification is clicked. If no custom URI is specified, clicking on the notification brings users into your app. You can use the custom URI to deep link inside your app as well as direct users to resources that exist outside of your app as well. This can be specified via our Messaging API or via our dashboard under “Advanced Settings” in the push composer wizard as pictured below:

Note: To enable Custom URI, your app’s BroadcastReceiver must be configured to properly handle opening the URI. This involves parsing incoming message contents for the custom URI and navigating to it. Our example receiver provides a sample implementation.

Custom URI

Sounds

Appboy allows you to play a notification sound of your choice when sending a push message by specifying a local sound resource on the device (e.g. android.resource://com.mycompany.myapp/raw/mysound). Specifying “default” in this field will play the default notification sound on the device. This can be specified via our Messaging API or via our dashboard under “Advanced Settings” in the push composer wizard as pictured below:

Sounds

Enter the full sound resource URI (e.g. android.resource://com.mycompany.myapp/raw/mysound) into the dashboard prompt.

In-App Messaging

Time Estimate: 15 Minutes

In-App Messages are great for creating unobtrusive calls to action, notifying people of new content in the news feed and driving them toward it or communicating with users who have push turned off. They are also effective for other content that isn’t time-sensitive enough to warrant a push notification, or permanent enough to warrant a news feed item. You can find a detailed explanation of in-app message behavior in Appboy Academy.

Integration

Step 1: Appboy In-App Message Manager Registration

In-App Message display is managed by the AppboyInAppMessageManager class. Every activity in your app must be registered with the AppboyInAppMessageManager to allow it to add in-app message views to the view hierarchy. There are two ways to accomplish this:

Activity Lifecycle Callback Integration (API 14+)

The Activity Lifecycle Callback Integration handles in-app message registration automatically, no extra integration is required.

Non-Activity Lifecycle Callback Integration (API 13 and Lower)

In order for in-app messages to function appropriately on apps not using our Activity Lifecycle Callback Integration, EVERY activity must call the following within their onResume() and onPause() lifecycle methods respectively. See our Manual Integration sample for an example implementation.

// This should be called within the onResume() method
AppboyInAppMessageManager.getInstance().registerInAppMessageManager(Activity);
// This should be called within the onPause() method
AppboyInAppMessageManager.getInstance().unregisterInAppMessageManager(Activity);

Additionally, in order to ensure that all in-app messages get caught by the AppboyInAppMessageManager, we recommend calling ensureSubscribedToInAppMessageEvents in your Application.onCreate().

AppboyInAppMessageManager.getInstance().ensureSubscribedToInAppMessageEvents(getApplicationContext());

Without the above method call, any in-app messages triggered before the AppboyInAppMessageManager is registered for the first time could be lost, such as those triggered off session start events.

Note: For integration instructions for original in-app messages (deprecated), please see our section on integrating original in-app messages.

Congratulations, you’ve finished integrating in-app messages! Read on for descriptions of our default in-app message types, display semantics, customization options, and integrating advanced features such as GIFs.

In-App Message Types

Appboy offers several default in-app message types, each customizable with messages, images, Font Awesome icons, click actions, analytics, editable styling and color schemes. The currently available types are Slideup, Modal, Full, and HTML Full. It is also possible to define your own custom in-app message view.

All in-app messages implement the IInAppMessage interface, which defines basic behavior and traits for all in-app messages. InAppMessageBase is an abstract class that implements IInAppMessage and provides the foundational in-app message implementation. All in-app message classes are subclasses of InAppMessageBase.

In addition, there is a subinterface of IInAppMessage called IInAppMessageImmersive, which adds click action and analytics enabled buttons, as well as header text and a close button. InAppMessageImmersiveBase is an abstract class that implements IInAppMessageImmersive and provides the foundational immersive in-app message implementation. Modal and Full in-app messages are subclasses of InAppMessageImmersiveBase.

HTML Full in-app messages are InAppMessageHtmlFull instances, which implement IInAppMessageHtml, another subclass of IInAppMessage.

Slideup In-App Messages

Slideup in-app messages are so-named because they “slide up” or “slide down” from the top or bottom of the screen. They cover a small portion of the screen and provide an effective and non-intrusive messaging capability.

Slideup Example

Modal in-app messages appear in the center of the screen and are framed by a translucent panel. Useful for more critical messaging, they can be equipped with up to two click action and analytics enabled buttons.

Modal Example

Full In-App Messages

Full in-app messages are useful for maximizing the content and impact of your user communication. The upper half of a full in-app message contains an image and the lower half displays text as well as up to two click action and analytics enabled buttons.

Full Example

HTML Full In-App Messages

HTML Full in-app messages are useful for creating fully customized user content. User-defined HTML Full in-app message content is displayed in a WebView and may optionally contain other rich content, such as images and fonts, allowing for full control over message appearance and functionality.

The following example shows a survey HTML Full in-app message created by Soundcloud.

HTML5 Example

In-App Message Delivery

In-App Messages (Triggered)

The following documentation refers to Appboy’s In-App Messaging product, aka “triggered in-app messages,” which are branded as highlighted below in the “Create Campaign” drop-down:

In-App Messaging Composer

You may also refer to the documentation for our deprecated Original In-App Messaging product.

Trigger Types

Our in-app message product allows you to trigger in-app message display as a result of several different event types: Any Purchase, Specific Purchase, Session Start, Custom Event, Push Click. Furthermore, Specific Purchase and Custom Event triggers can contain robust property filters.

-Note: Triggered in-app messages only work with custom events logged through the SDK and not through the Rest APIs. If you’re working with Android, please check out how to log custom events here. If you’re working with iOS, check out how to log custom events here.

Delivery Semantics

All in-app messages that a user is eligible for are delivered to the user’s device on session start. For more information about the SDK’s session start semantics, see our session lifecycle documentation. Upon delivery, the SDK will pre-fetch assets so that they are available immediately at trigger time, minimizing display latency.

When a trigger event has more than one eligible in-app message associated with it, only the in-app message with the highest priority will be delivered.

For in-app messages that display immediately on deliver (i.e., session start, push click) there can be some latency due to assets not being prefetched.

Minimum Time Interval Between Triggers

By default, we rate limit in-app messages to once every 30 seconds to ensure a quality user experience.

To override this value, set com_appboy_trigger_action_minimum_time_interval_seconds in your appboy.xml. An example can be found in our sample application’s appboy.xml.

Original In-App Messages (Deprecated)

The following documentation refers to Appboy’s Original In-App Messaging product, branded as highlighted below in the “Create Campaign” drop-down:

Original In-App Messaging Composer

Original in-app messages request one in-app message at a time on session start. They are a deprecated feature and will be eventually removed in favor of triggered in-app messages. See our documentation about the key differences between original and triggered in-app messages, including reasons to use the latter.

Requesting New Original In-App Messages

With original in-app messages, messages are displayed upon receipt from Appboy’s servers instead of being triggered by in-app events. Calling Appboy.requestInAppMessageRefresh() is required to receive new in-app messages from Appboy.

We recommend calling requestInAppMessageRefresh() within your onResume() method whenever onResume() immediately follows onStart(). This ensures that when the application starts, it checks for new in-app messages and displays them if available but doesn’t make any unnecessary calls afterwards.

See the onStart() and onResume() lifecycle methods in AppboyFragmentActivity.java in our Droidboy sample app for an example implementation.

Local In-App Messages

In-app messages can be created within the app and displayed locally in real-time. All customization options available on the dashboard are also available locally. This is particularly useful for displaying messages that you wish to trigger within the app in real-time.

  // Initializes a new slideup type in-app message and specifies its message.
  InAppMessageSlideup inAppMessage = new InAppMessageSlideup();
  inAppMessage.setMessage("Welcome to Appboy! This is a slideup in-app message.");

Note: Do not display in-app messages when the soft keyboard is displayed on screen as rendering is undefined in this circumstance.

Manually Triggering In-App Message Display

The following method will manually display your in-app message.

  AppboyInAppMessageManager.getInstance().addInAppMessage(inAppMessage);

See InAppMessageTesterFragment.java in the DroidBoy sample app for example usage.

In-Depth: Defining Custom In-App Message Types

Appboy’s slideup in-app message object extends InAppMessageBase. Appboy’s full and modal type messages extend InAppMessageImmersiveBase. Extending one of these classes gives you the option of adding custom functionality to your locally generated in-app messages.

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

Customization

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:

Map<String, String> getExtras()

See the Javadoc for more information.

Custom Styling

Appboy 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 Appboy SDK’s styles.xml file.

  <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.

Using Custom Styling to Set a Custom Font

Appboy has defined a custom font attribute called appboyInAppMessageCustomFontFile that allows the use of custom fonts. To use it, override the style for message text, headers, and/or button text and use the custom font attribute to instruct Appboy to use your custom font.

For example, to update the font on your in-app message button text, override the Appboy.InAppMessage.Button style and include our custom appboyInAppMessageCustomFontFile attribute. The attribute value should point to a .ttf font file in your /assets directory.

Here is a truncated example with appboyInAppMessageCustomFontFile set on the last line:

  <style name="Appboy.InAppMessage.Button">
    <item name="android:layout_height">wrap_content</item>
    ...
    <item name="android:paddingBottom">15.0dp</item>
    <item name="appboyInAppMessageCustomFontFile">my-awesome-font.ttf</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 across all possible in-app message text, you must override all three styles.

Note: As with other custom styles, the entire style must be copied over to your local styles.xml file for all attributes to be correctly set.

For a complete example, see our sample app Droidboy’s tablet styles.xml file. It uses a custom font for its message and button text and italic text for its header text.

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 recieve 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 Appboy, the onInAppMessageReceived() method will be called. If this method returns true, that signals to AppboyInAppMessageManager that the in-app message will be handled by the host app and that it should not be displayed by Appboy. If false is returned, the AppboyInAppMessageManager attempts 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: Instruct Appboy to use your In-App Message Manager Listener

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

Note: We recommend setting your IInAppMessageManagerListener in your Application.onCreate() before any other calls to Appboy. 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:

  @Override
  public InAppMessageOperation beforeInAppMessageDisplayed(IInAppMessage inAppMessageBase) {
    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.

Note: If you choose to DISCARD the in-app message and replace it with your own in-app message view, you will need to manually log in-app message clicks and impressions.

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

Note: Once an in-app message has been placed on the stack, you can request for it to be retrieved and displayed at any time by calling AppboyInAppMessageManager.requestDisplayInAppMessage(). Calling this method requests Appboy to display the next available in-app message from the stack.

Setting a Custom View Factory

Appboy’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, Appboy makes this possible via setting a custom view factory.

Step 1: Implement an In-App Message View Factory

Create a class that implements IInAppMessageViewFactory

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

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

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

In-Depth: Implementing an Appboy View Interface

Appboy’s slideup in-app message view implements IInAppMessageView. Appboy’s full and modal type message views implement IInAppMessageImmersiveView. Implementing one of these classes will allow Appboy to add click listeners to your custom view where appropriate. All Appboy 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.

Client Example

The following image is an example custom In-App Message view from an Appboy client:

Foodo In-App Message Customization Example

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, Appboy 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 Appboy to use your In-App Message View Factory

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

Note: We recommend setting your IInAppMessageAnimationFactory in your Application.onCreate() before any other calls to Appboy. 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 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.

public InAppMessageOperation beforeInAppMessageDisplayed(IInAppMessage inAppMessage) {
  // Set the orientation to portrait
 inAppMessage.setOrientation(Orientation.PORTRAIT);
 return InAppMessageOperation.DISPLAY_NOW;
}

GIFs

Appboy requires Facebook’s Fresco image library to display animated GIFs with in-app messages.

Fresco is neither included nor enabled in the Appboy library by default, and must be included and enabled explicitly by the parent app. Without Fresco included and enabled, GIFs will still appear, but they will not be animated.

Note: Our DroidBoy sample app contains a sample end-to-end integration of Fresco with Appboy.

Integration

If you are already using a compatible version of Fresco in your app, skip to Step 3.

If you are not yet using Fresco in your app, start with Step 1:

Step 1: Add Fresco as a Dependency

Add

compile "com.facebook.fresco:fresco:0.9.0"

to the dependencies block of your build.gradle.

Step 2: Initialize Fresco

In your app’s Application file, initialize Fresco in your application’s onCreate() method.

Example:

@Override
  public void onCreate() {
    Fresco.initialize(getApplicationContext());
  }

For more information, visit Getting Started with Fresco or the Fresco class Javadoc.

Note: If your app doesn’t already have a class that extends Application, you will need to create one and make sure the name attribute of the application element in your AndroidManifest.xml references it. See DroidboyApplication.java and AndroidManifest.xml from our DroidBoy sample application for an example.

Note: To ensure Fresco is available for Appboy to use, make sure Fresco is always initialized when the app is in the foreground and if you call Fresco.shutDown() in your app, ensure you don’t do so until the app is backgrounded.

Step 3: Enable Fresco Use in the Appboy SDK

Add

<bool name="com_appboy_enable_fresco_library_use">true</bool>

to your appboy.xml to allow Appboy to use Fresco to display in-app message images. Integration is now complete and GIFs included with in-app messages should animate successfully.

Step 4: Proguard

If you are Proguarding your app, make sure to add Fresco’s proguard directives, available at http://frescolib.org/docs/proguard.html.

GIFs should now animate successfully on all in-app message types.

Advanced Notes

Android Dialogs

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

Button Text Capitalization

Android Material Design specifies that Button text should be upper case by default. Appboy’s in-app message buttons follow this convention as well.

Youtube in HTML in-app messages

Starting in Appboy 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.

Troubleshooting

Troubleshooting Scenarios

Expected In-App Message Did Not Display

Most in-app message issues can be broken down into two main categories: delivery and display. To troubleshoot why an expected in-app message did not display on your device, you should first ensure that the in-app message was delivered to the device, then troubleshoot message display.

Impression or Click Analytics Aren’t Being Logged

If you have set an in-app message delegate to manually handle message display or click actions, you’ll need to manually log clicks and impressions on the in-app message.

Impressions Are Lower Than Expected

Triggers take time to sync to the device on session start, so there can be a race condition if users log an event or purchase right after they start a session. One potential workaround could be changing the campaign to trigger off of session start, then segmenting off of the intended event or purchase. Note that this would deliver the in-app message on the next session start after the event has occurred.

In-App Message Delivery

The SDK requests in-app messages from Appboy’s servers on session start. To check if in-app messages are being delivered to your device, you’ll need to ensure that in-app messages are being both requested by the SDK and returned by Appboy’s servers.

Check If Messages Are Requested and Returned

  1. Add yourself as a test user on the Dashboard.
  2. Set up an in-app message campaign targeted at your user.
  3. Ensure that a new session occurs in your application.
  4. Use the Event User Logs to check that your device is requesting in-app messages on session start. Find the SDK Request associated with your test user’s session start event.
    • If your app was meant to request triggered In-App Messages, you should see trigger in the Requested Responses field under Response Data.
    • If your app was meant to request Original In-App Messages, you should see in_app in the Requested Responses field under Response Data.
  5. Use the Event User Logs to check if the correct in-app messages are being returned in the Response Data.

In-App Message

Troubleshoot Messages Not Being Requested

If your in-app messages are not being requested, your app might not be tracking sessions correctly, as in-app messages are refreshed upon session start. Also be sure that your app is actually starting a session based on your app’s session timeout semantics:

Session Start

Troubleshoot Messages Not Being Returned

If your in-app messages are not being returned, you’re likely experiencing a campaign targeting issue:

  • Your segment does not contain your user.
    • Check your user’s Engagement tab to see if the correct segment appears under Segments.
  • Your user has previously received the in-app message and was not re-eligible to receive it again.
    • Check the campaign re-eligibility settings under the Delivery tab of the Campaign Composer and make sure the re-eligibility settings align with your testing setup.
  • Your user hit the frequency cap for the campaign.
  • If there was a control group on the campaign, your user may have fallen into the control group.
    • You can check if this has happened by creating a segment with a “Received Campaign Variant” filter, where the campaign variant is set to “Control”, and checking if your user fell into that segment.
    • When creating campaigns for integration testing purposes, make sure to opt-out of adding a control group.

In-App Message Display

If your app is successfully requesting and receiving in-app messages but they are not being shown, some device-side logic may be preventing display:

  • Triggered in-app messages are rate-limited based on the minimum time interval between triggers, which defaults to 30 seconds.
  • If you have set a delegate to customize in-app message handling, check your delegate to ensure it is not affecting in-app message display.
  • Failed image downloads will prevent in-app messages with images from displaying. Image downloads will always fail if the AppboyInAppMessageManager is not registered properly. Check your device logs to ensure that image downloads are not failing.
  • If the device orientation did not match the orientation specified by the in-app message, the in-app message will not display. Make sure that your device is in the correct orientation.

News Feed

The News Feed is a fully customizable in-app content feed for your users. Our targeting and segmentation allows you to create a stream of content that is individually catered to the interests of each user. Depending on their position in the user life cycle and the nature of your app, this could be an on-boarding content server, an advertisement center, an achievement center, or a generic news center.

Time Estimate: 10 Minutes

Example News Feed

Sample News Feed

News Feed Integration Overview

In Android, the news feed and feedback form are implemented as Fragments that are available in the Appboy Android UI project. View Google’s documentation on Fragments for information on how to add a Fragment to an Activity.

Note: The Android UI Fragments do not automatically track session analytics. To ensure that sessions are tracked correctly, you should call IAppboy.openSession() when your app is opened (learn more about tracking user sessions).

The AppboyFeedFragment class will automatically refresh and display the contents of the news feed and log usage analytics. The cards that can appear in a user’s news feed are set on the Appboy dashboard.

Linking to the news feed from an in-app message must be enabled by registering the AppboyFeedActivity within your AndroidManifest.xml file.

Implementation Example

See DroidBoyActivity.java in the Droidboy sample app.

News Feed Customization

Default Styling

The Appboy UI elements (the feedback form and news feed) 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 res/values/style.xml file in the Appboy SDK distribution.

  <style name="Appboy"/>
  <!-- Feedback -->
  <style name="Appboy.Feedback"/>
  <style name="Appboy.Feedback.Layout"/>
  <style name="Appboy.Feedback.NavigationBar">
    <item name="android:padding">4dp</item>
    <item name="android:background">@color/com_appboy_feedback_form_navigation_bar_background</item>
  </style>
  <style name="Appboy.Feedback.NavigationBarCancelButton">
    <item name="android:layout_marginRight">2dp</item>
    <item name="android:text">@string/com_appboy_feedback_form_cancel</item>
    <item name="android:textStyle">bold</item>
  </style>

Overriding Styles

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 of the attributes to be correctly set.

Correct Style Override

<style name="Appboy.Feed.List">
  <item name="android:background">@color/mint</item>
  <item name="android:cacheColorHint">@color/mint</item>
  <item name="android:divider">@android:color/transparent</item>
  <item name="android:dividerHeight">16.0dp</item>
  <item name="android:paddingLeft">12.5dp</item>
  <item name="android:paddingRight">5.0dp</item>
  <item name="android:scrollbarStyle">outsideInset</item>
</style>

Incorrect Style Override

<style name="Appboy.Feed.List">
  <item name="android:background">@color/mint</item>
  <item name="android:cacheColorHint">@color/mint</item>
</style>

Feed Style Elements

Below is a description of the themable Appboy UI elements and their names for styling purposes:

Android Feed Android Cards Android Empty Android Network Error

Setting a Custom News Feed Click Listener

As of Android SDK v.1.14.0, you can handle News Feed clicks manually by setting a custom News Feed click listener. This enables use cases such as selectively using the native web browser to open web links.

Step 1: Implement A News Feed Click Listener

Create a class that implements IFeedClickActionListener. Implement the onFeedCardClicked() method, which will be called when the user clicks a News Feed card.

See CustomFeedClickActionListener.java in our Droidboy sample application for an example implementation.

Step 2: Instruct Appboy to Use Your News Feed Click Listener

Once your IFeedClickActionListener is created, call AppboyFeedManager.getInstance().setFeedCardClickActionListener() to instruct AppboyFeedManager to use your custom IFeedClickActionListener.

See PreferencesActivity.java in our Droidboy sample application for an example implementation.

Fully Custom Feed Display

If you would like to display the feed in a completely custom manner, it is possible to do so by using your own views populated with data from our models. To obtain Appboy’s News Feed models, you will need to subscribe for News Feed updates and use the resulting model data to populate your views. You will also need to log analytics on the model objects as users interact with your views.

Part 1: Subscribing to Feed Updates

First, declare a private variable in your custom feed class to hold your subscriber:

// subscriber variable
private IEventSubscriber<FeedUpdatedEvent> mFeedUpdatedSubscriber;

Next, add the following code to subscribe to feed updates from Appboy, typically inside of your custom feed activity’s Activity.onCreate():

// Remove the old subscription first
Appboy.getInstance(this).removeSingleSubscription(mFeedUpdatedSubscriber, FeedUpdatedEvent.class);
mFeedUpdatedSubscriber = new IEventSubscriber<FeedUpdatedEvent>() {
  @Override
  public void trigger(final FeedUpdatedEvent event) {
    // This list of Card objects included in the FeedUpdatedEvent should be used to populate your News Feed views.
    List<Card> cards = event.getFeedCards();
    // your logic here
  }
};
Appboy.getInstance(this).subscribeToFeedUpdates(mFeedUpdatedSubscriber);

// Request a refresh of feed data
Appboy.getInstance(this).requestFeedRefresh();

We also recommend unsubscribing when your custom feed activity moves out of view. Add the following code to your activity’s onDestroy() lifecycle method:

Appboy.getInstance(this).removeSingleSubscription(mFeedUpdatedSubscriber, FeedUpdatedEvent.class);

Part 2: Logging Analytics

When using custom views, you will need to log analytics manually as well, since analytics are only handled automatically when using Appboy views.

To log a display of the feed, call Appboy.logFeedDisplayed().

To log an impression or click on a Card, call Card.logClick() and Card.logImpression() respectively.

Categories

Defining a News Feed Category

Instances of the Appboy News Feed can be configured to only receive cards from a certain “category”. This allows for effective integration of multiple news feed streams within a single application. For more information on this feature see Appboy Academy

News Feed Categories can be defined by calling the following methods as you load the News Feed:

newsFeed.setCategories(CardCategory.ALL_CATEGORIES);
newsFeed.setCategories(CardCategory.ADVERTISING);
newsFeed.setCategories(CardCategory.ANNOUNCEMENTS);
newsFeed.setCategories(CardCategory.NEWS);
newsFeed.setCategories(CardCategory.SOCIAL);
newsFeed.setCategories(CardCategory.NO_CATEGORY);

You can also populate a feed with a combination of categories as in the following example:

newsFeed.setCategories:EnumSet.of(CardCategory.ANNOUNCEMENTS, CardCategory.NEWS);

Read/Unread Indicators

Appboy allows you to optionally toggle on an Unread/Read indicator on news feed cards as pictured below:

UnreadvsRead

Enabling the Indicators

In order to enable this functionality add the following line to your appboy.xml file:

<bool name="com_appboy_newsfeed_unread_visual_indicator_on">true</bool>

Customizing the Indicators

These indicators can be customized by altering the values in android-sdk-ui/src/main/res/drawable-hdpi/icon_unread.png and android-sdk-ui/src/main/res/drawable-hdpi/icon_read.png.

Card Types

Appboy has 5 unique news feed card types which share a base model. Each card type also has additional card-specific properties which are listed below.

Base Card

The Base Card model provides foundational behavior for all cards.

  • getId() - returns the card’s ID set by Appboy
  • getViewed() - returns a boolean reflects if the card is read or unread by the user
  • getExtras() - returns a map of key-value extras for this card
  • setViewed(boolean) - sets a card’s viewed field
  • getCreated() - returns the unix timestamp of the card’s creation time from Appboy dashboard
  • getUpdated() - returns the unix timestamp of the card’s latest update time from Appboy dashboard
  • getCategories() - returns the list of categories assigned to the card, cards without a category will be assigned ABKCardCategoryNoCategory
  • isInCategorySet(EnumSet) - returns true if the card belongs to the given category set

Banner Image Cards are clickable full-sized images. In addition to the base card properties:

  • getImageUrl() - returns the URL of the card’s image
  • getUrl() - returns the URL that will be opened after the card is clicked on. It can be a http(s) URL or a protocol URL
  • getDomain() - returns link text for the property url.

Captioned Image Card

Captioned Image Cards are clickable full-sized images with accompanying descriptive text. In addition to the base card properties:

  • getImageUrl() - returns the URL of the card’s image
  • getTitle() - returns the title text for the card
  • getDescription() - returns the body text for the card
  • getUrl() - returns the URL that will be opened after the card is clicked on. It can be a http(s) URL or a protocol URL
  • getDomain() - returns the link text for the property url.

Text Announcement Card (Captioned Image without Image)

Text Announcement Cards are clickable cards containing descriptive text. In addition to the base card properties:

  • getTitle() - returns the title text for the card
  • getDescription() - returns the body text for the card
  • getUrl() - returns the URL that will be opened after the card is clicked on. It can be a http(s) URL or a protocol URL
  • getDomain() - returns the link text for the property url.

Short News Card

Short News Cards are clickable cards with images and accompanying descriptive text. In addition to the base card properties:

  • getImageUrl() - returns the URL of the card’s image
  • getTitle() - returns the title text for the card
  • getDescription() - returns the body text for the card
  • getUrl() - returns the URL that will be opened after the card is clicked on. It can be a http(s) URL or a protocol URL
  • getDomain() - returns the link text for the property url.

Cross Promotion Small Card

Cross-Promotion Small Cards link to items in the Google Play Store or Kindle Store. In addition to the base card properties:

  • getTitle() - returns the title text for the card. This will be the promoted item’s name.
  • getSubtitle() - returns the text of the category of the promoted item
  • getImageUrl() - returns property is the URL of the card’s image.
  • getPackage() - reutrns the package name of the promoted item.
  • getRating() - returns the rating of the promoted app. This property will be 0.0 unless the promoted item is an app, in which case the rating will be in the range of [0.0, 5.0];
  • getPrice() - returns the price of the promoted app.
  • getReviewCount() - returns the number of reviews of the promoted app. This property will be 0 unless the promoted item is an app.
  • getCaption() - returns the text that will be displayed in the tag on the top of the small cross promotion card.
  • getUrl() - returns the url of the promoted item which leads to the item’s App Store page.

Adding a Badge

You can request the number of unread cards at any time by calling:

getUnreadCardCount()

See the Javadoc for more information.

Refreshing the Feed

You can queue a manual refresh of the Appboy News Feed at any time by calling:

Appboy.requestFeedRefresh()

See the Javadoc for more information.

Key/Value Pairs

Card objects may optionally carry key value pairs as extras. These can be used to send data down along with a Card for further handling by the application.

Call the following on a Card object to retrieve its extras:

Map<String, String> getExtras()

See the Javadoc for more information.

GIFs

Appboy requires Facebook’s Fresco image library to display animated GIFs with the News Feed.

Fresco is neither included nor enabled in the Appboy library by default, and must be included and enabled explicitly by the parent app. Without Fresco included and enabled, GIFs will still appear, but they will not be animated.

Note: Our DroidBoy sample app contains a sample end-to-end integration of Fresco with Appboy.

Integration

If you are already using a compatible version of Fresco in your app, skip to Step 3.

If you are not yet using Fresco in your app, start with Step 1:

Step 1: Add Fresco as a Dependency

Add

compile "com.facebook.fresco:fresco:0.9.0"

to the dependencies block of your build.gradle.

Step 2: Initialize Fresco

In your app’s Application file, initialize Fresco in your application’s onCreate() method.

Example:

@Override
  public void onCreate() {
    Fresco.initialize(getApplicationContext());
  }

For more information, visit Getting Started with Fresco or the Fresco class Javadoc.

Note: If your app doesn’t already have a class that extends Application, you will need to create one and make sure the name attribute of the application element in your AndroidManifest.xml references it. See DroidboyApplication.java and AndroidManifest.xml from our DroidBoy sample application for an example.

Note: To ensure Fresco is available for Appboy to use, make sure Fresco is always initialized when the app is in the foreground and if you call Fresco.shutDown() in your app, ensure you don’t do so until the app is backgrounded.

Step 3: Enable Fresco Use in the Appboy SDK

Add

<bool name="com_appboy_enable_fresco_library_use">true</bool>

to your appboy.xml to allow Appboy to use Fresco to display in-app message images. Integration is now complete and GIFs included with in-app messages should animate successfully.

Step 4: Proguard

If you are Proguarding your app, make sure to add Fresco’s proguard directives, available at http://frescolib.org/docs/proguard.html.

GIFs should now animate successfully on all in-app message types.

Analytics

Session Tracking

The Appboy SDK reports session data that is used by the Appboy dashboard to calculate user engagement and other analytics integral to understanding your users. Based on the below session semantics, our SDK generates “start session” and “close session” data points that account for session length and session counts viewable within the Appboy Dashboard.

Session Lifecycle

If you have integrated Appboy using our recommended Activity Lifecycle Callback Integration, openSession() and closeSession() will be called automatically for each Activity in your app. By default, sessions on Android are opened upon the first call to openSession() and are closed after an app has been out of the foreground for longer than 10 seconds. Note that calling closeSession() does not close a session immediately. Rather, it closes a session in 10 seconds if the user doesn’t call openSession() (e.g., by navigating to another Activity) in the interim.

An Android session times out after 10 seconds without any communication from the host application. This means if a user backgrounds the app and returns 9 seconds later, the same session will be continued.

Note: If a session closes while the user has the app backgrounded, that data may not be flushed to the server until the app is opened again.

Note: If you need to force a new session, you can do so by changing users.

Customizing Session Timeout

To customize the session timeout, add com_appboy_session_timeout to your appboy.xml file:

<!-- The length of time before a session times out in seconds. The session manager will "re-open"
otherwise closed sessions if the call to StartSession comes within this interval. (default is 10) -->
<integer name="com_appboy_session_timeout">NUMBER_OF_SECONDS_UNTIL_SESSION_TIMEOUT</integer>

If you have set a session timeout, then the above session semantics all extend to that customized timeout.

Testing Session Tracking

To detect sessions via your user, find your user on the dashboard and navigate to “App Usage” on the user profile. You can confirm that session tracking is working by checking that the “Sessions” metric increases when you would expect it to.

test_session

Setting User IDs

User IDs should be set for each of your users. These should be unchanging and accessible when a user opens the app. A database ID or a hashed email address/username is usually a good reference to use. We strongly recommend providing this identifier as it will allow you to:

  • Track your users across devices and platforms, improving the quality of your behaviorial and demographic data.
  • Import data about your users using our User Data API.
  • Target specific users with our Messaging API for both general and transactional messages.

Note: If such an identifier is not available, Appboy will assign a unique identifier to your users, but you will lack the capabilities above. You should avoid setting User IDs for users for whom you lack a unique identifier that is tied to them as an individual. Passing a device identifier offers no benefit versus the automatic anonymous user tracking Appboy offers by default.

Note: These User IDs should be private and not easily obtained (e.g. not a plain email address or username).

Assigning a User ID

Time Estimate: 3 Minutes

You should make the following call as soon as the user is identified (generally after logging in) in order to set the user id:

Appboy.getInstance(YOUR_ACTIVITY.this).changeUser(YOUR_USER_ID_STRING);

Note: Do not call changeUser() when a user logs out. changeUser() should only be called when the user logs into the application. Setting changeUser() to a static default value will associate ALL user activity with that default “user” until the user logs in again. Additionally, we recommend against changing the user ID when a user logs out, as it makes you unable to target the previously logged-in user with reengagement campaigns. If you anticipate multiple users on the same device, but only want to target one of them when your app is in a logged out state, we recommend separately keeping track of the user ID you want to target while logged out and switching back to that user ID as part of your app’s logout process.

Refer to the changeUser documentation for more information.

Implementation Example

See the UserProfileDialog.java file in the Droidboy sample app.

Full class information can be found in the javadocs.

Automatic Preservation of Anonymous User History

Identification Context Preservation Behavior
User has not been previously identified Anonymous history is merged with user profile upon identification
User has been previously identified in-app or via API Anonymous history is not merged with user profile upon identification

Additional Notes and Best Practices

Please note the following:

  • If your app is used by multiple people, you can assign each user a unique identifier to track them.
  • Once a user ID has been set, you cannot revert that user to an anonymous profile
  • Do Not change the user ID upon a user “log out”.
    • Doing so separates the device from the user profile. You will be unable to target the previously logged out user with re-engagement messages. If you anticipate multiple users on the same device, but only want to target one of them when your app is in a logged out state, we recommend separately keeping track of the user ID you want to target while logged out and switching back to that user ID as part of your app’s logout process. By default, only the last user that was logged in will receive push notifications from your app.
  • Switching from one identified user to another is a relatively costly operation.
    • When you request the user switch, the current session for the previous user is automatically closed and a new session is started. Furthermore, Appboy will automatically make a data refresh request for the news feed, slideup and other Appboy resources for the new user.
  • Note: If you opt to use a hash of a unique identifier as your userID take care to ensure that you’re normalizing the input to your hashing function.
    • e.g. If you’re going to use a hash of an email address, ensure that you’re stripping leading and trailing whitespace from the input, and taking localization problems into account.

Tracking Custom Events

You can record custom events in Appboy to learn more about your app’s usage patterns and to segment your users by their actions on the dashboard.

Before implementation, be sure to review examples of the segmentation options afforded by Custom Events vs. Custom Attributes vs Purchase Events in our Analytics Overview.

Adding A Custom Event

Time Estimate: 5 Minutes

Appboy.getInstance(YOUR_ACTIVITY.this).logCustomEvent(YOUR_EVENT_NAME);

See the Javadoc for more information.

Adding Properties

You can add metadata about custom events by passing an Appboy Properties object with your custom event.

Properties are defined as key-value pairs. Keys are String objects and values can be String, int, float, boolean, or Date objects.

AppboyProperties eventProperties = new AppboyProperties();
eventProperties.addProperty("key", "value");
Appboy.getInstance(YOUR_ACTIVITY.this).logCustomEvent(YOUR_EVENT_NAME, eventProperties);

Reserved Keys

The following keys are RESERVED and CANNOT be used as Custom Event Properties:

  • time
  • product_id
  • quantity
  • event_name
  • price
  • currency

See the Javadoc for more information.

Implementation Examples

See DecisionFragment.java and CustomLoggingDialog.java in the Droidboy sample app.

Setting Custom Attributes

Appboy provides methods for assigning attributes to users. You’ll be able to filter and segment your users according to these attributes on the dashboard.

Before implementation, be sure to review examples of the segmentation options afforded by Custom Events vs. Custom Attributes vs Purchase Events in our Analytics Overview.

Time Estimate: 5 Minutes

Assigning Standard User Attributes

To assign attributes to your users, call the getCurrentUser() method on your Appboy instance to get a reference to the current user of your app. Once you have a reference to the current user, you can call methods to set predefined or custom attributes.

Appboy provides predefined methods for setting the following user attributes within the AppboyUser class. See the JavaDocs for method specifications:

  • First Names
  • Last Names
  • Country
  • Date of Birth
  • Email
  • Avatar Image URLs for Appboy User Profiles
  • Gender
  • Home City
  • Phone Number
  • Facebook Data
  • Twitter Data

All string values such as first name, last name, country, and home city are limited to 255 characters. Avatar Image URLs are limited to 1024 characters.

We strongly recommend collecting email addresses even if you’re not sending emails through Appboy. Email makes it easier to search for individual user profiles and troubleshoot issues as they arise.

Implementation Example This is what setting a first name would look like in code:

Appboy.getInstance(YOUR_ACTIVITY.this).getCurrentUser().setFirstName("SomeFirstName");

See UserProfileDialog.java in the Droidboy sample app.

Assigning Custom User Attributes

In addition to our predefined user attribute methods, Appboy also provides custom attributes to track data from your applications. Appboy Custom Attributes can be set with the following data types:

  • Strings
  • Arrays
    • Includes methods to set arrays, add items to existing arrays, and delete items from existing arrays.
  • Integers
  • Booleans
  • Dates
  • Longs
  • Floats

Full method specifications for custom attributes can be found here within the AppboyUser class within the Javadocs.

Setting a Custom Attribute with a String Value

Appboy.getInstance(YOUR_ACTIVITY.this).getCurrentUser().setCustomUserAttribute(
  YOUR_ATTRIBUTE_KEY_STRING,
  YOUR_STRING_VALUE
);

Setting a Custom Attribute with an Integer Value

Appboy.getInstance(YOUR_ACTIVITY.this).getCurrentUser().setCustomUserAttribute(
  YOUR_ATTRIBUTE_KEY_STRING,
  YOUR_INT_VALUE
// Integer attributes may also be incremented using code like the following:
Appboy.getInstance(YOUR_ACTIVITY.this).getCurrentUser().incrementCustomUserAttribute(
  YOUR_ATTRIBUTE_KEY_STRING,
  THE_INTEGER_VALUE_BY_WHICH_YOU_WANT_TO_INCREMENT_THE_ATTRIBUTE
);

Setting a Custom Attribute with a Boolean Value

Appboy.getInstance(YOUR_ACTIVITY.this).getCurrentUser().setCustomUserAttribute(
  YOUR_ATTRIBUTE_KEY_STRING,
  YOUR_BOOLEAN_VALUE
);

Setting a Custom Attribute with a Long Value

Appboy.getInstance(YOUR_ACTIVITY.this).getCurrentUser().setCustomUserAttribute(
  YOUR_ATTRIBUTE_KEY_STRING,
  YOUR_LONG_VALUE
);

Setting a Custom Attribute with a Float Value

Appboy.getInstance(YOUR_ACTIVITY.this).getCurrentUser().setCustomUserAttribute(
  YOUR_ATTRIBUTE_KEY_STRING,
  YOUR_FLOAT_VALUE
);

Setting a Custom Attribute with a Date Value

Appboy.getInstance(YOUR_ACTIVITY.this).getCurrentUser().setCustomUserAttribute(
  YOUR_ATTRIBUTE_KEY_STRING,
  YOUR_DATE_VALUE
);
// This method will assign the current time to a custom attribute at the time the method is called:
Appboy.getInstance(YOUR_ACTIVITY.this).getCurrentUser().setCustomUserAttributeToNow(
  YOUR_ATTRIBUTE_KEY_STRING
);
// This method will assign the date specified by secondsFromEpoch to a custom attribute:
Appboy.getInstance(YOUR_ACTIVITY.this).getCurrentUser().setCustomUserAttributeToSecondsFromEpoch(
  YOUR_ATTRIBUTE_KEY_STRING,
  long secondsFromEpoch
);
);

Note: Dates passed to Appboy with this method must either be in the ISO 8601 format, e.g 2013-07-16T19:20:30+01:00 or in the yyyy-MM-dd'T'HH:mm:ss.SSSZ format e.g 2016-12-14T13:32:31.601-0800

Setting a Custom Attribute with an Array Value

Note: The maximum number of elements in Custom Attribute Arrays defaults to 25. The maximum for individual arrays can be increased to up to 100 in the Appboy Dashboard, under “Manage App Group -> Custom Attributes”. Arrays exceeding the maximum number of elements will be truncated to contain the maximum number of elements. For more information on Custom Attribute Arrays and their behavior, see our Documentation on Arrays.

// Setting a custom attribute with an array value
appboyUser.setCustomAttributeArray("custom_attribute_array_test", testSetArray);
// Adding to a custom attribute with an array value
appboyUser.addToCustomAttributeArray("custom_attribute_array_test", testAddString);
// Removing a value from an array type custom attribute
appboyUser.removeFromCustomAttributeArray("custom_attribute_array_test", testRemString);

Unsetting a Custom Attribute

Custom Attributes can also be unset using the following method:

Appboy.getInstance(YOUR_ACTIVITY.this).getCurrentUser().unsetCustomUserAttribute(
  YOUR_ATTRIBUTE_KEY_STRING
);

Setting a Custom Attribute via the REST API

You can also use our REST API to set user attributes. To do so refer to the User API documentation.

Custom Attribute Length

Custom attribute keys and values have a maximum length of 255 characters. Longer strings will be truncated to 255 characters.

Reserved Key Prefixes

Custom attribute keys may not start with the following reserved prefixes:

  • appboy

Reserved Keys

The following reserved keys may not be used as custom attribute keys:

  • first_name
  • last_name
  • email
  • bio
  • gender
  • dob
  • country
  • home_city
  • email_subscribe
  • phone
  • facebook
  • twitter
  • image_url
  • push_subscribe

Implementation Example

See CustomLoggingDialog.java in the Droidboy sample app.

Full class information can be found in the javadocs.

Setting Up User Subscriptions

To set up a subscription for your users (either email or push), call the functions setEmailNotificationSubscriptionType() or setPushNotificationSubscriptionType(), respectively. Both of these functions take the enum type ‘NotificationSubscriptionType’ as arguments. This type has three different states:

Subscription Status Definition
OPTED_IN Subscribed, and explicitly opted in
SUBSCRIBED Subscribed, but not explicitly opted in
UNSUBSCRIBED Unsubscribed and/or explicitly opted out

Note: No explicit opt-in is required by Android to send users push notifications. When a user is registered for push, they are set to SUBSCRIBED rather than OPTED_IN by default. For more information on implementing subscriptions and explicit opt-ins, visit the topic on Appboy Academy.

Sample Code

Setting Email Subscriptions
Appboy.getInstance(YOUR_ACTIVITY.this).getCurrentUser().setEmailNotificationSubscriptionType(
  "NotificationSubscriptionType"
);
Setting Push Notification Subscription
Appboy.getInstance(YOUR_ACTIVITY.this).getCurrentUser().setPushNotificationSubscriptionType(
  "NotificationSubscriptionType"
);

Logging Purchases

Record in-app purchases so that you can track your revenue over time and across revenue sources, as well as segment your users by their lifetime value.

Appboy supports purchases in multiple currencies. Purchases that you report in a currency other than USD will be shown in the dashboard in USD based on the exchange rate at the date they were reported.

Before implementation, be sure to review examples of the segmentation options afforded by Custom Events vs. Custom Attributes vs Purchase Events in our Analytics Overview.

Tracking Purchases & Revenue

Time Estimate: 3-5 Minutes

To use this feature, add this method call after a successful purchase in your app:

Appboy.getInstance(YOUR_ACTIVITY.this).logPurchase(
   String productId,
   String currencyCode,
   BigDecimal price,
   int quantity
);

See the Javadoc for more information.

Note: If you pass in a value of 10 USD, and a quantity of 3 then that will log to the user’s profile as 3 purchases of 10 dollars for a total of 30 dollars. Quantities must be less than or equal to 100. Values of purchases can be negative.

Adding Properties

You can add metadata about purchases by passing an Appboy Properties object with your purchase information.

Properties are defined as key-value pairs. Keys are String objects and values can be String, int, float, boolean, or Date objects.

AppboyProperties purchaseProperties = new AppboyProperties();
purchaseProperties.addProperty("key", "value");
Appboy.getInstance(YOUR_ACTIVITY.this).logPurchase(..., purchaseProperties);

See the Javadoc for more information.

Reserved Keys

The following keys are RESERVED and CANNOT be used as Purchase Properties:

  • time
  • product_id
  • quantity
  • event_name
  • price
  • currency

REST API

You can also use our REST API to record purchases. Refer to the User API documentation for details.

*Implementation Examples

See PreferencesActivity.java and MainFragment.java in the Droidboy sample app.

Social Data Tracking

Similar to the Appboy iOS SDK, the Appboy Android SDK does not automatically collect Facebook and Twitter data. However, it’s possible to add social media data to an Appboy user’s profile from the Android SDK as well:

  • Obtain social media data within your app via the Facebook SDK and Twitter APIs.
  • Initialize Facebook and Twitter User objects with social media data and pass them to Appboy.

Social Network Data Constructors

FacebookUser(
  String facebookId,
  String firstName,
  String lastName,
  String email,
  String bio,
  String cityName,
  // Gender is an Appboy enum.
  // Specify either Gender.MALE or Gender.FEMALE.
  Gender gender,
  Integer numberOfFriends,
  // Names of pages the user likes.
  Collection<String> likes,
  // mm/dd/yyyy format.
  String birthday
)
TwitterUser(
  Integer twitterUserId,
  String twitterHandle,
  String name,
  String description,
  Integer followerCount,
  Integer followingCount,
  Integer tweetCount,
  String profileImageUrl
)

To pass data retrieved from social networks to Appboy, you’ll create a new FacebookUser or TwitterUser and then pass them to the method AppboyUser.setFacebookData()/AppboyUser.setTwitterData(). For example:

FacebookUser facebookUser = new FacebookUser("100000", "FirstName", "LastName", "email@email.com", "bio", "City", Gender.MALE, 3, ,"04/13/1990");
AppboyUser.setFacebookData(facebookUser);

String imageUrl = "https://si0.twimg.com/profile_images/000/0000.jpeg";
TwitterUser twitterUser = new TwitterUser(100000, "handle", "Name", "description", 100, 50, 150, imageUrl);
AppboyUser.setTwitterData(twitterUser);

Location Tracking

Add at least one of the following the following permission to your AndroidManifest.xml file to declare your app’s intent to collect location data:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Or:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Note: With the release of Android M, Android switched from an install-time to a runtime permissions model. To enable location tracking on devices running M and above, the app must explicitly receive permission to use location from the user (Appboy will not do this). Once location permissions are obtained, Appboy will automatically begin tracking location on the next session start. Devices running earlier versions of Android only require location permissions to be declared in the AndroidManifest.xml. For more information, visit Android’s permission documentation.

Note: ACCESS_FINE_LOCATION includes GPS data in reporting user location while ACCESS_COARSE_LOCATION includes data from the most battery-efficient non-GPS provider available (e.g. the network). Coarse location location will likely be sufficient for the majority of location data use-cases; however, under the runtime permissions model, receiving location permission from the user implicitly authorizes the collection of fine location data. You can read more about the differences between these location permissions and how you ought to utilize them here.

Disabling Automatic Location Tracking

To disable automatic location tracking, set com_appboy_disable_automatic_location_collection to true in appboy.xml:

<bool name="com_appboy_disable_automatic_location_collection">true</bool>

Then you can manually log single location data points via the setLastKnownLocation() method on AppboyUser like this:

Appboy.getInstance(YOUR_ACTIVITY.this).getCurrentUser().setLastKnownLocation(LATITUDE_DOUBLE_VALUE, LONGITUDE_DOUBLE_VALUE, ALTITUDE_DOUBLE_VALUE, ACCURACY_DOUBLE_VALUE);

See here for an implementation example of the above in our Droidboy sample app and here in our Javadocs for more information on the setLastKnownLocation method.

Uninstall Tracking

Uninstall Tracking utilizes background push notifications with an Appboy flag in the payload. For more information, see our Uninstall Tracking page on Appboy Academy.

Implementing Uninstall Tracking

Step 1: Checking for Appboy Background Push

In most cases, implementing Uninstall Tracking involves no code changes, as it requires no response on the part of the app. However, if your app takes automatic actions on all launches (including background launches) or background pushes, you’ll have to consider whether to gate that activity if the app was launched from an uninstall tracking push. For example, if you have logic that calls your servers for new content upon every background push or application launch, you likely would not want Appboy’s uninstall tracking pushes triggering that because you would incur unnecessary network traffic. Furthermore, because we send uninstall push to all users at approximately the same time, not gating network calls on launch from uninstall push could introduce significant server load.

You should check your application for automatic actions in the following places and update your code to ignore Appboy’s uninstall tracking pushes:

  1. Background Push Handling. Upon receipt of a background push notification, Appboy will broadcast a APPBOY_PUSH_RECEIVED intent. If you have a broadcast receiver listening for push received intents from Appboy, it will be instantiated and receive the intent in its onReceive() method.
  2. Application Launches. If your application is stopped, receiving a background push will launch it in the background and its Application.onCreate() method will be called. If you have a custom Application.onCreate() implementation, you should defer automatic server calls and any other actions you would not want triggered by background push.

If you need to make a specific exception for Appboy’s uninstall tracking pushes, Appboy recommends that you should wait to turn on uninstall tracking until virtually all users are on a release which includes the exception. Older app versions may experience undesirable behavior without the exception when uninstall tracking is turned on.

Version 1.8.2 of the SDK introduced the isUninstallTrackingPush() utility method to identify Appboy uninstall tracking pushes:

AppboyNotificationUtils.isUninstallTrackingPush(receivedIntent.getExtras())
Implementation Sample

The isUninstallTrackingPush() method is utilized in the AppboyBroadcastReceiver.java class in the Droidboy sample app. You can also view the method declaration within the AppboyNotificationUtils class.

Step 2: Test from the Dashboard

To ensure that your app does not take any unwanted automatic actions upon receiving an Appboy uninstall tracking push, send yourself a test push from the Dashboard.

  1. On the Campaigns page, create a Push Notification campaign.

    Push Notification

    Select Android Push as your platform.

  2. On the Additional Message Settings page, add the key appboy_uninstall_tracking with corresponding value true

    Key/Value Pair

  3. Use the Preview Message page to send yourself a test uninstall tracking push.

    Test User

  4. Check that your app does not take any unwanted automatic actions upon receiving the push.

Step 4: Enable Uninstall Tracking

Follow the instructions for enabling Uninstall Tracking on Appboy Academy.

Customer Feedback

The Appboy feedback form allows users to submit feedback about your app that is immediately sent to your company’s dashboard.

Time Estimate: 10 Minutes

Android ActivityFeed+FeedBack

In Android, the news feed and feedback form are implemented as Fragments that are available in the Appboy Android UI project. View Google’s documentation on Fragments for information on how to add a Fragment to an Activity.

Note: The Android UI Fragments do not automatically track session analytics. To ensure that sessions are tracked correctly, you should call IAppboy.openSession() when your app is opened (learn more about tracking user sessions).

Appboy Feedback Form

The AppboyFeedbackFragment class creates a Feedback form and makes calls to the core Appboy library to send feedback to Appboy. The AppboyFeedbackFragment contains two buttons, “cancel” and “send”, which when pressed will call a FeedbackFinishedListener. You must set a FeedbackFinishedListener on your fragment to handle navigation when a user interacts with the form:

AppboyFeedbackFragment appboyFeedbackFragment = new AppboyFeedbackFragment();
appboyFeedbackFragment.setFeedbackFinishedListener(new AppboyFeedbackFragment.FeedbackFinishedListener() {

    @Override
    public void onFeedbackFinished(AppboyFeedbackFragment.FeedbackResult feedbackResult) {
        // Here you can take action on the feedbackResult
    }

    @Override
    public String beforeFeedbackSubmitted(String feedbackString) {
        return feedbackString;
    }
});

Manual Feedback Collection

Appboy has a method allows you to pass Feedback to Appboy from a form or field within your app. This is perfect for passing feedback from an existing UI element to Appboy. The method will return a boolean which indicates whether or not the feedback was queued for delivery.

Third Party Provider Integrations

Appboy has easy integrations with both Desk.com and Zendesk. So long as you are collecting feedback through our ready-made UI or manually using the submitFeedback method, you can pass that feedback through to either third party provider. This will afford you the benefit of having the entire user profile card available to the CSR handling the case, and allow you to segment based upon the number of feedback requests a user has submitted.

To take advantage of these integrations, please visit the “feedback” section within the “app settings” page

Implementation Example

See the DroidBoyActivity.java file in the Droidboy sample app.

Theming the Appboy Feedback UI

The Appboy UI elements (the feedback form and news feed) 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 res/values/style.xml file in the Appboy SDK distribution. They are completely open source and completely customizable to suit your application’s aesthetic.

  <style name="Appboy"/>
  <!-- Feedback -->
  <style name="Appboy.Feedback"/>
  <style name="Appboy.Feedback.Layout"/>
  <style name="Appboy.Feedback.NavigationBar">
    <item name="android:padding">4dp</item>
    <item name="android:background">@color/com_appboy_feedback_form_navigation_bar_background</item>
  </style>
  <style name="Appboy.Feedback.NavigationBarCancelButton">
    <item name="android:layout_marginRight">2dp</item>
    <item name="android:text">@string/com_appboy_feedback_form_cancel</item>
    <item name="android:textStyle">bold</item>
  </style>

Overriding Styles

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 of the attributes to be correctly set.

Correct Style Override

<style name="Appboy.Feed.List">
  <item name="android:background">@color/mint</item>
  <item name="android:cacheColorHint">@color/mint</item>
  <item name="android:divider">@android:color/transparent</item>
  <item name="android:dividerHeight">16.0dp</item>
  <item name="android:paddingLeft">12.5dp</item>
  <item name="android:paddingRight">5.0dp</item>
  <item name="android:scrollbarStyle">outsideInset</item>
</style>

Incorrect Style Override

<style name="Appboy.Feed.List">
  <item name="android:background">@color/mint</item>
  <item name="android:cacheColorHint">@color/mint</item>
</style>

Feedback Form Style Elements

Android Feedback

Advanced Use Cases

Deep Linking to the News Feed

To deep link to the Appboy News Feed from a push notification we suggest you check for a specific Key/Value pair to queue your application to launch the FeedFragmentActivity. For example, you could use a key/value pair such as “Open_News_Feed” = “True”. This Key/Value pair could be sent through the dashboard or via our messaging REST API as an extras property. Please see the example code below:

  @Override
  public void onReceive(Context context, Intent intent) {
    Intent activityIntent;
    if (intent.getExtras() != null && getBooleanExtra(intent.getExtras().getBundle("extra"), "Open_News_Feed")) {
      activityIntent = new Intent(context, com.yourapp.NewsFeedActivity.class);
    } else {
      activityIntent = new Intent(context, com.yourapp.MainActivity.class);
    }
    // Set appropriate Intent flags.
    activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    context.startActivity(activityIntent);
  }

  public boolean getBooleanExtra(Bundle extras, String key) {
    return extras != null && Boolean.parseBoolean(extras.getString(key));
  }

News Feed Key Value

Localization

Localization is supported within the Appboy Android SDK. In addition to English, Appboy supports 29 languages in our built-in SDK messages. These pertain to the default messages displayed in applications integrated with Appboy, such as places in the app that request feedback (“Please enter a feedback message”) or when there are connectivity issues (“Cannot establish network connection. Please try again later.”) See below for a full list of messages (strings). If the phone language is set to one of the supported languages, any of the Appboy default strings triggered within an integrated application will automatically appear in that language.

Languages Supported

  1. Arabic
  2. Burmese
  3. Chinese - Simplified
  4. Chinese - Traditional
  5. Danish
  6. Dutch
  7. Estonian
  8. Finnish
  9. French
  10. German
  11. Hindi
  12. Indonesian
  13. Italian
  14. Japanese
  15. Khmer
  16. Korean
  17. Lao
  18. Malay
  19. Norwegian
  20. Polish
  21. Portuguese - Brazil
  22. Portuguese - Portugal
  23. Russian
  24. Spanish - Latin America
  25. Spanish - Spain
  26. Swedish
  27. Tagalog
  28. Thai
  29. Vietnamese

List of Localized Strings

  • Free
  • Reporting an Issue?
  • Message
  • Email
  • An email address is required.
  • Cancel
  • Please enter a feedback message.
  • Empty Feedback Message
  • Feedback
  • Send
  • Invalid Email Address
  • Please enter a valid email address and try again.
  • We have no updates. Please check again later.
  • Connection Error
  • Cannot establish network connection. Please try again later.
  • Cannot establish network connection.
  • Please try again later.
  • Provide contact info from:
  • or
  • Done
  • Enable Facebook Connection
  • To re-enable Facebook, go to Settings > Facebook.
  • Enable Twitter Connection
  • To re-enable Twitter, go to Settings > Twitter.
  • OK
  • Hh: mm (hour:minute format)
  • $%.2f (price format)

For more information see the Android Localization Developer Docs.

Beacon Integration

Here we will walk through how to integrate specific kinds of beacons with Appboy to allow for segmentation and messaging.

Gimbal Beacons

Once you have your Gimbal Beacons set up and integrated into your app, you can log Custom Events for things like a visit starting or ending, or a beacon being sighted. You can also log properties for these events, like the Place name or the Dwell time.

In order to log a Custom Event when a user enters a place, input this code into the onVisitStart method:

Appboy.getInstance(MainActivity.this).logCustomEvent("Entered " + visit.getPlace());
Appboy.getInstance(getContext()).requestImmediateDataFlush();

The requestImmediateDataFlush ensures that your event will log even if the app is in the background, and the same process can be implemented for leaving a location. Please note that the Activity and Context that you are working in may change exactly how you integrate the logCustomEvent and requestImmediateDataFlush lines. Also note that the above will create and increment a unique custom event for each new place that the user enters. As such, if you anticipate creating more than 50 places we recommend you create one generic “Place Entered” custom event and include the place name as an event property.

Network Offline Mode

Network Offline Mode is an optional feature that pauses or resumes outbound network requests from the Appboy SDK at any point during runtime. Events are not lost during the offline state. See the full documentation here.

Example Usage

To enable network offline mode in the Appboy SDK, see the following example:

Appboy.setOutboundNetworkRequestsOffline(true);

Runtime Configuration

Runtime configuration is an optional way to configure your app at runtime in place of an appboy.xml. Use of both runtime configuration and appboy.xml configuration is still possible. Runtime configured values will always take precedence over the same value in the appboy.xml. If the Appboy SDK can find all values in the runtime configuration, then the appboy.xml is no longer needed and can be removed. See the full documentation here.

Example Usage

The configuration uses a builder object that is then built and passed to Appboy.configure(). The following example uses a subset of the runtime configuration options available, see the javadoc for a complete list of available configuration options.

AppboyConfig appboyConfig = new AppboyConfig.Builder()
        .setApiKey("api-key-here")
        .setGcmMessagingRegistrationEnabled(false)
        .setSessionTimeout(60)
        .setHandlePushDeepLinksAutomatically(true)
        .setGreatNetworkDataFlushInterval(10)
        .build();
Appboy.configure(this, appboyConfig);

Another example can be found in our Hello Appboy sample app.

Android SDK v2.0.0 added the ability to set a single delegate object to custom handle all deep links opened by Appboy across in-app messages, push, and the news feed. Prior to v2.0.0, deep link delegates needed to be set separately for each channel.

Your delegate object should implement the IAppboyNavigator interface and be set using AppboyNavigator.setAppboyNavigator(). In most cases, the delegate should be set in your app’s Application.onCreate().

See CustomAppboyNavigator.java for an example implementation.

Note: You must also provide instructions for Appboy to navigate to your app’s (optional) news feed implementation. To use Appboy’s default handling, call AppboyNavigator.executeNewsFeedAction(context, uriAction);.

Note: Prior to v2.0.0, Appboy Navigator was only used when opening in-app messages.

Locations & Geofences

Geofences is currently in beta for select customers for access to the feature please create a support ticket or speak with your Appboy team. Learn more in Appboy ACademy.

To support geofences for Android:

  1. Your integration must support background push notifications.

  2. Appboy location collection must not be disabled.

Note: Appboy location collection is enabled by default. To verify your location collection status on Android, ensure that com_appboy_disable_location_collection is not set to true in your appboy.xml.

Time Estimate: 15 Minutes

Step 1: Update build.gradle

Add the Google Play Services Location package to your app level build.gradle:

dependencies {
  compile "com.google.android.gms:play-services-location:${PLAY_SERVICES_VERSION}"
}

See our sample application’s build.gradle for an example implementation.

Step 2: Update the Manifest

Add fine location permissions and boot permissions to your AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

Add the Appboy boot receiver to the application element of your AndroidManifest.xml:

<receiver android:name="com.appboy.AppboyBootReceiver">
  <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
  </intent-filter>
</receiver>

Add the Appboy Geofence service to the application element of your AndroidManifest.xml:

<service android:name="com.appboy.services.AppboyGeofenceService"/>

See our sample application’s AndroidManifest.xml for an example implementation.

Step 3: Obtain Location Permissions from the End User

For Android M and higher versions, you must request location permissions from the end user before gathering location information or registering geofences.

Add the following call to notify Appboy when a user grants the location permission to your app:

AppboyLocationService.requestInitialization(context);

This will cause the SDK to request geofences from Appboy’s servers and initialize geofence tracking.

See RuntimePermissionUtils.java in our sample application for an example implementation.

Note about Push to Sync

Note that Appboy syncs geofences to devices using background push. In most cases this will involve no code changes, as this feature requires no further integration on the part of the app.

However, note that if your application is stopped, receiving a background push will launch it in the background and its Application.onCreate() method will be called. If you have a custom Application.onCreate() implementation, you should defer automatic server calls and any other actions you would not want triggered by background push.

Sample Apps

Appboy’s SDKs each come with a sample application within the repository for your convenience. Each of these apps is fully buildable so you can test Appboy features alongside implementing them within your own applications. Testing behavior within your own application versus expected behavior and codepaths within the sample applications is an excellent way to debug any problems you may run into.

Building the Droidboy Test Application

Appboy’s test application within the Android SDK github repository is called Droidboy. Follow the instructions below to build a fully functional copy of it alongside your project.

  • Create a new “App Group” and note the Appboy API key.
  • Copy your GCM Project Number and Appboy API key into the appropriate places within /droidboy/res/values/appboy.xml (in between the tags for the strings named “com_appboy_push_gcm_sender_id” and “com_appboy_api_key”, respectively).
  • Copy your GCM API Key into your “App Settings” page.
  • To assemble the Droidboy APK run the following command within the SDK directory:

    ./gradlew assemble
    

    Note: Use gradlew.bat on Windows

  • To automatically install the Droidboy APK on a test device run the following command within the SDK directory:

    ./gradlew installDebug
    

Building the Hello Appboy Test Application

The Hello Appboy test application shows a minimal use case of the Appboy SDK, and additionally shows how to easily integrate the Appboy SDK into a gradle project.

  1. Copy your API key from your “App Settings” page into your appboy.xml file in the res/values folder. HelloAppboy

  2. To install the sample app to a device or emulator, run the following command within the SDK directory: ./gradlew installDebug

Note: If you don’t have your ANDROID_HOME variable properly set or don’t have a local.properties folder with a valid sdk.dir folder, this plugin will also install the base SDK for you. See the plugin repo for more information.

For more information on the Android SDK build system see the Github Repository readme.