diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 49acd6e..b429bec 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -41,6 +41,11 @@
+
+
diff --git a/app/src/main/java/com/dano/test1/ui/AbTestSettingsStore.kt b/app/src/main/java/com/dano/test1/ui/AbTestSettingsStore.kt
new file mode 100644
index 0000000..eb51892
--- /dev/null
+++ b/app/src/main/java/com/dano/test1/ui/AbTestSettingsStore.kt
@@ -0,0 +1,46 @@
+package com.dano.test1.ui
+
+import android.content.Context
+
+/**
+ * Persists dev-only A/B overrides. Not a security boundary; values are for local QA.
+ * Use [effectiveVariant] when branching questionnaire or remote-config logic.
+ */
+object AbTestSettingsStore {
+ private const val PREF = "dev_ab_settings"
+ private const val KEY_OVERRIDE = "override_enabled"
+ private const val KEY_VARIANT = "variant"
+
+ const val VARIANT_NONE = "NONE"
+ const val VARIANT_A = "A"
+ const val VARIANT_B = "B"
+
+ fun isOverrideEnabled(context: Context): Boolean =
+ context.getSharedPreferences(PREF, Context.MODE_PRIVATE).getBoolean(KEY_OVERRIDE, false)
+
+ fun setOverrideEnabled(context: Context, enabled: Boolean) {
+ context.getSharedPreferences(PREF, Context.MODE_PRIVATE).edit()
+ .putBoolean(KEY_OVERRIDE, enabled)
+ .apply()
+ }
+
+ fun getVariant(context: Context): String =
+ context.getSharedPreferences(PREF, Context.MODE_PRIVATE).getString(KEY_VARIANT, VARIANT_NONE)
+ ?: VARIANT_NONE
+
+ fun setVariant(context: Context, variant: String) {
+ context.getSharedPreferences(PREF, Context.MODE_PRIVATE).edit()
+ .putString(KEY_VARIANT, variant)
+ .apply()
+ }
+
+ /** Returns "A" or "B" when override is on and a branch is selected; otherwise null. */
+ fun effectiveVariant(context: Context): String? {
+ if (!isOverrideEnabled(context)) return null
+ return when (getVariant(context)) {
+ VARIANT_A -> "A"
+ VARIANT_B -> "B"
+ else -> null
+ }
+ }
+}
diff --git a/app/src/main/java/com/dano/test1/ui/DevSettingsActivity.kt b/app/src/main/java/com/dano/test1/ui/DevSettingsActivity.kt
new file mode 100644
index 0000000..16f0904
--- /dev/null
+++ b/app/src/main/java/com/dano/test1/ui/DevSettingsActivity.kt
@@ -0,0 +1,71 @@
+package com.dano.test1.ui
+
+import android.os.Bundle
+import android.widget.RadioButton
+import android.widget.RadioGroup
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.SwitchCompat
+import androidx.appcompat.widget.Toolbar
+import com.dano.test1.R
+
+/**
+ * Dev-only A/B settings. Entry: client code [_dev_settings_] on the opening screen Load action.
+ * Not a security boundary (secret string is in the APK).
+ */
+class DevSettingsActivity : AppCompatActivity() {
+
+ private lateinit var switchOverride: SwitchCompat
+ private lateinit var radioGroup: RadioGroup
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_dev_settings)
+
+ val toolbar = findViewById(R.id.devSettingsToolbar)
+ setSupportActionBar(toolbar)
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+
+ switchOverride = findViewById(R.id.switchAbOverride)
+ radioGroup = findViewById(R.id.radioGroupVariant)
+
+ applyPrefsToUi()
+
+ switchOverride.setOnCheckedChangeListener { _, isChecked ->
+ AbTestSettingsStore.setOverrideEnabled(this, isChecked)
+ updateRadiosEnabled(isChecked)
+ }
+
+ radioGroup.setOnCheckedChangeListener { _, checkedId ->
+ val variant = when (checkedId) {
+ R.id.radioVariantA -> AbTestSettingsStore.VARIANT_A
+ R.id.radioVariantB -> AbTestSettingsStore.VARIANT_B
+ else -> AbTestSettingsStore.VARIANT_NONE
+ }
+ AbTestSettingsStore.setVariant(this, variant)
+ }
+ }
+
+ private fun applyPrefsToUi() {
+ val overrideOn = AbTestSettingsStore.isOverrideEnabled(this)
+ switchOverride.isChecked = overrideOn
+ updateRadiosEnabled(overrideOn)
+
+ when (AbTestSettingsStore.getVariant(this)) {
+ AbTestSettingsStore.VARIANT_A -> radioGroup.check(R.id.radioVariantA)
+ AbTestSettingsStore.VARIANT_B -> radioGroup.check(R.id.radioVariantB)
+ else -> radioGroup.check(R.id.radioVariantDefault)
+ }
+ }
+
+ private fun updateRadiosEnabled(enabled: Boolean) {
+ for (i in 0 until radioGroup.childCount) {
+ (radioGroup.getChildAt(i) as? RadioButton)?.isEnabled = enabled
+ }
+ radioGroup.alpha = if (enabled) 1f else 0.5f
+ }
+
+ override fun onSupportNavigateUp(): Boolean {
+ finish()
+ return true
+ }
+}
diff --git a/app/src/main/java/com/dano/test1/ui/LoadButtonHandler.kt b/app/src/main/java/com/dano/test1/ui/LoadButtonHandler.kt
index 8cde1c2..1ab68ac 100644
--- a/app/src/main/java/com/dano/test1/ui/LoadButtonHandler.kt
+++ b/app/src/main/java/com/dano/test1/ui/LoadButtonHandler.kt
@@ -1,5 +1,6 @@
package com.dano.test1.ui
+import android.content.Intent
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
@@ -24,6 +25,11 @@ class LoadButtonHandler(
private val updateMainButtonsState: (Boolean) -> Unit,
) {
+ companion object {
+ /** Opening-screen client code that opens dev A/B settings (not a security boundary). */
+ private const val DEV_SETTINGS_SECRET = "_dev_settings_"
+ }
+
fun setup() {
loadButton.text = LanguageManager.getText(languageIDProvider(), "load")
loadButton.setOnClickListener { handleLoadButton() }
@@ -37,6 +43,12 @@ class LoadButtonHandler(
return
}
+ if (inputText == DEV_SETTINGS_SECRET) {
+ editText.text.clear()
+ activity.startActivity(Intent(activity, DevSettingsActivity::class.java))
+ return
+ }
+
buttonPoints.clear()
setButtonsEnabled(emptyList()) // temporär sperren
updateButtonTexts() // Chips zeigen vorläufig „Gesperrt“
diff --git a/app/src/main/res/layout/activity_dev_settings.xml b/app/src/main/res/layout/activity_dev_settings.xml
new file mode 100644
index 0000000..0cbf9f1
--- /dev/null
+++ b/app/src/main/res/layout/activity_dev_settings.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+