From 70b1a02d976ac324fb9b1551dfc7e22cf4c8d219 Mon Sep 17 00:00:00 2001 From: Henry Porter Date: Mon, 5 Dec 2022 14:22:04 +0000 Subject: [PATCH] Release v2.0.2 (#23) --- README.md | 7 +- qubit-sdk/build.gradle | 2 +- .../sdk/api/InitializationBuilder.java | 8 +- .../com/qubit/android/sdk/api/QubitSDK.java | 17 +++ .../com/qubit/android/sdk/internal/SDK.java | 13 +- .../eventtracker/EventRestModelCreator.java | 4 +- .../qubit/android/sdk/testapp/MainActivity.kt | 8 + .../src/main/res/layout/activity_main.xml | 142 ++++++++++-------- test-app/src/main/res/values/strings.xml | 2 + 9 files changed, 133 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index 9e5e7e1..abfe950 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ Installation of the QubitSDK, to provide event tracking and lookup. To make use | VERSION | UPDATES | |---|---| +| 2.0.2 | Added ability to set custom device identifier. | 2.0.1 | Resolve caching issue when campaigns are paused. | 2.0.0 | Major release, bringing support for Placement API. Upgrade to 2.* to use this feature. | 1.4.1 | Handle potential regression where /experiences endpoint does not return expected payload. @@ -20,7 +21,7 @@ In `build.gradle` of your Android application module (usually *$projectRoot/app/ ``` dependencies { - compile 'com.qubit:qubit-sdk-android:2.0.1' + compile 'com.qubit:qubit-sdk-android:2.0.2' } ``` @@ -51,6 +52,10 @@ Qubit's Android SDK needs the following permissions to communicate with the serv Note that you don't have to add these permissions to manifest of your application. +## Custom device identifier + +By default Qubit SDK uses system `Settings.Secure.ANDROID_ID` value as a device identifier. However it is possible to use custom value instead by calling `QubitSDK.restartWithCustomDeviceId("my-custom-device-id")`. Calling `restartWithCustomDeviceId(null)` restores default behaviour. Changing device identifier once SDK is already started restarts SDK causing clearing all the caches and resending startup events. + # Send events ## Sending events diff --git a/qubit-sdk/build.gradle b/qubit-sdk/build.gradle index b8e85ef..04889e8 100644 --- a/qubit-sdk/build.gradle +++ b/qubit-sdk/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' -version = '2.0.1' +version = '2.0.2' ext.retrofit_version = '2.4.0' diff --git a/qubit-sdk/src/main/java/com/qubit/android/sdk/api/InitializationBuilder.java b/qubit-sdk/src/main/java/com/qubit/android/sdk/api/InitializationBuilder.java index 34d0ee8..db5da9c 100644 --- a/qubit-sdk/src/main/java/com/qubit/android/sdk/api/InitializationBuilder.java +++ b/qubit-sdk/src/main/java/com/qubit/android/sdk/api/InitializationBuilder.java @@ -17,6 +17,7 @@ interface SdkConsumer { } private final SdkConsumer sdkConsumer; + private String deviceId; private Context appContext; private String trackingId; private QBLogLevel logLevel; @@ -25,6 +26,11 @@ interface SdkConsumer { this.sdkConsumer = sdkConsumer; } + public InitializationBuilder withCustomDeviceId(String deviceId) { + this.deviceId = deviceId; + return this; + } + /** * Set context of Android application. It can be {@link Application} itself * or result of {@link Context#getApplicationContext()}. @@ -74,7 +80,7 @@ public void start() { QBLogger.logLevel = logLevel; } - SDK sdk = new SDK(appContext, trackingId); + SDK sdk = new SDK(appContext, trackingId, deviceId); timings.addSplit("creation"); sdk.start(); timings.addSplit("starting"); diff --git a/qubit-sdk/src/main/java/com/qubit/android/sdk/api/QubitSDK.java b/qubit-sdk/src/main/java/com/qubit/android/sdk/api/QubitSDK.java index 2ab2f48..f533b4f 100644 --- a/qubit-sdk/src/main/java/com/qubit/android/sdk/api/QubitSDK.java +++ b/qubit-sdk/src/main/java/com/qubit/android/sdk/api/QubitSDK.java @@ -1,5 +1,7 @@ package com.qubit.android.sdk.api; +import android.content.Context; + import com.google.gson.JsonObject; import com.qubit.android.sdk.api.placement.Placement; import com.qubit.android.sdk.api.placement.PlacementMode; @@ -67,6 +69,21 @@ public static String getDeviceId() { return sdkSingleton.getDeviceId(); } + public static void restartWithCustomDeviceId(@Nullable String deviceId) { + if (sdkSingleton != null) { + // SDK is already initialized so it has to be restarted with a new deviceId + Context appContext = sdkSingleton.getAppContext(); + String trackingId = sdkSingleton.getTrackingId(); + + release(); + initialization() + .withCustomDeviceId(deviceId) + .inAppContext(appContext) + .withTrackingId(trackingId) + .start(); + } + } + public static String getTrackingId() { checkSdkInitialized(); return sdkSingleton.getTrackingId(); diff --git a/qubit-sdk/src/main/java/com/qubit/android/sdk/internal/SDK.java b/qubit-sdk/src/main/java/com/qubit/android/sdk/internal/SDK.java index d538482..c71e4da 100644 --- a/qubit-sdk/src/main/java/com/qubit/android/sdk/internal/SDK.java +++ b/qubit-sdk/src/main/java/com/qubit/android/sdk/internal/SDK.java @@ -50,10 +50,13 @@ import com.qubit.android.sdk.internal.session.repository.SessionRepository; import com.qubit.android.sdk.internal.session.repository.SessionRepositoryImpl; +import org.jetbrains.annotations.Nullable; + import java.util.concurrent.Future; public class SDK { + private final Context appContext; private final NetworkStateServiceImpl networkStateService; private final ConfigurationServiceImpl configurationService; private final LookupServiceImpl lookupService; @@ -66,7 +69,8 @@ public class SDK { private final ExperienceInteractor experienceInteractor; private final PlacementInteractor placementInteractor; - public SDK(Context appContext, String trackingId) { + public SDK(Context appContext, String trackingId, @Nullable String customDeviceId) { + this.appContext = appContext; this.networkStateService = new NetworkStateServiceImpl(appContext); ConfigurationRepository configurationRepository = new ConfigurationRepositoryImpl(appContext); @@ -75,8 +79,7 @@ public SDK(Context appContext, String trackingId) { new ConfigurationServiceImpl(networkStateService, configurationRepository, configurationConnectorBuilder); this.trackingId = trackingId; - this.deviceId = new SecureAndroidIdDeviceIdProvider(appContext).getDeviceId(); - + this.deviceId = (customDeviceId == null) ? new SecureAndroidIdDeviceIdProvider(appContext).getDeviceId() : customDeviceId; LookupRepository lookupRepository = new LookupRepositoryImpl(appContext); LookupConnectorBuilder lookupConnectorBuilder = new LookupConnectorBuilderImpl(trackingId, deviceId); @@ -154,6 +157,10 @@ public void stop() { networkStateService.stop(); } + public Context getAppContext() { + return appContext; + } + public EventTrackerImpl getEventTracker() { return eventTracker; } diff --git a/qubit-sdk/src/main/java/com/qubit/android/sdk/internal/eventtracker/EventRestModelCreator.java b/qubit-sdk/src/main/java/com/qubit/android/sdk/internal/eventtracker/EventRestModelCreator.java index 40e5c8b..f12c2cd 100644 --- a/qubit-sdk/src/main/java/com/qubit/android/sdk/internal/eventtracker/EventRestModelCreator.java +++ b/qubit-sdk/src/main/java/com/qubit/android/sdk/internal/eventtracker/EventRestModelCreator.java @@ -1,5 +1,7 @@ package com.qubit.android.sdk.internal.eventtracker; +import android.os.Build; + import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; @@ -23,7 +25,7 @@ class EventRestModelCreator { private final String trackingId; private final String deviceId; private final int sample; - private final String source = "Android@" + BuildConfig.VERSION_NAME; + private final String source = "Android@OS:" + Build.VERSION.SDK_INT + "@SDK:" + BuildConfig.VERSION_NAME; EventRestModelCreator(String trackingId, String deviceId) { this.trackingId = trackingId; diff --git a/test-app/src/main/java/com/qubit/android/sdk/testapp/MainActivity.kt b/test-app/src/main/java/com/qubit/android/sdk/testapp/MainActivity.kt index 11e013f..2904df4 100644 --- a/test-app/src/main/java/com/qubit/android/sdk/testapp/MainActivity.kt +++ b/test-app/src/main/java/com/qubit/android/sdk/testapp/MainActivity.kt @@ -94,6 +94,14 @@ class MainActivity : AppCompatActivity() { findViewById(R.id.placement_clickthrough).setOnClickListener { placement?.clickthrough() ?: Toast.makeText(this, "No placement loaded", Toast.LENGTH_LONG).show() } + + findViewById(R.id.device_id_custom).setOnClickListener { + QubitSDK.restartWithCustomDeviceId("custom") + } + + findViewById(R.id.device_id_reset).setOnClickListener { + QubitSDK.restartWithCustomDeviceId(null) + } } private fun getExperienceWithIds(list: List) { diff --git a/test-app/src/main/res/layout/activity_main.xml b/test-app/src/main/res/layout/activity_main.xml index 08bbba9..b28ec54 100644 --- a/test-app/src/main/res/layout/activity_main.xml +++ b/test-app/src/main/res/layout/activity_main.xml @@ -7,76 +7,92 @@ android:padding="16dp" tools:context="com.qubit.android.sdk.testapp.MainActivity"> -