The Pulsate Android SDK is a bridge between your customers' mobile devices and the Pulsate server.
It's very easy to use, and takes about 5 minutes to install.

📘

Android API Support

PulsateSDK 4.6.0 supports Android API 28 - 34
PulsateSDK 4.6.0 supports Android API 28 - 35

1. Add Dependency

Make sure you are using latest version of Android Studio.

  1. Make sure your project uses "mavenCentral" and "maven commonsware" as a dependency repository (default on latest version of the Android Gradle plugin).
buildscript {
    repositories {
        mavenCentral()
        maven { url "https://s3.amazonaws.com/repo.commonsware.com" }
    }
}

allprojects {
    repositories {
        mavenCentral()
        maven { url "https://s3.amazonaws.com/repo.commonsware.com" }
    }
}
  1. Add implementation 'com.pulsatehq.sdk:PulsateSdk:version' to the dependencies of your project. Change version to the actual version of the SDK that you want to use. All versions can be found here - https://pulsate.readme.io/v2.8.2/reference/android-sdk-release-notes
dependencies {
    implementation 'com.pulsatehq.sdk:PulsateSdk:4.6.1'
}

📘

Updating the SDK

The newest version of the SDK can be found here - https://pulsate.readme.io/v2.8.2/reference/android-sdk-release-notes

To update to the newest version of the SDK all you need to do is update the version tag in "implementation 'com.pulsatehq.sdk:PulsateSdk:version'" to the newest version found in the link above. Example - "implementation 'com.pulsatehq.sdk:PulsateSdk:4.6.1'"

2. Configure Gradle

Set compileSdkVersion to 35, minSdkVersion to 28 and targetSdkVersion to 35. The SDK also uses Java 17 and View Binding in it's layouts so View Binding must be enabled.

android {
    compileSdkVersion 35

    defaultConfig {
        minSdkVersion 28
        targetSdkVersion 35
    }
    buildFeatures {
        viewBinding true
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_17.toString()
    }
        ...
}

Also please make sure to use one of the newer versions of the Android Gradle Plugin.

buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:8.7.2'
    }
}

❗️

Google Play Services

The SDK uses the following play-services libraries
implementation "com.google.android.gms:play-services-location:21.3.0"
implementation "com.google.android.gms:play-services-maps:19.0.0"
implementation 'com.google.maps.android:android-maps-utils:3.8.2'
Please use the same versions to prevent any bugs caused by version mismatches.

❗️

Firebase

For Firebase the SDK uses the firebase-bom.
implementation platform('com.google.firebase:firebase-bom:33.5.1')
implementation 'com.google.firebase:firebase-messaging'
implementation 'com.google.firebase:firebase-storage'
Please use the same BOM version to prevent any bugs caused by version mismatches.

3. Set Authorization Data - App ID, App Key

There are two ways to setup Authorization Data - App ID, App Key.
The first way is to set them up in your Android Manifest as meta-data. The second way is by calling the "setAuthorizationData" method directly from the Pulsate Manager class in Java.

To setup the Authorization Data in your Android Manifest as meta-data you need to add the following code:

<application>
...
<!-- You can either set the needed data here or you can use pulsateManager.setAuthorizationData to set it later-->
<meta-data 
    android:name="PulsateAppId"
    android:value="xxxxxxxxxxxxxxxxxxxxxxxx"/>
<meta-data 
    android:name="PulsateAppKey"
    android:value="xxxxxxxxxxxxxxxxxxxxxxxx"/>
</application>

"PulsateAppId" and "PulsateAppKey" are used to associate the Pulsate framework with your Pulsate application which was created using the Pulsate web panel.

"PulsateAppId" and "PulsateAppKey" can be found in your app settings screen. To find them log into the Pulsate web interface and click the CONFIGURE icon on the main menu, your ID and KEY will be displayed here.

If you do not want to set these keys in your Android Manifest, you can pass these keys using the Pulsate Manager in Java code instead.

val authData = PulsateAuthData("SDK_APP_ID", "SDK_APP_KEY")
val pulsateManager = PulsateFactory.getInstance(authData)
//OR
val authData = PulsateAuthData("SDK_APP_ID", "SDK_APP_KEY")
val pulsateManager = PulsateFactory.getInstance()
pulsateManager.setAuthorizationData(authData)

4. MultiDex

As the Android platform has continued to grow, so has the size of Android apps. When your application and the libraries it references reach a certain size, you encounter build errors that indicate your app has reached a limit of the Android app build architecture.

We recommend all our users to add the following code in their projects to fix this problem.
In your gradle file under "defaultConfig" add the following line:

