Skip to content

Commit 38855d6

Browse files
committed
add consent required toggle
1 parent 9e002a5 commit 38855d6

7 files changed

Lines changed: 73 additions & 10 deletions

File tree

Examples/OneSignalDemoV2/app/src/main/java/com/onesignal/sdktest/application/MainApplication.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ class MainApplication : MultiDexApplication() {
6767
// Initialize tooltip helper
6868
TooltipHelper.init(this)
6969

70+
// Set consent required before init (must be set before initWithContext)
71+
OneSignal.consentRequired = SharedPreferenceUtil.getCachedConsentRequired(this)
72+
OneSignal.consentGiven = SharedPreferenceUtil.getUserPrivacyConsent(this)
73+
7074
// Initialize OneSignal on main thread (required)
7175
OneSignal.initWithContext(this, appId)
7276
LogManager.i(TAG, "OneSignal init completed")

Examples/OneSignalDemoV2/app/src/main/java/com/onesignal/sdktest/data/repository/OneSignalRepository.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,15 @@ class OneSignalRepository {
212212
}
213213

214214
// Privacy consent
215+
fun setConsentRequired(required: Boolean) {
216+
Log.d(TAG, "Setting consent required: $required")
217+
OneSignal.consentRequired = required
218+
}
219+
220+
fun getConsentRequired(): Boolean {
221+
return OneSignal.consentRequired
222+
}
223+
215224
fun setPrivacyConsent(granted: Boolean) {
216225
Log.d(TAG, "Setting privacy consent: $granted")
217226
OneSignal.consentGiven = granted

Examples/OneSignalDemoV2/app/src/main/java/com/onesignal/sdktest/ui/main/MainScreen.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ fun MainScreen(viewModel: MainViewModel) {
6767
val pushSubscriptionId by viewModel.pushSubscriptionId.observeAsState()
6868
val pushEnabled by viewModel.pushEnabled.observeAsState(false)
6969
val hasNotificationPermission by viewModel.hasNotificationPermission.observeAsState(false)
70+
val consentRequired by viewModel.consentRequired.observeAsState(false)
7071
val privacyConsentGiven by viewModel.privacyConsentGiven.observeAsState(false)
7172
val externalUserId by viewModel.externalUserId.observeAsState()
7273
val aliases by viewModel.aliases.observeAsState(emptyList())
@@ -166,6 +167,8 @@ fun MainScreen(viewModel: MainViewModel) {
166167
// === APP SECTION ===
167168
AppSection(
168169
appId = appId,
170+
consentRequired = consentRequired,
171+
onConsentRequiredChange = { viewModel.setConsentRequired(it) },
169172
privacyConsentGiven = privacyConsentGiven,
170173
onConsentChange = { viewModel.setPrivacyConsent(it) },
171174
externalUserId = externalUserId,

Examples/OneSignalDemoV2/app/src/main/java/com/onesignal/sdktest/ui/main/MainViewModel.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ class MainViewModel(application: Application) : AndroidViewModel(application), I
3838
private val _hasNotificationPermission = MutableLiveData<Boolean>()
3939
val hasNotificationPermission: LiveData<Boolean> = _hasNotificationPermission
4040

41+
// Consent Required
42+
private val _consentRequired = MutableLiveData<Boolean>()
43+
val consentRequired: LiveData<Boolean> = _consentRequired
44+
4145
// Privacy Consent
4246
private val _privacyConsentGiven = MutableLiveData<Boolean>()
4347
val privacyConsentGiven: LiveData<Boolean> = _privacyConsentGiven
@@ -119,6 +123,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application), I
119123
val context = getApplication<Application>()
120124

121125
_appId.value = SharedPreferenceUtil.getOneSignalAppId(context) ?: ""
126+
_consentRequired.value = repository.getConsentRequired()
122127
_privacyConsentGiven.value = repository.getPrivacyConsent()
123128
_inAppMessagesPaused.value = repository.isInAppMessagesPaused()
124129
_locationShared.value = repository.isLocationShared()
@@ -257,6 +262,14 @@ class MainViewModel(application: Application) : AndroidViewModel(application), I
257262
}
258263
}
259264

265+
// Consent required
266+
fun setConsentRequired(required: Boolean) {
267+
repository.setConsentRequired(required)
268+
SharedPreferenceUtil.cacheConsentRequired(getApplication(), required)
269+
_consentRequired.value = required
270+
showToast(if (required) "Consent required enabled" else "Consent required disabled")
271+
}
272+
260273
// Privacy consent
261274
fun setPrivacyConsent(granted: Boolean) {
262275
repository.setPrivacyConsent(granted)

Examples/OneSignalDemoV2/app/src/main/java/com/onesignal/sdktest/ui/main/Sections.kt

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ import com.onesignal.sdktest.ui.theme.WarningBackground
4747
@Composable
4848
fun AppSection(
4949
appId: String,
50+
consentRequired: Boolean,
51+
onConsentRequiredChange: (Boolean) -> Unit,
5052
privacyConsentGiven: Boolean,
5153
onConsentChange: (Boolean) -> Unit,
5254
externalUserId: String?,
@@ -118,11 +120,20 @@ fun AppSection(
118120
elevation = CardDefaults.cardElevation(defaultElevation = 0.dp)
119121
) {
120122
ToggleRow(
121-
label = "Privacy Consent",
122-
description = "Consent given for data collection",
123-
checked = privacyConsentGiven,
124-
onCheckedChange = onConsentChange
123+
label = "Consent Required",
124+
description = "Require consent before SDK processes data",
125+
checked = consentRequired,
126+
onCheckedChange = onConsentRequiredChange
125127
)
128+
if (consentRequired) {
129+
HorizontalDivider(modifier = Modifier.padding(horizontal = 16.dp))
130+
ToggleRow(
131+
label = "Privacy Consent",
132+
description = "Consent given for data collection",
133+
checked = privacyConsentGiven,
134+
onCheckedChange = onConsentChange
135+
)
136+
}
126137
}
127138

128139
// Logged In As (shown above buttons when logged in)

Examples/OneSignalDemoV2/app/src/main/java/com/onesignal/sdktest/util/SharedPreferenceUtil.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ object SharedPreferenceUtil {
1111
private const val USER_EXTERNAL_USER_ID_SHARED_PREF = "USER_EXTERNAL_USER_ID_SHARED_PREF"
1212
private const val LOCATION_SHARED_PREF = "LOCATION_SHARED_PREF"
1313
private const val IN_APP_MESSAGING_PAUSED_PREF = "IN_APP_MESSAGING_PAUSED_PREF"
14+
private const val CONSENT_REQUIRED_PREF = "CONSENT_REQUIRED_PREF"
1415

1516
private fun getSharedPreference(context: Context): SharedPreferences {
1617
return context.getSharedPreferences(APP_SHARED_PREFS, Context.MODE_PRIVATE)
@@ -60,4 +61,12 @@ object SharedPreferenceUtil {
6061
fun cacheInAppMessagingPausedStatus(context: Context, paused: Boolean) {
6162
getSharedPreference(context).edit().putBoolean(IN_APP_MESSAGING_PAUSED_PREF, paused).apply()
6263
}
64+
65+
fun getCachedConsentRequired(context: Context): Boolean {
66+
return getSharedPreference(context).getBoolean(CONSENT_REQUIRED_PREF, false)
67+
}
68+
69+
fun cacheConsentRequired(context: Context, required: Boolean) {
70+
getSharedPreference(context).edit().putBoolean(CONSENT_REQUIRED_PREF, required).apply()
71+
}
6372
}

Examples/OneSignalDemoV2/build_app_prompt.md

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ Location:
7878
- promptLocation()
7979
8080
Privacy consent:
81+
- setConsentRequired(required: Boolean)
82+
- getConsentRequired(): Boolean
8183
- setPrivacyConsent(granted: Boolean)
8284
- getPrivacyConsent(): Boolean
8385
@@ -166,10 +168,16 @@ App Section layout:
166168
- Link text: "Get your keys at onesignal.com" (clickable, opens browser)
167169
- Light background color to stand out
168170
169-
3. Privacy Consent toggle switch:
170-
- Label: "Privacy Consent"
171-
- Description: "Consent given for data collection"
172-
- Switch control
171+
3. Consent card with up to two toggles:
172+
a. "Consent Required" toggle (always visible):
173+
- Label: "Consent Required"
174+
- Description: "Require consent before SDK processes data"
175+
- Sets OneSignal.consentRequired
176+
b. "Privacy Consent" toggle (only visible when Consent Required is ON):
177+
- Label: "Privacy Consent"
178+
- Description: "Consent given for data collection"
179+
- Sets OneSignal.consentGiven
180+
- Separated from the above toggle by a horizontal divider
173181
- NOT a blocking overlay - user can interact with app regardless of state
174182
175183
4. "Logged in as" display (ABOVE the buttons, only visible when logged in):
@@ -508,6 +516,7 @@ showTooltipDialog?.let { key ->
508516
```
509517
SharedPreferenceUtil.kt stores:
510518
- OneSignal App ID
519+
- Consent required status
511520
- Privacy consent status
512521
- External user ID (for login state restoration)
513522
- Location shared status
@@ -519,12 +528,17 @@ SharedPreferenceUtil.kt stores:
519528
```
520529
On app startup, state is restored in two layers:
521530
522-
1. MainApplication.kt restores SDK state from SharedPreferences cache:
531+
1. MainApplication.kt restores SDK state from SharedPreferences cache BEFORE init:
532+
- OneSignal.consentRequired = SharedPreferenceUtil.getCachedConsentRequired(context)
533+
- OneSignal.consentGiven = SharedPreferenceUtil.getUserPrivacyConsent(context)
534+
- OneSignal.initWithContext(this, appId)
535+
Then AFTER init, restores remaining SDK state:
523536
- OneSignal.InAppMessages.paused = SharedPreferenceUtil.getCachedInAppMessagingPausedStatus(context)
524537
- OneSignal.Location.isShared = SharedPreferenceUtil.getCachedLocationSharedStatus(context)
525-
This ensures the SDK has the correct state before any UI is created.
538+
This ensures consent settings are in place before the SDK initializes.
526539
527540
2. MainViewModel.loadInitialState() reads UI state from the SDK (not SharedPreferences):
541+
- _consentRequired from repository.getConsentRequired() (reads OneSignal.consentRequired)
528542
- _privacyConsentGiven from repository.getPrivacyConsent() (reads OneSignal.consentGiven)
529543
- _inAppMessagesPaused from repository.isInAppMessagesPaused() (reads OneSignal.InAppMessages.paused)
530544
- _locationShared from repository.isLocationShared() (reads OneSignal.Location.isShared)

0 commit comments

Comments
 (0)