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

The SDK supports Android API 23 - 32

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/docs/android-sdk-release-notes
dependencies {
    implementation 'com.pulsatehq.sdk:PulsateSdk:3.8.1'
}

📘

Updating the SDK

The newest version of the SDK can be found here - https://pulsate.readme.io/v2.8/docs/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:3.8.1'"

2. Configure Gradle

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

android {
                compileSdkVersion 32

        defaultConfig {
                minSdkVersion 23
                targetSdkVersion 32
        }
        buildFeatures {
            viewBinding true
            }
        compileOptions {
                        sourceCompatibility JavaVersion.VERSION_1_8
                        targetCompatibility JavaVersion.VERSION_1_8
            }
        ...
}

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

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

❗️

Google Play Services

The SDK uses the following play-services libraries
play-services-location:19.0.1
play-services-maps:18.0.2
Please use the same versions to prevent any bugs caused by version mismatches.

❗️

Firebase

The SDK uses the following firebase libraries
firebase-core:21.0.0
firebase-messaging:23.0.5
firebase-storage:20.0.1
Please use the same versions to prevent any bugs caused by version mismatches.

❗️

Android Support Libraries - AndroidX

With the release of version 3.0.0 Pulsate now uses AndroidX. Please make sure that your App also uses AndroidX.

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.

23802380

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.

AuthorizationData authData = new AuthorizationData("SDK_APP_ID", "SDK_APP_KEY");
IPulsateManager pulsateManager = PulsateFactory.getInstance(authData);

//OR
AuthorizationData authData = new AuthorizationData("SDK_APP_ID", "SDK_APP_KEY");
IPulsateManager 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
protected void attachBaseContext(Context base) {
    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.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.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

<application>
    <activity
    android:name=".internal.messaging.inbox.PulsateInboxActivity"
    android:enabled="true"
    android:exported="true"
    android:label="Feed"
    android:screenOrientation="portrait"
    android:theme="@style/PulsateInboxTheme" />

    <activity
    android:name=".internal.util.PulsateCallToActionActivity"
    android:enabled="true"
    android:exported="false"
    android:screenOrientation="portrait"
    android:theme="@style/PulsateInboxTheme" />
    
    <activity
        android:name=".internal.messaging.fcm.helper.PulsateNotificationClickActivity"
    android:enabled="true"
    android:exported="false"
    android:screenOrientation="portrait"
    android:theme="@style/PulsateInboxTheme" />
    
  <activity
        android:name=".internal.messaging.fcm.helper.PulsateNotificationClickButtonActivity"
    android:enabled="true"
    android:exported="false"
    android:screenOrientation="portrait"
    android:theme="@style/PulsateInboxTheme" />

    <activity
    android:name=".internal.debug.ui.PulsateTestModeActivity"
    android:enabled="true"
    android:exported="false"
    android:screenOrientation="portrait"
    android:theme="@style/PulsateInboxTheme" />

    <activity
    android:name=".internal.debug.location.geofence.PulsateDebugGeofenceActivity"
    android:enabled="true"
    android:exported="false"
    android:label="Developer Geofence"
    android:screenOrientation="portrait"
    android:theme="@style/PulsateInboxTheme" />

    <activity
    android:name=".internal.debug.location.beacon.PulsateDebugBeaconActivity"
    android:enabled="true"
    android:exported="false"
    android:label="Developer Beacon"
    android:screenOrientation="portrait"
    android:theme="@style/PulsateInboxTheme" />

    <meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="AIzaSyBMerFFVHXU-YO0FWjwwJh53knAXDPuoLU" />
    
    <provider
    android:name=".internal.PulsateInitProvider"
    android:authorities="${applicationId}.pulsate"
    android:enabled="true"
    android:exported="false" />
    
    <receiver
    android:name=".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=".internal.location.beacon.PulsateSendBeaconBroadcastReceiver"
    android:enabled="true"
    android:exported="false">
    <intent-filter>
        <action android:name="com.pulsatehq.internal.broadcast.BEACON_EVENT" />
    </intent-filter>    
    </receiver> 

    <receiver
    android:name=".internal.location.geofence.PulsateSendGeofenceBroadcastReceiver"
    android:enabled="true"
    android:exported="false">
    <intent-filter>
        <action android:name="com.pulsatehq.internal.broadcast.GEOFENCE_EVENT" />
    </intent-filter>
  </receiver>   
    
    <receiver
    android:name=".internal.events.PulsateSyncEventsBroadcastReceiver"
    android:enabled="true"
    android:exported="false">
    <intent-filter>
        <action android:name="com.pulsatehq.internal.broadcast.SYNC_EVENTS" />
    </intent-filter>    
    </receiver> 
    
    <receiver
    android:name=".internal.session.PulsateEndSessionBroadcastReceiver"
    android:enabled="true"
    android:exported="false">
    <intent-filter>
        <action android:name="com.pulsatehq.internal.broadcast.END_SESSION" />
    </intent-filter>    
    </receiver> 
    
    <receiver
        android:name=".internal.location.geofence.PulsateGeofenceTransitionsReceiver"
    android:enabled="true"
    android:exported="false"
    android:permission="pulsate.permission.GEOFENCE_TRANSITION" />
  
    <receiver
        android:name=".internal.messaging.fcm.receiver.PulsateNotificationDismissReceiver"
    android:enabled="true"
    android:exported="false" />

    <service
        android:name=".internal.messaging.fcm.receiver.PulsateNotificationQuickReplyService"
    android:enabled="true"
    android:exported="false" />
  
    <service
    android:name=".internal.messaging.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>