defaultConfig {
    multiDexEnabled = true
    //Your defaultConfig code
}

Also in your gradle file under "dependencies" add:

dependencies {
    //Your dependencies
    implementation 'androidx.multidex:multidex:2.0.1'
}

The last thing to do is open your App class and add the following method:

override fun attachBaseContext(base: Context) {
    super.attachBaseContext(base)
    MultiDex.install(base)
}

Your app will now support MultiDexing.

5. Android Manifest Merger

This step is only required if you modify the Android Manifest Merger Strategy, by default the Pulsate SDK's Android Manifest will automatically merge with the App's Android Manifest.

The Android Manifest Merger Strategy can be set in your AndroidManifest.xml by setting the tools:node" flag for example _tools:node="replace". If you use _tools:node="replace"* or any other mode that might cause the manifests to not merge, you must add the code below to your Android Manifest.

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<uses-permission
    android:name="android.permission.BLUETOOTH"
    android:maxSdkVersion="30" />
<uses-permission
    android:name="android.permission.BLUETOOTH_ADMIN"
    android:maxSdkVersion="30" />
<uses-permission
    android:name="android.permission.BLUETOOTH_SCAN"
    android:usesPermissionFlags="neverForLocation"
    tools:targetApi="s" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

<application>
  <activity
      android:name=".internal.features.feed.PulsateInboxActivity"
      android:enabled="true"
      android:exported="true"
      android:theme="@style/PulsateInboxTheme" />
  
  <activity
      android:name=".internal.util.PulsateCallToActionActivity"
      android:enabled="true"
      android:exported="true"
      android:theme="@style/PulsateInboxTheme" />
  
  <activity
      android:name=".internal.features.fcm.helper.PulsateNotificationClickActivity"
      android:enabled="true"
      android:exported="true"
      android:theme="@style/PulsateInboxTheme" />
  
  <activity
      android:name=".internal.features.fcm.helper.PulsateNotificationClickButtonActivity"
      android:enabled="true"
      android:exported="true"
      android:theme="@style/PulsateInboxTheme" />

  <activity
      android:name="com.pulsatehq.internal.features.debug.ui.PulsateTestModeActivity"
      android:enabled="true"
      android:exported="true"
      android:theme="@style/PulsateInboxTheme" />

  <activity
      android:name="com.pulsatehq.internal.features.debug.ui.location.geofence.PulsateDebugGeofenceActivity"
      android:enabled="true"
      android:exported="true"
      android:label="Developer Geofence"
      android:theme="@style/PulsateInboxTheme" />

  <activity
      android:name="com.pulsatehq.internal.features.debug.ui.location.beacon.PulsateDebugBeaconActivity"
      android:enabled="true"
      android:exported="true"
      android:label="Developer Beacon"
      android:theme="@style/PulsateInboxTheme" />

  <provider
      android:name="com.pulsatehq.internal.PulsateProvider"
      android:authorities="${applicationId}.pulsate"
      android:enabled="true"
      android:exported="false"
      android:initOrder="-1"/>

  <receiver
      android:name="com.pulsatehq.internal.PulsateBootReceiver"
      android:enabled="true"
      android:exported="false">
    	<intent-filter>
          <category android:name="android.intent.category.DEFAULT" />
          <action android:name="android.intent.action.BOOT_COMPLETED" />
          <action android:name="android.intent.action.QUICKBOOT_POWERON" />
          <!-- For HTC devices -->
          <action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
    	</intent-filter>
  </receiver>

  <receiver
      android:name="com.pulsatehq.internal.features.location.geofence.client.PulsateLocationReceiver"
      android:enabled="true"
      android:exported="false" />
  
  <receiver
      android:name="com.pulsatehq.internal.features.location.geofence.PulsateGeofenceTransitionsReceiver"
      android:enabled="true"
      android:exported="false" />

  <receiver
      android:name="com.pulsatehq.internal.features.fcm.receiver.PulsateNotificationDismissReceiver"
      android:enabled="true"
      android:exported="false" />

  <receiver
      android:name="com.pulsatehq.internal.features.fcm.receiver.PulsateNotificationQuickReplyService"
      android:enabled="true"
      android:exported="false" />

  <service
      android:name="com.pulsatehq.internal.features.fcm.receiver.PulsateFirebaseMessagingService"
      android:enabled="true"
      android:exported="false"
      android:stopWithTask="false">
    	<intent-filter>
          <action android:name="com.google.firebase.MESSAGING_EVENT" />
    	</intent-filter>
  </service>
</application>