Android
Requirements
- The Swrve Android SDK supports Android 5.0 and later (API level 21 and above) but is able to handle older versions with an empty SDK that does nothing.
- OTT – Android TV is supported. For more information on the features and campaign types supported in each OTT platform, see the OTT landing page.
- Gradle is distributed with the SDK and used to build the SDK and its dependencies.
- Ensure you have the latest version of Android Studio.
- The App ID and API Key for your app. This information is available in Swrve on the Integration Settings screen (on the Settings menu, select Integration settings).
Install the SDK
Swrve has an open source SDK repository. There are two options for downloading the latest public Swrve Android SDK:
- Install the Android SDK libraries using Gradle from the Swrve repository on Jcenter.
- Download the SDK from the GitHub public repository.
Install using Gradle
To install the Android SDK library in your project, add the following code to your build.gradle
file.
Step 1: In the project build.gradle
, add the Swrve repository and the Google repository.
repositories { mavenCentral() maven { url 'https://maven.google.com' } }
Step 2: Choose a Swrve library to install, ensuring you include the latest SDK version number (for example, 11.1.1). If you plan to integrate push notifications, use the Firebase, Amazon, or Huawei flavored libraries. Otherwise, use the basic Android SDK.
Firebase – select if you plan to use push notifications with Swrve, or already use any Firebase services like Firebase Cloud Messaging or Analytics.
dependencies { implementation 'com.swrve.sdk.android:swrve-firebase:11.1.1' }
Amazon – select if you use Amazon Device Messaging (ADM).
dependencies { implementation 'com.swrve.sdk.android:swrve-amazon:11.1.1' }
Huawei – select if you use Huawei Push Service.
dependencies { implementation 'com.swrve.sdk.android:swrve-huawei:11.1.1' }
Basic – select only if you are not using Swrve push notifications, or any Firebase/Amazon/Huawei services.
dependencies { implementation 'com.swrve.sdk.android:swrve:11.1.1' }
Amazon SDK dependency
If you’re compiling the Amazon-flavored SDK for Android from source, it is necessary to also download the Amazon SDK from the Amazon Developer portal to get the ADM jar support file (amazon-device-messaging-1.1.0.jar). Add the ADM jar file to your project in the appropriate folder. If you are using the Swrve Gradle build configurations, the location is ./SwrveSDK/providedLibs/. The corresponding project build.gradle
files refer to the jar file using the “provided” directive that when combined with the Amazon flavor SDK, becomes amazonProvided as follows:
dependencies { amazonProvided files('providedLibs/amazon-device-messaging-1.1.0.jar') }
The providing directive tells the library or plugin to compile against the jar but not include the class implementations. They are simply stub implementations and will fail if actually executed. The runtimes exist on the Amazon device.
build.gradle
dependency section. This isn’t required for release.Initialize the SDK
To initialize the SDK, create an instance on your application level. Replace <app_id>
and <api_key>
with your app ID and API key.
Kotlin
class YourApplication : Application() { override fun onCreate() { super.onCreate() try { val config = SwrveConfig() // To use the EU stack, include this in your config. // config.selectedStack = SwrveStack.EU SwrveSDK.createInstance(this, <app_id>, "<api_key>", config) } catch (exp: IllegalArgumentException) { Log.e("SwrveDemo", "Could not initialize the Swrve SDK", exp) } } }
Java
public class YourApplication extends Application { @Override public void onCreate() { super.onCreate(); try { SwrveConfig config = new SwrveConfig(); // To use the EU stack, include this in your config. // config.setSelectedStack(SwrveStack.EU); SwrveSDK.createInstance(this, <app_id>, "<api_key>", config); } catch (IllegalArgumentException exp) { Log.e("SwrveDemo", "Could not initialize the Swrve SDK", exp); } } }
minSDKversion
The minSDKversion that the Swrve SDK supports is level 21. If your app supports below level 21, the Swrve SDK does not track or execute on those earlier versions, but operates as normal on level 21 and above. If your app supports API levels below 19, you need to override the Swrve library defaults. Include the following overrides in your AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.yourapp.package"> <uses-sdk tools:overrideLibrary="com.swrve.sdk, com.swrve.swrvesdkcommon"/
Manage how you track user behavior
Swrve provides the following APIs to help you manage how you track user activity across app sessions and multiple devices.
- Identify – Makes a call to Swrve to determine if the current user has an existing Swrve user ID, by checking to see if the external user ID they provide is already linked to a known user ID in Swrve.
- Stop tracking – Stops all tracking of the current user’s activity. After this call is made, the SDK runs silently in the background and does not track user activity again until you call the
identify
orstart
API. - Start – Resumes tracking user activity after you call the
stopTracking
API.
This section explains how to use these APIs to manage how you track anonymous users, known users (that is, a user logs in and the SDK identifies them based on an external user ID), and users for whom you want to stop tracking activity (for example, a user logs out). For more information on how to identify users and then track and target them safely across multiple devices, platforms, and channels, see Tracking your users with Swrve User Identity.
External user ID
The external user ID is a non-discoverable key that identifies your user across multiple channels and platforms. To ensure app security, Swrve does not accept email or other personally identifiable information (PIIs) as the external user ID and rejects them on the server side. Before you implement the Identify service, please consult with your CSM at support@swrve.com for some guidance on best practices to follow in your integration.
The external user ID should always be unique to each user. Using a shared external user ID across users may have adverse consequences on user segmentation, reporting, audiences, and QA device behavior.
Identify pre-existing users
Use the identify
API to find pre-existing user identities that an app has logged, either on a single device or multiple devices. To use the identify
API, initialize the Swrve SDK as normal in your application:
Kotlin
SwrveSDK.createInstance(application, <app_id>, "<api_key>", config);
Java
SwrveSDK.createInstance(application, <app_id>, "<api_key>", config);
Do not call
identify
from the Application class. At the relevant point, call the identify
API with your external user ID:Kotlin
SwrveSDK.identify("<external_user_id>", object : SwrveIdentityResponse { override fun onSuccess(status: String, swrveId: String) { // Success, continue with your logic } override fun onError(responseCode: Int, errorMessage: String) { // Error should be handled. } })
Java
SwrveSDK.identify("<external_user_id>", new SwrveIdentityResponse() { @Override public void onSuccess(String status, String swrveId) { // Success, continue with your logic } @Override public void onError(int responseCode, String errorMessage) { // Error should be handled. } });
If the call fails, the user’s activity is not linked to an existing user ID in Swrve’s backend system, which might affect reporting and audiences where the user is logging in on multiple devices. We recommend not queuing or sending events until the
identify
call completes.
Delay tracking activity until user is identified
By default, once the SDK initializes it automatically starts tracking user activity. If you use the identify
API on its own, when a user first installs the app, Swrve tracks any activity that takes place prior to calling the identify
API as anonymous. For subsequent sessions, it attributes activity to the last known user.
To delay tracking until you’ve identified the user, use the autoStartLastUser
configuration property. If you set autoStartLastUser
to false
, the SDK does not start tracking any activity until you identify the user. Use this option if you do not want to track any anonymous user activity.
Kotlin
// In the Application class val config = SwrveConfig() config.isAutoStartLastUser = false SwrveSDK.createInstance(this, <app_id>, "<api_key>", config) // Later at a certain point in your app - but not in the Application class SwrveSDK.identify("<external_user_id>", object : SwrveIdentityResponse { override fun onSuccess(status: String, swrveId: String) { // Success, continue with your logic } override fun onError(responseCode: Int, errorMessage: String) { // Error should be handled. } })
Java
// In the Application class SwrveConfig config = new SwrveConfig(); config.setAutoStartLastUser(false); SwrveSDK.createInstance(this, <app_id>, "<api_key>", config); // Later at a certain point in your app - but not in the Application class SwrveSDK.identify("<external_user_id>", new SwrveIdentityResponse() { @Override public void onSuccess(String status, String swrveId) { // Success, continue with your logic } @Override public void onError(int responseCode, String errorMessage) { // Error should be handled. } });
If you set the
autoStartLastUser
configuration property to false
, the SDK:
- Only tracks user activity once you call the
identify
API. - Does not automatically start tracking user activity if the app cannot call the
stopTracking
API for some reason (for example, if the user hard-closes the app before thestopTracking
API call is complete). - Does not display in-app message campaigns that are linked to a push notification.
- Attributes push notification engagement metrics to the last user the SDK was tracking.
To check if the SDK is started before calling regular APIs when autoStartLastUser
is false
, use the SwrveSDK.isStarted()
API.
Stop tracking user activity
As of Android SDK version 8.0.0, it is possible to stop the SDK from tracking user activity and logging events. To stop tracking the current user’s activity, call the stopTracking
API:
SwrveSDK.stopTracking()
After you call the stopTracking
API, the SDK:
- Disables most APIs and returns empty strings or null objects as defaults.
- Does not start tracking user behavior again until you call the
start
oridentify
API. - Continues to display push notifications, except those you restrict to display only for identified users. The SDK attributes engagement metrics to the last user the SDK was tracking.
- Does not display in-app message campaigns, including those that are linked to a push notification.
- Continues to process background app updates.
Resume tracking user activity
To resume tracking after you call the stopTracking
API, call the start
or identify
API:
SwrveSDK.start(activity)
If you call the start
API, by default the SDK resumes tracking against the last known user ID. If you don’t want to assume it’s the same user, call the identify
API.
Custom Swrve user ID
If your integration uses a custom Swrve user ID, there are additional steps you need to take to manage the SDK intitialization and user activity tracking. For more information, contact your CSM at support@swrve.com.
Push notifications
Use Swrve’s push notification campaigns to send personalized messages to your app users while they’re outside of your app or to send silent background app updates. For more information, see Intro to push notifications. Push notifications are disabled by default. To enable push notifications, use either the Firebase, Amazon, or Huawei-flavored SDK.
Push notification permission request
With the release of Android 13, users must actively grant permission for an app to display notifications on their device. Android allows you to display the permission prompt a maximum of two times, therefore it’s important to carefully consider the context in which you trigger the request. Some best practices for improving notification opt-in rates are:
- Update your app’s target SDK version to Android 13 to give you more flexibility over when the permission dialog appears.
- Wait to show the notification permission prompt until users are more familiar with your app.
- Request the permission in context, so it’s clear to users what the notifications are used for and the benefits of opting in.
To configure the notification permission request:
Step 1: Set the targetSdkVersion
for the app in your build.gradle
file to at least API Level 33.
Step 2: Configure the pushNotificationPermissionEvents
API in SwrveNotificationConfig
with a list of special event names to trigger the prompt.
Step 3: When a user triggers one of the events, the permission prompt is displayed.
Using Swrve push notifications with other providers
For information about how to integrate Swrve push notifications with other providers, see the Multiple FCM Providers example in the Android SDK samples folder on GitHub.
Using only Swrve push notifications
If this is the first push notification integration for your app, complete the following steps.
Step 1: Make the following changes to your AndroidManifest.xml
to include the Firebase, Amazon, or Huawei configurations.
Firebase
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="${packageName}" android:versionCode="1" android:versionName="1.0" > <!-- Add this to your AndroidManifest.xml --> <uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- End of changes --> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <!-- Add this to your AndroidManifest.xml --> <service android:name="com.swrve.sdk.SwrveFirebaseMessagingService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> <!-- End of changes --> ... </application> </manifest>
Step 2: Add the following script dependency:
buildscript { // ... dependencies { // ... classpath 'com.google.gms:google-services:4.4.2' } }
Step 3: Add the following plugin to the build.gradle file of your app.
dependencies { // ... } // ADD THIS AT THE BOTTOM apply plugin: 'com.google.gms.google-services'
Step 4: Add the google-services.json from the Firebase Console to your project. For more information, see the Firebase help article, Download a configuration file.
Step 5: Provide your notification configuration to the SwrveConfig
and pass into SwrveSDK.createInstance
.
val config = SwrveConfig() val channel: NotificationChannel? = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { NotificationChannel( "123", "Devapp swrve default channel", NotificationManager.IMPORTANCE_DEFAULT ) } else { null } val notificationEvents = listOf("tutorial.complete", "subscribe") val notificationConfig = SwrveNotificationConfig.Builder(R.drawable.logo1, R.drawable.logo2, channel) .activityClass(MainActivity::class.java) .largeIconDrawableId(R.drawable.swrve_s_solid) .accentColorHex("#3949AB") .pushNotificationPermissionEvents(notificationEvents) .build() config.notificationConfig = notificationConfig SwrveSDK.createInstance(this, <app_id>, "<api_key>", config)
Amazon
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:amazon="http://schemas.amazon.com/apk/res/android" package="${packageName}" android:versionCode="1" android:versionName="1.0" > <!-- Add this to your AndroidManifest.xml --> <!-- ADM uses WAKE_LOCK to keep the processor from sleeping when a message is received. --> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="com.amazon.device.messaging.permission.RECEIVE" /> <permission android:name="${packageName}.permission.RECEIVE_ADM_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="${packageName}.permission.RECEIVE_ADM_MESSAGE" /> <!-- End of changes --> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <!-- Add this to your AndroidManifest.xml --> <amazon:enable-feature android:name="com.amazon.device.messaging" android:required="true"/> <service android:name="com.swrve.sdk.SwrveAdmHandlerJobService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="false" /> <service android:name="com.swrve.sdk.SwrveAdmIntentService" android:exported="false" /> <receiver android:name="com.swrve.sdk.SwrveAdmMessageReceiver" android:permission="com.amazon.device.messaging.permission.SEND" > <intent-filter> <action android:name="com.amazon.device.messaging.intent.REGISTRATION" /> <action android:name="com.amazon.device.messaging.intent.RECEIVE" /> <category android:name="${packageName}" /> </intent-filter> </receiver> <!-- End of changes --> </application> </manifest>
Notes:
- For more information, see Amazon Device Messaging.
- Add the the Amazon namespace xmlns:amazon=”http://schemas.amazon.com/apk/res/android to your
<manifest>
.
Step 2: If you do your own application signing, you need to add the Amazon api_key.txt to the assets folder of your project. To get this key from Amazon, follow this guide on Obtaining Amazon Device Messaging Credentials.
Step 3: Provide your notification configuration to the SwrveConfig
and pass into SwrveSDK.createInstance
.
val config = SwrveConfig() var channel: NotificationChannel? = null if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { channel = NotificationChannel( "123", "Devapp swrve default channel", NotificationManager.IMPORTANCE_DEFAULT ) val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager notificationManager?.createNotificationChannel(channel) } val notificationConfig = SwrveNotificationConfig.Builder(R.drawable.logo1, R.drawable.logo2, channel) .activityClass(MainActivity::class.java) .largeIconDrawableId(R.drawable.swrve_s_solid) .accentColorHex("#3949AB") .build() config.notificationConfig = notificationConfig SwrveSDK.createInstance(this, <app_id>, <api_key>, config)
Huawei
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:amazon="http://schemas.amazon.com/apk/res/android" package="${packageName}" android:versionCode="1" android:versionName="1.0" > <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <!-- Add this to your AndroidManifest.xml --> <service android:name="com.swrve.sdk.SwrveHmsMessageService" android:exported="false" > <intent-filter> <action android:name="com.huawei.push.action.MESSAGING_EVENT" /> </intent-filter> </service> <meta-data android:name="push_kit_auto_init_enabled" android:value="true" /> <!-- End of changes --> </application> </manifest>
Step 2: Add the following repository to buildscript in the root build.gradle:
buildscript { // ... repositories { // ... maven { url 'https://developer.huawei.com/repo/' } } }
Step 3: Add the following dependency to buildscript in the root build.gradle:
buildscript { // ... dependencies { // ... classpath 'com.huawei.agconnect:agcp:1.7.2.300' } }
Step 4: Add the following dependency to allprojects in the root build.gradle:
allprojects { // ... repositories { // ... maven { url 'https://developer.huawei.com/repo/' } } }
Step 5: Add the following plugin to the build.gradle file of your app:
dependencies { // ... } // ADD THIS AT THE BOTTOM apply plugin: 'com.huawei.agconnect'
Step 6: Add the agconnect-services.json from the Huawei Console to your project. For more information, see the Huawei help article, Download a configuration file.
Step 7: Provide your notification configuration to the SwrveConfig
and pass into SwrveSDK.createInstance
.
val config = SwrveConfig() var channel: NotificationChannel? = null if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { channel = NotificationChannel( "123", "Devapp swrve default channel", NotificationManager.IMPORTANCE_DEFAULT ) val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager notificationManager?.createNotificationChannel(channel) } val notificationConfig = SwrveNotificationConfig.Builder(R.drawable.logo1, R.drawable.logo2, channel) .activityClass(MainActivity::class.java) .largeIconDrawableId(R.drawable.swrve_s_solid) .accentColorHex("#3949AB") .build() config.notificationConfig = notificationConfig SwrveSDK.createInstance(this, <app_id>, <api_key>, config)
Configuring silent notifications
To enable silent push notifications in your app, add the new silent push listener in your Application’s onCreate activity:
Kotlin
SwrveSDK.createInstance(this, <app_id>, "<api_key>", config) SwrveSDK.setSilentPushListener(object : SwrveSilentPushListener { override fun onSilentPush(context: Context, payload: JSONObject) { // NOTE: Do not call the Swrve SDK from this context // NOTE: This is called directly from the push service in the background // Your code here } })
Java
SwrveSDK.createInstance(this, <app_id>, "<api_key>", config); SwrveSDK.setSilentPushListener(new SwrveSilentPushListener() { @Override public void onSilentPush(Context context, JSONObject payload) { // NOTE: Do not call the Swrve SDK from this context // NOTE: This is called directly from the push service in the background // Your code here } });
Note: This listener is executed from the push service.
Managing the Firebase service account key
To enable your app to send push notifications to Google Play devices, you require a Firebase Cloud Messaging service account key. For more information, see How do I manage the Android service account key for push notifications?
Enabling Amazon Device Messaging
To enable ADM in your Amazon app, log in to the Amazon Developer portal, go to Apps & Services > My App > Device Messaging and select Enable.
Managing the Amazon Client ID and Client Secret
To enable your app to send push notifications to Amazon devices, you need the Client ID and Client Secret for your app. For information on how to get these credentials, see Obtaining Amazon Device Messaging Credentials. Generally, you enter the Client Id and Client Secret on the Swrve dashboard when configuring the Integration Settings as part of the Swrve onboarding process. You can edit the settings on this screen later on if required.
Step 1: On the Settings menu, select Integration Settings.
Step 2: Under the Push Notifications section, in the Amazon Device Messaging Service section, enter your Client Id and Client secret.
Step 3: Test the server key by sending a test push notification to one of your QA devices. To send a test push notification:
- Select your QA device from the list of available devices.
- Select Send Test Push.
Managing the Huawei App ID and App Secret
To enable your app to send push notifications to Huawei devices, you need the App ID and App Secret for your app. For information on how to get these credentials, see the Huawei help article, Viewing App Information. Generally, you enter the App Id and App secret on the Swrve dashboard when configuring the Integration Settings as part of the Swrve onboarding process. You can edit the settings on this screen later on if required.
Step 1: On the Settings menu, select Integration Settings.
Step 2: Under the Push Notifications section, in the Huawei Push Mobile Service section, enter your App Id and App secret.
Step 3: Test the server key by sending a test push notification to one of your QA devices. To send a test push notification:
- Select your QA device from the list of available devices.
- Select Send Test Push.
Advanced push notification configuration
This section describes how to configure advanced options for Android SDK push notification integration.
Processing custom payloads
To execute code when a notification is opened, add a listener to you config as part of initialization in your Application class:
Kotlin
val config = SwrveConfig() config.notificationListener = object : SwrvePushNotificationListener { override fun onPushNotification(payload: JSONObject) { // CUSTOM CODE HERE } } SwrveSDK.createInstance(this, <app_id>, "<api_key>", config) ...
Java
SwrveConfig config = new SwrveConfig(); config.setNotificationListener(new SwrvePushNotificationListener() { @Override public void onPushNotification(JSONObject payload) { // CUSTOM CODE HERE } }); SwrveSDK.createInstance(this, <app_id>, "<api_key>", config); ...
Using custom sounds
You can send push notifications with custom sounds. To do so, place your custom sound under res/raw
and set your sounds in the Swrve service. For more information about adding custom sounds in Swrve, see Intro to push notifications.
In-app messages
Swrve’s in-app message campaigns are available by default and require no additional integration steps. Use in-app messages to send personalized messages to your app users while they’re using your app. For more information, see Intro to in-app messages.
To test in-app messages in your app, you need to first create the campaign in Swrve. For more information, see Creating in-app messages.
In-app message deeplinks
When creating in-app messages in Swrve, you can configure message buttons to direct users to perform a custom action when clicked. For example, you might configure a button to direct the app user straight to the app store to provide a rating. Swrve’s default behavior for in-app messages is to treat custom actions as URIs. If your app has an existing custom URL scheme defined in your AndroidManifest.xml
, you can use this to deeplink in your app.
In-app message listener interactions
SwrveInAppMessageListener
receives callbacks for the following in-app message interactions:
- In-app message impression
- Custom button action
- Dismiss button action
- Copy to clipboard button action
The SwrveInAppMessageListener
may be called multiple times, such as for the initial impression and subsequent button actions like Dismiss, Custom, or CopyToClipboard. It is important to manage each case in the callback logic.
If a deeplink is present on a custom action or from a push message, the SwrveSDK will attempt to open the deeplink. To override this behavior, implement the SwrveDeepLinkListener
.
To receive added in-app message interactions, implement the SwrveInAppMessageListener
like this:
Kotlin
val config = SwrveConfig() val inAppConfigBuilder = SwrveInAppMessageConfig.Builder() .messageListener(object : SwrveInAppMessageListener { override fun onAction( context: Context, action: SwrveMessageAction, messageDetails: SwrveMessageDetails, selectedButton: SwrveMessageButtonDetails? ) { // See messageDetails object for campaign meta data available // See selectedButton object for button meta data available // Note: selectedButton will be null for SwrveImpression callback. when (action) { SwrveMessageAction.Impression -> { // process Impression callback } SwrveMessageAction.Custom -> { // process Custom callback // SwrveSDK will handle deep links internally. // To override this behavior, implement the SwrveDeeplinkListener } SwrveMessageAction.Dismiss -> { // process Dismiss callback } SwrveMessageAction.CopyToClipboard -> { // process CopyToClipboard callback } else -> { // Handle default case } } } }) config.inAppMessageConfig = inAppConfigBuilder.build() // Callback must be configured before SwrveSDK is instantiated SwrveSDK.createInstance(this, <app_id>, "<api_key>", config)
Java
SwrveConfig config = new SwrveConfig(); SwrveInAppMessageConfig.Builder inAppConfigBuilder = new SwrveInAppMessageConfig.Builder().messageListener(new SwrveInAppMessageListener() { @Override public void onAction(Context context, SwrveMessageAction action, SwrveMessageDetails messageDetails, SwrveMessageButtonDetails selectedButton) { // See messageDetails object for campaign meta data available // See selectedButton object for button meta data available // Note: selectedButton will be nil for SwrveImpression callback. switch (action) { case Impression: // process Impression callback break; case Custom: // process Custom callback // SwrveSDK will handle deep links internally. // to override this behavior you can implement the SwrveDeeplinkListener break; case Dismiss: // process Dismiss callback break; case CopyToClipboard: // process CopyToClipboard callback break; default: break; } } }); config.setInAppMessageConfig(inAppConfigBuilder.build()); // callback must be configured before SwrveSDK is instantiated SwrveSDK.createInstance(this, <app_id>, "<api_key>", config);
For in-app messages, deeplinks strings are handled as URLs. It is also possible to override this behavior of treating custom actions as URL deeplinks and integrate custom actions to direct users to a sale, website or other target when they click an in-app message. For example, to send Swrve events using custom actions, implement the
SwrveInAppMessageListener
like this:Kotlin
val config = SwrveConfig() val inAppConfigBuilder = SwrveInAppMessageConfig.Builder() .messageListener { context, action, messageDetails, selectedButton -> if (action == SwrveMessageAction.Custom) { val EVENT_DELAY_MILLISECONDS = 250L val timedService = Executors.newSingleThreadScheduledExecutor() timedService.schedule({ selectedButton?.actionString?.let { actionString -> val uri = Uri.parse(actionString) if (uri.scheme == "swrve") { uri.queryParameterNames.forEach { key -> val value = uri.getQueryParameter(key) if (key == "event") { SwrveSDK.event(value!!) } SwrveSDK.sendQueuedEvents() } } } }, EVENT_DELAY_MILLISECONDS, TimeUnit.MILLISECONDS) } } config.inAppMessageConfig = inAppConfigBuilder.build() // callback must be configured before SwrveSDK is instantiated SwrveSDK.createInstance(this, <app_id>, "<api_key>", config)
Java
SwrveConfig config = new SwrveConfig(); SwrveInAppMessageConfig.Builder inAppConfigBuilder = new SwrveInAppMessageConfig.Builder().messageListener(new SwrveInAppMessageListener() { @Override public void onAction(Context context, SwrveMessageAction action, SwrveMessageDetails messageDetails, SwrveMessageButtonDetails selectedButton) { if (action == Custom) { final int EVENT_DELAY_MILLISECONDS = 250; ScheduledExecutorService timedService = Executors.newSingleThreadScheduledExecutor(); timedService.schedule(new Runnable() { @Override public void run() { Uri uri = Uri.parse(selectedButton.getActionString()); if (uri.getScheme().equals("swrve")) { for( String key: uri.getQueryParameterNames() ) { final String value = uri.getQueryParameter(key); if(key.equals("event") ) { SwrveSDK.event(value); } SwrveSDK.sendQueuedEvents(); } } }, EVENT_DELAY_MILLISECONDS, TimeUnit.MILLISECONDS); } } } }); config.setInAppMessageConfig(inAppConfigBuilder.build()); // callback must be configured before SwrveSDK is instantiated SwrveSDK.createInstance(this, <app_id>, "<api_key>", config);
Request device permissions
Request certain device permissions from your users, such as post notifications, camera, or read contacts, using in-app message actions. Please contact your CSM at support@swrve.com if you require other permissions.
Permission requests via in-app message
To initiate a permission request using an in-app message action, you must include the permission in your AndroidManifest.xml with exception of the post notifications permission which is already included in the Swrve SDK AndroidManifest.xml.
In-app message text
If required, set the default color of the font, background, and text of your buttons and text boxes via the Swrve Config. In the absence of these settings, the SDK defaults to a transparent background, black text color, and default system font of the OS. Currently, this styling applies to all text that’s displayed.
Kotlin
val inAppConfigBuilder = SwrveInAppMessageConfig.Builder() .personalizedTextBackgroundColor(Color.RED) .personalizedTextForegroundColor(Color.YELLOW) .personalizedTextTypeface(Typeface.create("sans-serif-thin", Typeface.NORMAL)) .defaultBackgroundColor(ColorUtils.setAlphaComponent(Color.GREEN, 125)) config.inAppMessageConfig = inAppConfigBuilder.build()
Java
SwrveInAppMessageConfig.Builder inAppConfigBuilder = new SwrveInAppMessageConfig.Builder() .personalizedTextBackgroundColor(Color.RED) .personalizedTextForegroundColor(Color.YELLOW) .personalizedTextTypeface(Typeface.create("sans-serif-thin", Typeface.NORMAL)); .defaultBackgroundColor(ColorUtils.setAlphaComponent(Color.GREEN, 125)); config.setInAppMessageConfig(inAppConfigBuilder.build());
In-app message Stories
Customize the dismiss button for in-app Story messages according to your app’s requirements by creating a StateListDrawable
object. Assign the object to the SwrveInAppMessageConfig
when setting up the application, as shown below:
Kotlin
val defaultDrawable = ContextCompat.getDrawable(context, R.drawable.story_dismiss_default) val pressedDrawable = ContextCompat.getDrawable(context, R.drawable.story_dismiss_pressed) val focusedDrawable = pressedDrawable val stateListDrawable = StateListDrawable().apply { addState(intArrayOf(android.R.attr.state_pressed), pressedDrawable) addState(intArrayOf(android.R.attr.state_focused), focusedDrawable) addState(intArrayOf(), defaultDrawable) } val inAppConfig = SwrveInAppMessageConfig.Builder() .storyDismissButton(stateListDrawable) .build() val config = SwrveConfig().apply { inAppMessageConfig = inAppConfig } SwrveSDK.createInstance(this, <app_id>, "<app_key>", config)
Java
Drawable defaultDrawable = ContextCompat.getDrawable(context, R.drawable.story_dismiss_default); Drawable pressedDrawable = ContextCompat.getDrawable(context, R.drawable.story_dismiss_pressed); Drawable focusedDrawable = pressedDrawable; StateListDrawable stateListDrawable = new StateListDrawable(); stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, pressedDrawable); stateListDrawable.addState(new int[]{android.R.attr.state_focused}, focusedDrawable); stateListDrawable.addState(new int[]{}, defaultDrawable); SwrveInAppMessageConfig.Builder inAppConfigBuilder = new SwrveInAppMessageConfig.Builder().storyDismissButton(stateListDrawable); SwrveInAppMessageConfig inAppConfig = inAppConfigBuilder.build(); SwrveConfig config = new SwrveConfig(); config.setInAppMessageConfig(inAppConfig); SwrveSDK.createInstance(this, <app_id>, "<app_key>", config);
You can employ any drawable or resource image type supported by your Android API level. Specify at least one drawable item, functioning as the default for all button states.
Note: The color values assigned to a Story dismiss button in the dashboard are still applied. However, if your app utilizes custom images, it is advisable, when configuring a new Story campaign in the dashboard, to employ fully transparent colors for the dismiss button states.
Embedded campaigns
Swrve’s embedded campaigns give you complete control over how you deliver, handle, and display content on your app, while still letting you use our powerful audience targeting and event-triggering system to deliver the campaign. This opens up scenarios where you can deliver JSON to your application, targeted to specific users, triggered by specific situations, like a campaign, and then use this JSON to custom render a visual in your own application code. For more information see Embedded campaigns.
The Swrve SDK has direct access to the most recent version of the realtime user properties values in Swrve. When your app makes an embedded campaign callback, the contents of the personalizationProperties
argument in the embedded message include the realtime user properties retrieved during the process of triggering the campaign. To implement embedded campaigns in your integration, pass the SwrveEmbeddedMessageConfig
config object prior to initialization. For example:
Kotlin
val embeddedListener = SwrveEmbeddedListener { context, message, personalizationProperties, isControl -> // Perform your own message rendering println(message.data) // `data` is where your JSON resides } // Set your callback as part of your configuration val embeddedMessageConfig = SwrveEmbeddedMessageConfig.Builder() .embeddedListener(embeddedListener) .build() config.embeddedMessageConfig = embeddedMessageConfig // Callback must be configured before SwrveSDK is instantiated SwrveSDK.createInstance(this, <app_id>, "<api_key>", config)
Java
SwrveEmbeddedListener embeddedListener = (context, message, personalizationProperties, isControl) -> { // perform your own message rendering System.out.println(message.getData()); //getData is where your JSON resides }; // set your callback as part of your configuration. SwrveEmbeddedMessageConfig embeddedMessageConfig = new SwrveEmbeddedMessageConfig.Builder() .embeddedListener(embeddedListener) .build(); config.setEmbeddedMessageConfig(embeddedMessageConfig); // callback must be configured before SwrveSDK is instantiated SwrveSDK.createInstance(this,<app_id> , "<api_key>", config);
To use Swrve’s tracking, holdout groups, and personalization, there are methods you can call within the
SwrveEmbeddedMessage
listener. Use these methods to send impression and click events for your own embedded campaigns and use Swrve’s targeting, segmentation, and goal tracking. For example:Kotlin
val embeddedListener = SwrveEmbeddedListener { context, message, personalizationProperties, isControl -> if (isControl) { // This campaign should not be shown to the user. Send an impression event for reporting. SwrveSDK.embeddedControlMessageImpressionEvent(message) } else { // Returns the message data with personalization resolved. It will be null if it couldn't resolve. val resolvedMessageData = SwrveSDK.getPersonalizedEmbeddedMessageData(message, personalizationProperties) // Continue with normal logic // If you want to track an impression event SwrveSDK.embeddedMessageWasShownToUser(message) // The message object returns a list of strings representing the button options. // In this example, we take the first button from the list and send a click event. val buttons = message.buttons if (!buttons.isNullOrEmpty() && buttons.size == 1) { val buttonName = buttons[0] SwrveSDK.embeddedMessageButtonWasPressed(message, buttonName) } } }
Java
SwrveEmbeddedListener embeddedListener = (context, message, personalizationProperties, isControl) -> { if (isControl) { // this campaign should not be shown to user, to help with reporting you should use the api below to send us an impression event SwrveSDK.embeddedControlMessageImpressionEvent(message); } else { // returns the message data with personalization resolved. It will be null if it could not resolve. String resolvedMessageData = SwrveSDK.getPersonalizedEmbeddedMessageData(message, personalizationProperties); // continue with normal logic // If you want to track an impression event SwrveSDK.embeddedMessageWasShownToUser(message); // The message object returns a list of strings representing the button options. // In this example we are taking out the first button from the list and sending a click event if (message.getButtons() != null && message.getButtons().size() = 1) { String buttonName = message.getButtons().get(0); SwrveSDK.embeddedMessageButtonWasPressed(message, buttonName); } } };
Sending events
The Swrve SDK automatically sends certain events and also enables you to track user behavior by sending custom events. (For a list of default Swrve events, see Segment and audience filters, Events.) In turn, you can use app-generated events to trigger in-app messages, while both app- and server-generated events help you define segments and perform in-depth analysis.
Custom events
To send a custom event, include the below example in a method where you want to send an event to Swrve.
SwrveSDK.event("custom.event_name")
Requirements for sending custom events:
- Do not send the same named event with different case. For example, if you send
tutorial.start
, then ensure you never sendTutorial.Start
. - Use a period (.) in your event names to organize their layout in the Swrve dashboard. Each ‘.’ creates a new branch in the Event name column of the Events report, and groups your events so they are easy to locate.
- Do not send more than 1000 unique named events.
- Do not add unique identifiers to event names. For example,
Tutorial.Start.ServerID-ABDCEFG
- Do not add timestamps to event names. For example,
Tutorial.Start.1454458885
- Do not add unique identifiers to event names. For example,
- Do not use the
swrve.*
orSwrve.*
namespace for your own events. This is reserved for Swrve use only. Custom event names beginning withSwrve.
are restricted and cannot be sent.
Event payloads
You can add and send an event payload with every event. This allows for more detailed reporting around events and funnels. Notes on associated payloads:
- The associated payload should be a dictionary of key/value pairs; it is restricted to string and integer keys and values.
- There is a maximum cardinality of 500 key-value pairs for this payload per event. This parameter is optional, but only the first 500 payloads are displayed in the dashboard. The data is still available in raw event logs and for audience filtering.
- If you want to use event payloads to target your campaign audiences, you can configure up to 10 custom events with a maximum of 20 payloads per event for audience filtering purposes. For more information, see Targeting your audience by event payloads.
Kotlin
val payload = mapOf( "key1" to "value1", "key2" to "value2" ) SwrveSDK.event("custom.event_name", payload)
Java
Map<String,String> payload = new HashMap<String, String>(); payload.put("key1", "value1"); payload.put("key2", "value2"); SwrveSDK.event("custom.event_name", payload);
For example, if you want to track when a user starts the tutorial experience, it might make sense to send an event named
tutorial.start
and add a payload time
that captures how much time it took the user to complete the tutorial.Kotlin
val payload = mapOf( "time" to "100", "step" to "5" ) SwrveSDK.event("tutorial.start", payload)
Java
Map<String,String> payload = new HashMap<String, String>(); payload.put("time", "100"); payload.put("step", "5"); SwrveSDK.event("tutorial.start", payload);
Custom user properties
The Swrve SDK sends certain user properties by default and also enables you to assign custom properties to update the user’s status. (For a full list of the default user properties, see Assigning user properties.) For example, you could create a custom user property called premium
, and then target non-premium users and premium users in your campaigns. When configuring custom properties for Android, the Swrve SDK only supports string values.
Example of group of user properties
Kotlin
val attributes = mapOf( "premium" to "true", "level" to "12", "balance" to "999" ) SwrveSDK.userUpdate(attributes)
Java
Map<String, String> attributes = new HashMap<String, String>(); attributes.put("premium", "true"); attributes.put("level", "12"); attributes.put("balance", "999"); SwrveSDK.userUpdate(attributes);
Example of single date-typed user property
Use the Date object to send a DateTime user property; for example, the current date at the time of a user purchase:
Kotlin
SwrveSDK.userUpdate("last_purchase", Date())
Java
SwrveSDK.userUpdate("last_purchase", new Date());
Virtual economy events
To ensure virtual currency events are not ignored by the server, make sure the currency name configured in your app matches exactly the Currency Name you enter in the App Currencies section on the App Settings screen (including case-sensitive). If there is any difference, or if you haven’t added the currency in Swrve, the server will ignore the event and return an error event called Swrve.error.invalid_currency
. Additionally, the ignored events are not included in your KPI reports. For more information, see Add your app. If your app has a virtual economy, send the purchase
event when users purchase in-app items with virtual currency.
Kotlin
val item = "some.item" val currency = "gold" val cost = 99 val quantity = 1 SwrveSDK.purchase(item, currency, cost, quantity)
Java
String item = "some.item"; String currency = "gold"; int cost = 99; int quantity = 1; SwrveSDK.purchase(item, currency, cost, quantity);
Send the
currency given
event when you give users virtual currency. Examples include initial currency balances, retention bonuses and level-complete rewards.Kotlin
val givenCurrency = "gold" val givenAmount = 99.0 SwrveSDK.currencyGiven(givenCurrency, givenAmount)
Java
String givenCurrency = "gold"; double givenAmount = 99; SwrveSDK.currencyGiven(givenCurrency, givenAmount);
In-app purchase events and validation
If your app has in-app purchases (IAPs), send the IAP
event when a user purchases something with real money. This section details the IAP functions for unverified IAP events and for IAP events where the receipt can be verified. It also details how to enable IAP receipt validation for Google Play.
IAP functions
In the case of Android platforms (both native and Unity), Swrve does not automatically receive IAP receipts. For Swrve to verify IAPs, you must send an event for each purchase using the IAP API with the purchase receipt. For native Android, use Google Play services for this purpose. For Unity Android, you must use a Unity plugin to receive IAP receipts. IAP functions for unverified IAP events (that is, for any app store other than Google Play):
Kotlin
fun iap( quantity: Int, productId: String, productPrice: Double, currency: String ) fun iap( quantity: Int, productId: String, productPrice: Double, currency: String, rewards: SwrveIAPRewards )
Java
public void iap(int quantity, String productId, double productPrice, String currency); public void iap(int quantity, String productId, double productPrice, String currency, SwrveIAPRewards rewards);
IAP functions for IAP events where the receipt can be verified (for now, only Google Play is supported):
Kotlin
fun iapPlay( productId: String, productPrice: Double, currency: String, receipt: String, receiptSignature: String ) fun iapPlay( productId: String, productPrice: Double, currency: String, rewards: SwrveIAPRewards, receipt: String, receiptSignature: String )
Java
public void iapPlay(String productId, double productPrice, String currency, String receipt, String receiptSignature); public void iapPlay(String productId, double productPrice, String currency, SwrveIAPRewards rewards, String receipt, String receiptSignature);
Example: The following code is the initialization of the in-app purchase:
Kotlin
// Start an in-app purchase for the product with purchaseProductId try { val buyIntentBundle = mService.getBuyIntent( 3, packageName, purchaseProductId, "inapp", "extra" ) val pendingIntent = buyIntentBundle.getParcelable<PendingIntent>("BUY_INTENT") startIntentSenderForResult( pendingIntent.intentSender, purchaseRequestCode, Intent(), 0, 0, 0 ) } catch (e: RemoteException) { e.printStackTrace() } catch (e: SendIntentException) { e.printStackTrace() }
Java
// start an in-app purchase for the product with purchaseProductId try { Bundle buyIntentBundle = mService.getBuyIntent(3, getPackageName(), purchaseProductId, "inapp", "extra"); PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT"); startIntentSenderForResult(pendingIntent.getIntentSender(), purchaseRequestCode, new Intent(), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0)); } catch (RemoteException e) { e.printStackTrace(); } catch (SendIntentException e) { e.printStackTrace(); }
The following code is the callback function (executed when the purchase has been made):
Kotlin
// Callback on purchase finished override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == purchaseRequestCode) { val responseCode = data?.getIntExtra("RESPONSE_CODE", 0) ?: 0 // Get the receipt JSON string and the receipt signature val receipt = data?.getStringExtra("INAPP_PURCHASE_DATA") val receiptSignature = data?.getStringExtra("INAPP_DATA_SIGNATURE") // Make sure the purchase succeeded if (resultCode == RESULT_OK && responseCode == 0) { // Fill in the product details and the receipt data SwrveSDK.iapPlay( purchaseProductId, purchasePrice, purchaseCurrency, receipt, receiptSignature ) } } }
Java
@Override // callback on purchase finished protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == purchaseRequestCode) { int responseCode = data.getIntExtra("RESPONSE_CODE", 0); // get the receipt JSON string and the receipt signature String receipt = data.getStringExtra("INAPP_PURCHASE_DATA"); String receiptSignature = data.getStringExtra("INAPP_DATA_SIGNATURE"); // make sure the purchase succeeded if (resultCode == RESULT_OK && responseCode == 0) { // fill in the product details and the receipt data SwrveSDK.iapPlay(purchaseProductId, purchasePrice, purchaseCurrency, receipt, receiptSignature); } } }
It is also possible to create a
SwrveIAPRewards
object containing all the in-app currency and bundle items purchased (if the purchase contained other in-app items):Kotlin
val purchaseRewards = SwrveIAPRewards() purchaseRewards.addCurrency(virtualCurrency, 200) purchaseRewards.addItem(inAppItem, 1)
Java
SwrveIAPRewards purchaseRewards = new SwrveIAPRewards(); purchaseRewards.addCurrency(virtualCurrency, 200); purchaseRewards.addItem(inAppItem, 1);
In this instance,
iapPlay
can be supplied with this object:
SwrveSDK.iapPlay(purchaseProductId, purchasePrice, purchaseCurrency, purchaseRewards, receipt, receiptSignature)
Enabling IAP receipt validation
To enable validation of Google Play IAP receipts, on the Integration Settings screen, in the IAP Validation section, in the Google Play Licensing Public Key field, you must enter and save the public key for licensing and in-app billing. This public key is used to verify digital signatures. Google signs data (the app itself for verifying that the app has been payed for or the in-app purchase receipt) and Swrve then uses the public key to verify every purchase before calculating your revenue KPIs. This ensures that your revenue figures are as accurate as possible (ignoring pirates and cheaters). You usually enter the public key into Swrve when configuring the Integration Settings screen as part of the Swrve onboarding process. You can edit the settings on this screen at any time, as required. On the Settings menu, select Integration Settings. To access your public key, access the Google Play Console and navigate to All applications > [Your app] > Development tools > Services and APIs. The public key is then displayed in the Your license key for this application section. For more information, see the Google Play In-App Billing documentation.
Verifying IAP receipt validation
Use the following events to monitor the success of IAP receipt validation:
swrve.valid_iap
– fired if receipt verification has been successful and the receipt is valid.swrve.invalid_iap
– fired if receipt verification has been successful and the receipt is invalid.
Resource A/B testing
Integrating Swrve’s resource A/B testing functionality enables you to use Swrve to test how users respond to changes to the native app content. For more information about resource A/B testing, see Intro to resource A/B testing. To get the latest version of a resource from Swrve using the Resource Manager, use the following:
Kotlin
// Get the SwrveResourceManager which holds all up-to-date attribute values val resourceManager = SwrveSDK.getResourceManager() // Then, whenever you need to use a resource, pull it from the resourceManager. // For example, use the following to set some welcome text in your app to the // current value of the attribute "welcome_text" of the resource "new_app_config" // defaulting to "Welcome!" when the attribute is unavailable welcomeScreen.setMessageText( resourceManager.getAttributeAsString("new_app_config", "welcome_text", "Welcome!") )
Java
// Get the SwrveResourceManager which holds all up-to-date attribute values SwrveResourceManager resourceManager = SwrveSDK.getResourceManager(); // Then, whenever you need to use a resource, pull it from the resourceManager. // For example, use the following to set some welcome text in your app to the // current value of the attribute "welcome_text" of the resource "new_app_config" // defaulting to "Welcome!" when attribute is unavailable welcomeScreen.setMessageText(resourceManager.getAttributeAsString("new_app_config", "welcome_text", "Welcome!"));
If you want to be notified whenever resources change, you can add a
callback
function as follows:Kotlin
SwrveSDK.setResourcesListener(object : SwrveResourcesListener { override fun onResourcesUpdated() { // Callback functionality } })
Java
SwrveSDK.setResourcesListener(new SwrveResourcesListener() { public void onResourcesUpdated() { // Callback functionality } });
Testing your integration
After you’ve completed the above, the next step is to test the integration. For more information, see Testing your integration.
Upgrade instructions
If you’re moving from an earlier version of the Android SDK to the current version, see the Android SDK upgrade guide for upgrade instructions.
SDK samples
For a general demo of the Swrve Android SDK, see the Swrve Android SDK samples on GitHub.