The Reteno Android SDK for Mobile Customer Engagement and Analytics solutions.
See the video manual on Android SDK setup:
Overview
Reteno
is a lightweight SDK for Android that helps mobile teams integrate Reteno into their mobile apps. The server-side library makes it easy to call the Reteno API
.
You can check the latest SDK version on this page.
The SDK supports
-
Native Android applications written in Java/Kotlin
-
Android 8.0 or later (minSdk = 26)
Getting Started with Reteno SDK for Android
- Add the mavenCentral repository in your project level
build.gradle
:
buildscript {
repositories {
mavenCentral()
}
...
}
- Add
reteno
andfirebase
dependencies in yourbuild.gradle
application level:
dependencies {
implementation 'com.reteno:fcm:(SDK_latest_version_here)'
...
implementation "com.google.firebase:firebase-messaging:23.1.0"
implementation "com.google.firebase:firebase-messaging-ktx:23.1.0"
}
Library | Description |
---|---|
com.reteno:fcm | FCM enables push notifications and all core functionality through SDK |
firebase:firebase-messaging | Firebase cloud messaging |
firebase:firebase-messaging-ktx | Firebase cloud messaging Kotlin extensions |
License :
Reteno Android SDK
is released under the MIT license. See LICENSE for details.
Setting Up SDK
Follow our setup guide to integrate the Reteno SDK with your app.
Step 1. Enable AndroidX and Jetifier in Your gradle.properties
File
gradle.properties
Fileandroid.useAndroidX=true
Step 2. Determine Compiler for Java Code
Add com.reteno:fcm
and firebase
dependencies in build.gradle
.
Note
Java 1.8 compiler is required. In
build.gradle
app level
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Note
If your app is running on Android 13 or later (which you should) make sure to handle Notification runtime permissions
Step 3. Declare a Notification Permission in Your Manifest
<manifest ...>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application ...>
...
</application>
</manifest>
Step 4. Initialize the Reteno SDK
Edit your custom Application
class and provider API Access-Key at SDK initialization.
Note
To set up SDK you need an SDK_ACCESS_KEY, visit Managing Mobile SDK Access Keys to get it.
Below is a sample code you can add to your application class, which gets you started with RetenoSDK
. You may need to create a new class that extends the Application
in this step. Don't forget to edit your manifest file to use the custom Application class. Also, make sure to provide the access-key in the constructor. You may store Reteno access key the way you wish based on your preferences:
package [com.YOUR_PACKAGE];
import android.app.Application
import com.reteno.core.Reteno
import com.reteno.core.RetenoApplication
import com.reteno.core.RetenoImpl
class CustomApplication: Application(), RetenoApplication {
private lateinit var retenoInstance: Reteno
override fun onCreate() {
super.onCreate()
retenoInstance = RetenoImpl(this, "your_access_key_here")
}
override fun getRetenoInstance(): Reteno {
return retenoInstance
}
}
package [com.YOUR_PACKAGE];
import android.app.Application;
import androidx.annotation.NonNull;
import com.reteno.core.Reteno;
import com.reteno.core.RetenoApplication;
import com.reteno.core.RetenoImpl;
public class CustomApplication extends Application implements RetenoApplication {
private Reteno retenoInstance;
@Override
public void onCreate() {
super.onCreate();
retenoInstance = new RetenoImpl(this, "your_access_key_here");
}
@NonNull
@Override
public Reteno getRetenoInstance() {
return retenoInstance;
}
}
Manifest.xml
<application
android:name=".CustomApplication"
...
>
...
</application>
Important
Initialization settings are crucial for correct SDK functioning.
Step 5. Use SDK via Reteno
Interface
Reteno
InterfaceDo not use RetenoImpl
directly, access Reteno SDK across your application via your app instance. E.g. in Activity:
val reteno = (application as CustomApplication).getRetenoInstance()
Reteno reteno = ((CustomApplication)getApplication()).getRetenoInstance();
Step 6. Handle Runtime Permissions.
Since Android 13 was released you have to make sure you are handling Notification runtime permissions
When user accepts permission, you have to call updatePushPermissionStatus()
function from Reteno interface to notify the Reteno SDK that user has granted the permission.
val requestPermissionLauncher = registerForActivityResult(RequestPermission()) { isGranted: Boolean ->
if (isGranted) {
(getApplicationContext() as RetenoApplication).getRetenoInstance().updatePushPermissionStatus()
Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "Permission not granted", Toast.LENGTH_SHORT).show()
}
}
private fun checkPermissions() {
if (ContextCompat.checkSelfPermission(this, permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) {
return
} else if (shouldShowRequestPermissionRationale(permission.POST_NOTIFICATIONS)) {
AlertDialog.Builder(this)
.setTitle("Notifications blocked")
.setMessage("Please allow receiving notifications from this app in your device settings")
.setNegativeButton("Cancel", null)
.setPositiveButton("Go to Settings") { dialog, which ->
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
val uri = Uri.fromParts("package", getPackageName(), null)
intent.data = uri
startActivity(intent)
}.show()
} else {
requestPermissionLauncher.launch(permission.POST_NOTIFICATIONS)
}
}
private final ActivityResultLauncher<String> requestPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
if (isGranted) {
((RetenoApplication) getApplicationContext()).getRetenoInstance().updatePushPermissionStatus();
Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Permission not granted", Toast.LENGTH_SHORT).show();
}
});
private void checkPermissions() {
if (ContextCompat.checkSelfPermission(this, POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) {
return;
} else if (shouldShowRequestPermissionRationale(POST_NOTIFICATIONS)) {
new AlertDialog.Builder(this)
.setTitle("Notifications blocked")
.setMessage("Please allow receiving notifications from this app in your device settings")
.setNegativeButton("Cancel", null)
.setPositiveButton("Go to Settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
})
.show();
} else {
requestPermissionLauncher.launch(POST_NOTIFICATIONS);
}
}
Please Check Optional Items Below
Now you are ready to run your app and send a marketing push notification to your application.
Run your app on a physical Android device to make sure it builds correctly.
Optional
If you use own FCM pushes along with Reteno.
If you use your custom FCM service extended from FirebaseMessagingService
don't extend it directly. Extend RetenoFirebaseMessagingService
instead and call super methods for onCreate
, onNewToken
, onMessageReceived
.
E.g.:
class CustomFcmService: RetenoFirebaseMessagingService() {
override fun onCreate() {
super.onCreate()
// Your code here
}
override fun onNewToken(token: String) {
super.onNewToken(token)
// Your code here
}
override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)
// Your code here
}
}
public class CustomFcmService extends RetenoFirebaseMessagingService {
@Override
public void onCreate() {
super.onCreate();
// Your code here
}
@Override
public void onNewToken(@NonNull String token) {
super.onNewToken(token);
// Your code here
}
@Override
public void onMessageReceived(@NonNull RemoteMessage message) {
super.onMessageReceived(message);
// Your code here
}
}
Optional
You may add your default icon and color for all Reteno notifications via AndroidManifest.xml
<meta-data
android:name="@string/notification_icon"
android:resource="@drawable/ic_notification" />
<meta-data
android:name="@string/notification_icon_color"
android:resource="@color/red_dark" />
Optional
Additionally, you can further configure the handling of Deeplinks, Custom Data, and/or Notification Events (Push Received, Notification Clicked).
To learn more, please visit the Android Push Handling page.
Using Reteno Config for Initialization
Optionally, you can provide RetenoConfig in the constructor to setup SDK on initialization
data class RetenoConfig(
val isPausedInAppMessages: Boolean,
val userIdProvider: DeviceIdProvider,
val lifecycleTrackingOptions: LifecycleTrackingOptions,
val accessKey: String
)
isPausedInAppMessages
- indicates paused/resumed state for in-app messagesuserIdProvider
- Provider that will return custom userId. In case if id provided with a delay from external source. For example, if you have your own system for user identification, you can setup provider here that will wait until provider is going to return first non-null value and will use it for current user identification.lifecycleTrackingOptions
- behavior of automatic app lifecycle event tracking, see Android Lifecycle Tracking to learn moreaccessKey
- your access key, can be provided directly in the SDK constructor or here. Key from config has higher priority. Two ways to provide access key maintained for backwards compatibility.