diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderClient.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderClient.java index 820ccc4eb..72376ebaa 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderClient.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderClient.java @@ -628,11 +628,9 @@ public static void updateWithAdvertisingId(@NonNull String advertisingId) { } /** - * Set the AdvertisingId yourself. If set, SDK will not capture idfa automatically - * - * Call this method before initializing the RudderClient + * Set the AdvertisingId yourself. If set, SDK will not capture advertisingId automatically * - * @param advertisingId IDFA for the device + * @param advertisingId advertisingId for the device */ public static void putAdvertisingId(@NonNull String advertisingId) { if (RudderClient.getInstance() == null) { @@ -646,6 +644,14 @@ public static void putAdvertisingId(@NonNull String advertisingId) { RudderElementCache.cachedContext.updateWithAdvertisingId(advertisingId); } + /** + * Clears the AdvertisingId set manually. + */ + + public void clearAdvertisingId() { + RudderElementCache.cachedContext.clearAdvertisingId(); + } + /** * Set the push token for the device to be passed to the downstream destinations * diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderContext.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderContext.java index b134d421c..8d8053aed 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderContext.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderContext.java @@ -106,7 +106,7 @@ public class RudderContext { this.screenInfo = new RudderScreenInfo(application); this.userAgent = System.getProperty("http.agent"); - this.deviceInfo = new RudderDeviceInfo(advertisingId, deviceToken, collectDeviceId); + this.deviceInfo = new RudderDeviceInfo(advertisingId, deviceToken, collectDeviceId, preferenceManger); this.networkInfo = new RudderNetwork(application); this.osInfo = new RudderOSInfo(); this.libraryInfo = new RudderLibraryInfo(); @@ -199,6 +199,10 @@ void updateWithAdvertisingId(String advertisingId) { } } + void clearAdvertisingId() { + this.deviceInfo.clearAdvertisingId(); + } + void updateDeviceWithAdId() { if (isOnClassPath("com.google.android.gms.ads.identifier.AdvertisingIdClient")) { // This needs to be done each time since the settings may have been updated. @@ -248,7 +252,7 @@ private boolean getGooglePlayServicesAdvertisingID() throws Exception { if (TextUtils.isEmpty(this.deviceInfo.getAdvertisingId())) { // set the values if and only if the values are not set // if value exists, it must have been set by the developer. don't overwrite - this.deviceInfo.setAdvertisingId((String) advertisingInfo.getClass().getMethod("getId").invoke(advertisingInfo)); + this.deviceInfo.setAutoCollectedAdvertisingId((String) advertisingInfo.getClass().getMethod("getId").invoke(advertisingInfo)); this.deviceInfo.setAdTrackingEnabled(true); } @@ -273,7 +277,7 @@ private boolean getAmazonFireAdvertisingID() throws Exception { if (TextUtils.isEmpty(this.deviceInfo.getAdvertisingId())) { // set the values if and only if the values are not set // if value exists, it must have been set by the developer. don't overwrite - this.deviceInfo.setAdvertisingId(Settings.Secure.getString(contentResolver, "advertising_id")); + this.deviceInfo.setAutoCollectedAdvertisingId(Settings.Secure.getString(contentResolver, "advertising_id")); this.deviceInfo.setAdTrackingEnabled(true); } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderDeviceInfo.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderDeviceInfo.java index 6b55d7661..40531e6fc 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderDeviceInfo.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderDeviceInfo.java @@ -32,14 +32,25 @@ class RudderDeviceInfo { @SerializedName("advertisingId") private String advertisingId; - RudderDeviceInfo(String advertisingId, String token, boolean collectDeviceId) { + private transient RudderPreferenceManager preferenceManager; + + RudderDeviceInfo(String advertisingId, String token, boolean collectDeviceId, RudderPreferenceManager preferenceManager) { + + this.preferenceManager = preferenceManager; if (collectDeviceId) { this.deviceId = Utils.getDeviceId(RudderClient.getApplication()); } + + // update the advertisingId value in persistence, if user specifies one again + // if the user didn't pass any advertisingId, then try reading it from preferences if (advertisingId != null && !advertisingId.isEmpty()) { + preferenceManager.saveAdvertisingId(advertisingId); this.advertisingId = advertisingId; - this.adTrackingEnabled = true; + } else { + this.advertisingId = preferenceManager.getAdvertisingId(); } + this.adTrackingEnabled = (this.advertisingId != null); + if (token != null && !token.isEmpty()) { this.token = token; } @@ -60,6 +71,12 @@ void setAdTrackingEnabled(boolean enabled) { void setAdvertisingId(String advertisingId) { this.advertisingId = advertisingId; + this.adTrackingEnabled = true; + preferenceManager.saveAdvertisingId(advertisingId); + } + + void setAutoCollectedAdvertisingId(String advertisingId) { + this.advertisingId = advertisingId; } String getAdvertisingId() { @@ -69,4 +86,10 @@ String getAdvertisingId() { boolean isAdTrackingEnabled() { return this.adTrackingEnabled; } + + void clearAdvertisingId() { + this.advertisingId = null; + this.adTrackingEnabled = false; + preferenceManager.clearAdvertisingId(); + } } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderElementCache.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderElementCache.java index caa61d543..d2fa5d7e2 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderElementCache.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderElementCache.java @@ -22,7 +22,8 @@ static void initiate(Application application, String anonymousId, String adverti if (cachedContext == null) { RudderLogger.logDebug("RudderElementCache: initiating RudderContext"); cachedContext = new RudderContext(application, anonymousId, advertisingId, deviceToken, isCollectDeviceId); - if (isAutoCollectAdvertId) { + // we will perform the auto collection of advertisingId only when the user didn't pass any advertisingId by calling the putAdvertisementId() + if (cachedContext.getAdvertisingId() == null && isAutoCollectAdvertId) { cachedContext.updateDeviceWithAdId(); } } diff --git a/core/src/main/java/com/rudderstack/android/sdk/core/RudderPreferenceManager.java b/core/src/main/java/com/rudderstack/android/sdk/core/RudderPreferenceManager.java index bda72ea20..41b119e95 100644 --- a/core/src/main/java/com/rudderstack/android/sdk/core/RudderPreferenceManager.java +++ b/core/src/main/java/com/rudderstack/android/sdk/core/RudderPreferenceManager.java @@ -29,6 +29,8 @@ class RudderPreferenceManager { private static final String RUDDER_PERIODIC_WORK_REQUEST_ID_KEY = "rl_periodic_work_request_key"; private static final String RUDDER_LAST_ACTIVE_TIMESTAMP_KEY = "rl_last_event_timestamp_key"; private static final String RUDDER_SESSION_ID_KEY = "rl_session_id_key"; + + private static final String RUDDER_ADVERTISING_ID_KEY = "rl_advertising_id_key"; private static final String RUDDER_AUTO_SESSION_TRACKING_STATUS_KEY = "rl_auto_session_tracking_status_key"; private static final String RUDDER_DMT_HEADER_KEY = "rl_dmt_header_key"; @@ -179,6 +181,19 @@ void clearSessionId() { preferences.edit().remove(RUDDER_SESSION_ID_KEY).apply(); } + void saveAdvertisingId(String advertisingId) { + preferences.edit().putString(RUDDER_ADVERTISING_ID_KEY, advertisingId).apply(); + } + + @Nullable + String getAdvertisingId() { + return preferences.getString(RUDDER_ADVERTISING_ID_KEY, null); + } + + void clearAdvertisingId() { + preferences.edit().remove(RUDDER_ADVERTISING_ID_KEY).apply(); + } + @Nullable Long getSessionId() { long sessionId = preferences.getLong(RUDDER_SESSION_ID_KEY, -1); diff --git a/sample-kotlin/build.gradle b/sample-kotlin/build.gradle index bcad85874..b85bdb0a7 100644 --- a/sample-kotlin/build.gradle +++ b/sample-kotlin/build.gradle @@ -90,6 +90,9 @@ dependencies { //work-manager implementation 'androidx.work:work-runtime:2.8.1' + // required for auto collection of advertisingId + implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1' + testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'