The Iterable Android SDK is a Java implementation of an Android client for Iterable, supporting Android API versions 15 and higher.
- Installation
- Setting up a push integration in Iterable
- Sample apps
- Using the SDK
- Optional setup
- Additional information
- License
- Want to contribute?
It's possible to install stable or beta versions of Iterable's Android SDK, as described below. You'll also need to handle Firebase push messages and tokens.
âš IMPORTANT
Versions 3.2.0 and higher of Iterable's Android SDK depend on the AndroidX support libraries. Migrate your app to use AndroidX before using version 3.2.0 or higher of the SDK.
Add the following dependencies to your application's build.gradle:
implementation 'com.iterable:iterableapi:3.2.2'implementation 'com.iterable:iterableapi-ui:3.2.2' // Optional, contains Inbox UI componentsimplementation 'com.google.firebase:firebase-messaging:X.X.X' // Min version 17.4.0
See Bintray for the latest version of the SDK.
âš IMPORTANT
Beta versions of this SDK are subject to Iterable's Beta Mobile SDK Terms of Service.
Beta versions of Iterable's Android SDK are published to JitPack instead of Maven. To find the latest beta version of Iterable's Android SDK, look at look at this JitPack page.
To install a beta version:
-
Add the JitPack repository to your build file. Add it in your root build.gradle at the end of repositories:
allprojects { repositories { ... maven { url 'https://jitpack.io' } } } -
Add dependencies for Iterable's Android SDK (this example selects version
3.2.0-beta1):implementation 'com.github.Iterable.iterable-android-sdk:iterableapi:3.2.0-beta1' implementation 'com.github.Iterable.iterable-android-sdk:iterableapi-ui:3.2.0-beta1'
Before integrating the SDK for push messaging, you will need to:
-
Set your application up to receive push notifications via Firebase.
-
Set up a Mobile App in Iterable and create a Firebase push integration in it. This allows Iterable to communicate on your behalf with Firebase Cloud Messaging.
For more details, read Iterable's Setting up Android Push Notifications guide.
This repository contains the following sample apps:
-
In the
onCreatemethod of theApplication, initialize the Iterable SDK:IterableConfig config = new IterableConfig.Builder() .build(); IterableApi.initialize(context, "<your-api-key>", config);
- The
apiKeyshould correspond to the API key of your project in Iterable. If you'd like, you can specify a differentapiKeydepending on whether you're building inDEBUGorPRODUCTION, and point the SDK to the relevant Iterable project. IterableConfigcontains various configuration options for the SDK. Please refer to the Javadoc comments in the class source code for more information on the available configuration options.
âš Don't call
IterableApi.initializefromActivity#onCreate; it is necessary for Iterable SDK to be initialized when the application is starting, to make sure everything is set up regardless of whether the app is launched to open an activity or is woken up in background as a result of an incoming push message.The SDK uses the app's package name by default when it is not specified (app's package name is also the default name for all new integrations created via Mobile Apps section in Iterable). If your push integration was created before August 2019, it may have a custom name that is different from the app's package name. In that case, specify it when initializing the SDK:
IterableConfig config = new IterableConfig.Builder() .setPushIntegrationName("<push integration name>") .build(); IterableApi.initialize(context, "<your-api-key>", config);
You can find the integration name in 'Push' section of the Mobile App:
- The
-
Once you know the email (Preferred) or userId of the user, call
setEmailorsetUserId- EMAIL:
IterableApi.getInstance().setEmail("email@example.com"); - USERID:
IterableApi.getInstance().setUserId("userId");
âš Don't specify both email and userId in the same session, as they will be treated as different users by the SDK. Only use one type of identifier, email or userId, to identify the user.
- EMAIL:
-
Register for remote notifications
Iterable SDK automatically registers the push token with Iterable whenever
setEmailorsetUserIdis called.âš This default behavior is the preferred way of handling token registrations.
If you want to trigger token registration manually, first disable automatic registration by calling
setAutoPushRegistration(false)onIterableConfig.Builderwhen initializing the SDK.Than call
registerForPushwhenever you want to register the token:IterableApi.getInstance().registerForPush();This will take care of retrieving the token and registering it with Iterable.
âš Device registration will fail if user email or userId is not set. If you're calling
setEmailorsetUserIdafter the app is launched (i.e. when the user logs in), make sure you callregisterForPush()again to register the device with the logged in user.
Congratulations! You can now send remote push notifications to your device from Iterable!
The SDK adds a FirebaseMessagingService to the app manifest automatically, so
you don't have to do any extra setup to handle incoming push messages.
If your application implements its own FirebaseMessagingService, make sure you
forward onMessageReceived and onNewToken calls to
IterableFirebaseMessagingService.handleMessageReceived and
IterableFirebaseMessagingService.handleTokenRefresh, respectively:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
IterableFirebaseMessagingService.handleMessageReceived(this, remoteMessage);
}
@Override
public void onNewToken(String s) {
IterableFirebaseMessagingService.handleTokenRefresh();
}
}Note that FirebaseInstanceIdService is deprecated and replaced with
onNewToken in recent versions of Firebase.
When a user logs out, you typically want to disable push notifications to that user/device. This can be accomplished by calling disablePush(). Please note that it will only attempt to disable the device if you have previously called registerForPush().
In order to re-enable push notifcations to that device, simply call registerForPush() as usual when the user logs back in.
Notifications are rendered with the app launcher icon by default. To specify a custom icon for notifications, add this line to AndroidManifest.xml:
<meta-data android:name="iterable_notification_icon" android:resource="@drawable/ic_notification_icon"/>where ic_notification_icon is the name of the notification icon.
Add this line to AndroidManifest.xml to specify the notification color:
<meta-data android:name="iterable_notification_color" android:value="#FFFFFF"/>where #FFFFFF can be replaced with a hex representation of a color of your choice. In stock Android, the notification icon and action buttons will be tinted with this color.
You can also use a color resource:
<meta-data android:name="iterable_notification_color" android:resource="@color/notification_color"/>Since Android 8.0, Android requires apps to specify a channel for every notification. Iterable uses one channel for all notification; to customize the name of this channel, add this to AndroidManifest.xml:
<meta-data android:name="iterable_notification_channel_name" android:value="Notifications"/>You can also use a string resource to localize the channel name:
<meta-data android:name="iterable_notification_channel_name" android:resource="@string/notification_channel_name"/>By default, when an in-app message arrives from the server, the SDK automatically shows it if the app is in the foreground. If an in-app message is already showing when the new message arrives, the new in-app message will be shown 30 seconds after the currently displayed in-app message closes (see how to change this default value below). Once an in-app message is shown, it will be "consumed" from the server queue and removed from the local queue as well. There is no need to write any code to get this default behavior.
An incoming in-app message triggers a call to the onNewInApp method of IterableConfig.inAppHandler (an object of type IterableInAppHandler). To override the default behavior, set inAppHandler in IterableConfig to a custom class that overrides the onNewInApp method. onNewInApp should return InAppResponse.SHOW to show the incoming in-app message or InAppResponse.SKIP to skip showing it.
class MyInAppHandler implements IterableInAppHandler {
@Override
public InAppResponse onNewInApp(IterableInAppMessage message) {
if (/* add conditions here */) {
return InAppResponse.SHOW;
} else {
return InAppResponse.SKIP;
}
}
}
// ...
IterableConfig config = new IterableConfig.Builder()
.setPushIntegrationName("myPushIntegration")
.setInAppHandler(new MyInAppHandler())
.build();
IterableApi.initialize(context, "<your-api-key>", config);The SDK keeps the local in-app message queue in sync by checking the server queue every time the app goes into foreground, and via silent push messages that arrive from Iterable servers to notify the app whenever a new in-app message is added to the queue.
To access the in-app message queue, call IterableApi.getInstance().getInAppManager().getMessages(). To show a message, call IterableApi.getInstance().getInAppManager().showMessage(message).
// Get the in-app messages list
IterableInAppManager inAppManager = IterableApi.getInstance().getInAppManager();
List<IterableInAppMessage> messages = inAppManager.getMessages();
// Show an in-app message
inAppManager.showMessage(message);
// Show an in-app message without consuming (not removing it from the queue)
inAppManager.showMessage(message, false, null);The SDK handles in-app message buttons and links as follows:
-
If the URL of the button or link uses the
action://URL scheme, the SDK passes the action toIterableConfig.customActionHandler.handleIterableCustomAction(). IfcustomActionHandler(anIterableCustomActionHandlerobject) has not been set, the action will not be handled.- For the time being, the SDK will treat
itbl://URLs the same way asaction://URLs. However, this behavior will eventually be deprecated (timeline TBD), so it's best to migrate to theaction://URL scheme as it's possible to do so.
- For the time being, the SDK will treat
-
The
iterable://URL scheme is reserved for action names predefined by the SDK. If the URL of the button or link uses aniterable://URL known to the SDK, it will be handled automatically and will not be passed to the custom action handler.- The SDK does not yet recognize any
iterable://actions, but may do so in the future.
- The SDK does not yet recognize any
-
The SDK passes all other URLs to
IterableConfig.urlHandler.handleIterableURL(). IfurlHandler(anIterableUrlHandlerobject) has not been set, or if it returnsfalsefor the provided URL, the URL will be opened by the system (using a web browser or other application, as applicable).
To customize the time delay between successive in-app messages, set inAppDisplayInterval on IterableConfig to an appropriate value in seconds. The default value is 30 seconds.
Apps using version 3.2.0 and later of this SDK can allow users to save in-app messages to an inbox. This inbox displays a list of saved in-app messages and allows users to read them at their convenience. The SDK provides a default user interface for the inbox, which can be customized to match your brand's styles.
To learn more about Mobile Inbox, how to customize it, and events related to its usage, read:
- In-App Messages and Mobile Inbox
- Sending In-App Messages
- Events for In-App Messages and Mobile Inbox
- Setting up Mobile Inbox on Android
- Customizing Mobile Inbox on Android
Push notifications and action buttons may have openUrl actions attached to them. When a URL is specified, the SDK first calls the urlHandler specified in your IterableConfig object. You can use this class to handle openUrl actions the same way as you handle normal deep links. If the handler is not set or returns NO, the SDK will open a browser with that URL.
// MyApplication.java
@Override
public void onCreate() {
super.onCreate();
...
IterableConfig config = new IterableConfig.Builder()
.setUrlHandler(this)
.build();
IterableApi.initialize(context, "YOUR API KEY", config);
}
@Override
public boolean handleIterableURL(Uri uri, IterableActionContext actionContext) {
// Assuming you have a DeeplinkHandler class that handles all deep link URLs and navigates to the right place in the app
return DeeplinkHandler.handle(this, uri);
}For App Links to work with link rewriting in emails, you need to set up an assetlinks.json file in the Iterable project. For more information, read Setting up Android App Links.
If you already have a urlHandler (see Handling links from push notifications), the same handler can be used for email deep links by calling handleAppLink in the activity that handles all app links in your app:
// MainActivity.java
@Override
public void onCreate() {
super.onCreate();
...
handleIntent(getIntent());
}
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent != null) {
handleIntent(intent);
}
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() != null) {
IterableApi.handleAppLink(intent.getDataString());
// Overwrite the intent to make sure we don't open the deep link
// again when the user opens our app later from the task manager
setIntent(new Intent(Intent.ACTION_MAIN));
}
}Alternatively, call getAndTrackDeeplink along with a callback to handle the original deep link URL. You can use this method for any incoming URLs, as it will execute the callback without changing the URL for non-Iterable URLs.
IterableApi.getAndTrackDeeplink(uri, new IterableHelper.IterableActionHandler() {
@Override
public void execute(String result) {
Log.d("HandleDeeplink", "Redirected to: "+ result);
// Handle the original deep link URL here
}
});Deferred deep linking allows a user who does not have a specific app installed to:
- Click on a deep link that would normally open content in that app.
- Install the app from the App Store.
- Open the app and immediately see the content referenced by the link.
As the name implies, the deep link is deferred until the app has been installed.
After tapping a deep link in an email from an Iterable campaign, users without the associated app will be directed to Play Store to install it. If the app uses the Iterable SDK and has deferred deep linking enabled, the content associated with the deep link will load on first launch.
Set checkForDeferredDeeplink to true on IterableConfig when initializing the SDK to enable deferred deep linking for Iterable SDK. Make sure a urlHandler is also set up to handle deep links to open the right content within your app on first launch (see above for details).
-
In-app messages:
spawnInAppNotification-
spawnInAppNotificationis no longer needed and will fail to compile. The SDK now displays in-app messages automatically. For more information, see In-app messages. -
There is no need to poll the server for new messages.
-
-
In-app messages: handling manually
-
To control when in-app messages display (rather than displaying them automatically), set
IterableConfig.inAppHandler(anIterableInAppHandlerobject). From itsonNewInAppmethod, returnInAppResponse.SKIP. -
To get the queue of available in-app messages, call
IterableApi.getInstance().getInAppManager().getMessages(). Then, callIterableApi.getInstance().getInAppManager().showMessage(message)to show a specific message. -
For more details, see In-app messages.
-
-
In-app messages: custom actions
-
This version of the SDK reserves the
iterable://URL scheme for Iterable-defined actions handled by the SDK and theaction://URL scheme for custom actions handled by the mobile application's custom action handler. For more details, see Handling in-app message buttons and links. -
If you are currently using the
itbl://URL scheme for custom actions, the SDK will still pass these actions to the custom action handler. However, support for this URL scheme will eventually be removed (timeline TBD), so it is best to move templates to theaction://URL scheme as it's possible to do so.
-
-
Consolidated deep link URL handling
- By default, the SDK handles deep links with the the URL handler
assigned to
IterableConfig. Follow the instructions in Deep linking to migrate any existing URL handling code to this new API.
- By default, the SDK handles deep links with the the URL handler
assigned to
The recommended migration path is to upgrade the existing Google Cloud project to Firebase, update the server token in the existing GCM push integration in Iterable with the new Firebase token, and update the Android app to support Firebase. If you keep using the same project for FCM and the same integration name, the old tokens will still be valid and won't require re-registration of existing devices.
If you're using a different project for FCM and have existing devices on a GCM project with a different sender ID, updating the app will generate new tokens for users, but the old tokens will still be valid. When migrating from one sender ID to another, specify legacyGCMSenderId in IterableConfig when initializing the SDK. This will disable old tokens to make sure users won't receive duplicate notifications.
For more information, take a look at Iterable's Mobile Developer Guides.
The MIT License
See LICENSE
This library is open source, and we will look at pull requests!
See CONTRIBUTING for more information.
