diff --git a/OmetriaSDK/build.gradle.kts b/OmetriaSDK/build.gradle.kts
index 5eb9e97..f7232b3 100644
--- a/OmetriaSDK/build.gradle.kts
+++ b/OmetriaSDK/build.gradle.kts
@@ -1,4 +1,4 @@
-val versionName = "1.6.1"
+val versionName = "1.6.2"
plugins {
id("com.android.library")
diff --git a/OmetriaSDK/src/main/AndroidManifest.xml b/OmetriaSDK/src/main/AndroidManifest.xml
index 960021d..f5ebb42 100644
--- a/OmetriaSDK/src/main/AndroidManifest.xml
+++ b/OmetriaSDK/src/main/AndroidManifest.xml
@@ -8,5 +8,17 @@
android:usesCleartextTraffic="true"
tools:targetApi="m">
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OmetriaSDK/src/main/java/com/android/ometriasdk/core/LocalCache.kt b/OmetriaSDK/src/main/java/com/android/ometriasdk/core/LocalCache.kt
index 04d67dc..0a128ef 100644
--- a/OmetriaSDK/src/main/java/com/android/ometriasdk/core/LocalCache.kt
+++ b/OmetriaSDK/src/main/java/com/android/ometriasdk/core/LocalCache.kt
@@ -20,6 +20,7 @@ private const val ARE_NOTIFICATIONS_ENABLED_KEY = "ARE_NOTIFICATIONS_ENABLED_KEY
private const val IS_FIRST_PERMISSION_UPDATE_EVENT_KEY = "IS_FIRST_PERMISSION_UPDATE_EVENT_KEY"
private const val JSON_ARRAY = "[]"
private const val SDK_VERSION_RN_KEY = "SDK_VERSION_RN_KEY"
+private const val API_TOKEN_KEY = "API_TOKEN_KEY"
internal class LocalCache(private val context: Context) {
@@ -165,4 +166,12 @@ internal class LocalCache(private val context: Context) {
fun getSdkVersionRN(): String? {
return localCacheEncryptedPreferences.getString(SDK_VERSION_RN_KEY, null)
}
+
+ fun saveApiToken(apiToken: String) {
+ localCacheEncryptedPreferences.edit().putString(API_TOKEN_KEY, apiToken).apply()
+ }
+
+ fun getApiToken(): String? {
+ return localCacheEncryptedPreferences.getString(API_TOKEN_KEY, null)
+ }
}
\ No newline at end of file
diff --git a/OmetriaSDK/src/main/java/com/android/ometriasdk/core/Ometria.kt b/OmetriaSDK/src/main/java/com/android/ometriasdk/core/Ometria.kt
index d7005f4..a64bbf2 100644
--- a/OmetriaSDK/src/main/java/com/android/ometriasdk/core/Ometria.kt
+++ b/OmetriaSDK/src/main/java/com/android/ometriasdk/core/Ometria.kt
@@ -2,6 +2,7 @@ package com.android.ometriasdk.core
import android.app.Application
import android.app.Notification.COLOR_DEFAULT
+import android.content.Context
import android.content.Intent
import android.net.Uri
import android.webkit.URLUtil
@@ -39,8 +40,10 @@ import com.android.ometriasdk.notification.NotificationHandler
import com.android.ometriasdk.notification.OMETRIA_CHANNEL_NAME
import com.android.ometriasdk.notification.OmetriaNotification
import com.android.ometriasdk.notification.OmetriaNotificationInteractionHandler
+import com.google.android.gms.tasks.OnCompleteListener
+import com.google.firebase.messaging.FirebaseMessaging
import com.google.firebase.messaging.RemoteMessage
-import java.util.*
+import java.util.UUID
/**
* The primary class that allows instantiating and integrating Ometria in your application
@@ -126,15 +129,49 @@ class Ometria private constructor() : OmetriaNotificationInteractionHandler {
}
application.registerActivityLifecycleCallbacks(it.activityLifecycleHelper)
}
+
+ if (it.localCache.getPushToken().isNullOrEmpty()) {
+ it.retrieveFirebaseToken()
+ }
+
+ it.localCache.saveApiToken(apiToken)
}
+ /**
+ * A lightweight initialization of Ometria, only for internal usage.
+ * Note: Not all SDK functions will be available after this initialization.
+ * @return An initialized Ometria instance object.
+ */
+ internal fun initializeForInternalUsage(context: Context) =
+ instance.also {
+ it.executor = OmetriaThreadPoolExecutor()
+ it.localCache = LocalCache(context)
+
+ val apiToken = it.localCache.getApiToken()
+ apiToken ?: return@also
+
+ it.ometriaConfig = OmetriaConfig(apiToken, context)
+ it.repository = Repository(
+ Client(ConnectionFactory(it.ometriaConfig)),
+ it.localCache,
+ it.executor
+ )
+ it.eventHandler = EventHandler(context, it.repository)
+ it.isInitialized = true
+ }
+
private fun clearOldInstanceIfNeeded() {
if (instance.isInitialized) {
- instance.flush()
- instance.clear()
+ clearOldInstance()
}
}
+ internal fun clearOldInstance() {
+ instance.flush()
+ instance.clear()
+ instance.isInitialized = false
+ }
+
/**
* Instances are safe to store, since they're immutable and always the same.
* @return An existing Ometria instance
@@ -149,6 +186,24 @@ class Ometria private constructor() : OmetriaNotificationInteractionHandler {
}
}
+ internal fun isReactNativeUsage(): Boolean = repository.getSdkVersionRN() != null
+
+ private fun retrieveFirebaseToken() {
+ FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
+ if (!task.isSuccessful) {
+ Logger.w(
+ Constants.Logger.EVENTS,
+ "Fetching FCM registration token failed."
+ )
+ return@OnCompleteListener
+ }
+
+ val token = task.result
+ Logger.d(Constants.Logger.PUSH_NOTIFICATIONS, "Token - $token")
+ instance.onNewToken(token)
+ })
+ }
+
private fun shouldGenerateInstallationId(): Boolean = repository.getInstallationId() == null
internal fun generateInstallationId() {
@@ -195,7 +250,9 @@ class Ometria private constructor() : OmetriaNotificationInteractionHandler {
}
fun onNewToken(token: String) {
- trackPushTokenRefreshedEvent(token)
+ if (localCache.getPushToken() != token) {
+ trackPushTokenRefreshedEvent(token)
+ }
}
private fun trackEvent(type: OmetriaEventType, data: Map? = null) {
@@ -272,7 +329,7 @@ class Ometria private constructor() : OmetriaNotificationInteractionHandler {
/**
* Track the current app user being deidentified.
- * An app user has deidentified themselves. This basically means: a user has logged out.*
+ * An app user has deidentified themselves. This basically means: a user has logged out.
*/
fun trackProfileDeidentifiedEvent() {
trackEvent(OmetriaEventType.PROFILE_DEIDENTIFIED)
diff --git a/OmetriaSDK/src/main/java/com/android/ometriasdk/core/OmetriaConfig.kt b/OmetriaSDK/src/main/java/com/android/ometriasdk/core/OmetriaConfig.kt
index d751486..a89986d 100644
--- a/OmetriaSDK/src/main/java/com/android/ometriasdk/core/OmetriaConfig.kt
+++ b/OmetriaSDK/src/main/java/com/android/ometriasdk/core/OmetriaConfig.kt
@@ -1,10 +1,10 @@
package com.android.ometriasdk.core
-import android.app.Application
+import android.content.Context
internal class OmetriaConfig(
var apiToken: String,
- var application: Application
+ var application: Context
) {
var enableDebugging: Boolean = false
}
\ No newline at end of file
diff --git a/OmetriaSDK/src/main/java/com/android/ometriasdk/core/event/EventExtensions.kt b/OmetriaSDK/src/main/java/com/android/ometriasdk/core/event/EventExtensions.kt
index 8475de7..f9b128a 100644
--- a/OmetriaSDK/src/main/java/com/android/ometriasdk/core/event/EventExtensions.kt
+++ b/OmetriaSDK/src/main/java/com/android/ometriasdk/core/event/EventExtensions.kt
@@ -4,7 +4,8 @@ import com.android.ometriasdk.core.Constants
import com.android.ometriasdk.core.network.model.OmetriaApiRequest
import java.text.DateFormat
import java.text.SimpleDateFormat
-import java.util.*
+import java.util.Calendar
+import java.util.Locale
/**
* @return A hashcode used to compare and group cached events in batches when performing flush.
diff --git a/OmetriaSDK/src/main/java/com/android/ometriasdk/core/event/EventHandler.kt b/OmetriaSDK/src/main/java/com/android/ometriasdk/core/event/EventHandler.kt
index 84bd8ff..c2a891e 100644
--- a/OmetriaSDK/src/main/java/com/android/ometriasdk/core/event/EventHandler.kt
+++ b/OmetriaSDK/src/main/java/com/android/ometriasdk/core/event/EventHandler.kt
@@ -12,7 +12,9 @@ import com.android.ometriasdk.core.Ometria
import com.android.ometriasdk.core.Repository
import java.text.DateFormat
import java.text.SimpleDateFormat
-import java.util.*
+import java.util.Calendar
+import java.util.Locale
+import java.util.UUID
import java.util.concurrent.TimeUnit
private const val FLUSH_LIMIT = 10
diff --git a/OmetriaSDK/src/main/java/com/android/ometriasdk/core/event/OmetriaEvent.kt b/OmetriaSDK/src/main/java/com/android/ometriasdk/core/event/OmetriaEvent.kt
index 1ab5d7f..82af64f 100644
--- a/OmetriaSDK/src/main/java/com/android/ometriasdk/core/event/OmetriaEvent.kt
+++ b/OmetriaSDK/src/main/java/com/android/ometriasdk/core/event/OmetriaEvent.kt
@@ -3,7 +3,7 @@ package com.android.ometriasdk.core.event
import android.os.Build
import com.android.ometriasdk.BuildConfig
import com.android.ometriasdk.core.Constants.Common.PLATFORM
-import java.util.*
+import java.util.Date
internal data class OmetriaEvent(
val eventId: String,
diff --git a/OmetriaSDK/src/main/java/com/android/ometriasdk/core/network/Client.kt b/OmetriaSDK/src/main/java/com/android/ometriasdk/core/network/Client.kt
index 05ecd6e..973bb69 100644
--- a/OmetriaSDK/src/main/java/com/android/ometriasdk/core/network/Client.kt
+++ b/OmetriaSDK/src/main/java/com/android/ometriasdk/core/network/Client.kt
@@ -5,7 +5,12 @@ import com.android.ometriasdk.core.Logger
import com.android.ometriasdk.core.network.model.OmetriaApiError
import com.android.ometriasdk.core.network.model.OmetriaApiRequest
import org.json.JSONException
-import java.io.*
+import java.io.BufferedReader
+import java.io.BufferedWriter
+import java.io.IOException
+import java.io.InputStreamReader
+import java.io.OutputStream
+import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.nio.charset.Charset
diff --git a/OmetriaSDK/src/main/java/com/android/ometriasdk/notification/OmetriaMessagingReceiver.kt b/OmetriaSDK/src/main/java/com/android/ometriasdk/notification/OmetriaMessagingReceiver.kt
new file mode 100644
index 0000000..580a82a
--- /dev/null
+++ b/OmetriaSDK/src/main/java/com/android/ometriasdk/notification/OmetriaMessagingReceiver.kt
@@ -0,0 +1,41 @@
+package com.android.ometriasdk.notification
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import com.android.ometriasdk.core.Ometria
+import com.android.ometriasdk.core.Ometria.Companion.clearOldInstance
+import com.android.ometriasdk.core.event.OmetriaEventType
+import com.android.ometriasdk.core.network.toOmetriaNotificationBody
+import com.google.firebase.messaging.RemoteMessage
+
+/**
+ * Used as Push notification interceptor.
+ * This will not replace Firebase's own BroadcastReceiver.
+ * The purpose of using this BroadcastReceive is to log [OmetriaEventType.NOTIFICATION_RECEIVED] event
+ * when the app is killed for React Native use-case.
+ */
+class OmetriaMessagingReceiver : BroadcastReceiver() {
+
+ override fun onReceive(context: Context?, intent: Intent?) {
+ val remoteMessage = RemoteMessage(intent?.extras)
+
+ try {
+ Ometria.instance()
+ } catch (e: IllegalStateException) {
+ context?.let {
+ Ometria.initializeForInternalUsage(context)
+
+ if (Ometria.instance().isReactNativeUsage()) {
+ val ometriaNotificationBody = remoteMessage.toOmetriaNotificationBody()
+ val ometriaNotificationContext = ometriaNotificationBody?.context
+
+ ometriaNotificationContext?.let {
+ Ometria.instance().trackNotificationReceivedEvent(it)
+ clearOldInstance()
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 0ef208f..bb63271 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ To install the library inside **Android Studio**, declare it as dependency in yo
```gradle
dependencies {
- implementation 'com.ometria:android-sdk:1.6.1'
+ implementation 'com.ometria:android-sdk:1.6.2'
}
```
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index a727356..da2ad3a 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -12,8 +12,8 @@ android {
applicationId = "com.android.sample"
minSdk = 23
targetSdk = 33
- versionCode = 9
- versionName = "1.0.9"
+ versionCode = 11
+ versionName = "1.2.0"
}
signingConfigs {
getByName("debug") {
diff --git a/app/src/main/java/com/android/sample/SampleApp.kt b/app/src/main/java/com/android/sample/SampleApp.kt
index 8613d90..4ec443b 100644
--- a/app/src/main/java/com/android/sample/SampleApp.kt
+++ b/app/src/main/java/com/android/sample/SampleApp.kt
@@ -15,6 +15,7 @@ import com.android.sample.presentation.MainActivity
import com.android.sample.presentation.OMETRIA_NOTIFICATION_STRING_EXTRA_KEY
class SampleApp : Application(), OmetriaNotificationInteractionHandler {
+
companion object {
lateinit var instance: SampleApp
}
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
index eeb21ee..adb2560 100644
--- a/app/src/main/res/layout/fragment_home.xml
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -55,7 +55,7 @@
android:layout_margin="16dp"
android:drawableEnd="@drawable/ic_arrow_right_alt_24px"
android:drawablePadding="5dp"
- android:text="Update API Toekn"
+ android:text="@string/update_api_token"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/detailsBTN" />
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 68d20d3..815a8b3 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -16,4 +16,5 @@
Email
Please enter your API token
Do it later
+ Update API Token
\ No newline at end of file