feat(kiosk): ask if scale is present; check+update gateway in wizard
Wizard step 3 — 'Do you have a Bluetooth smart scale?':
- New question card with two buttons shown first:
✅ Yes → reveal gateway status card + bottom nav buttons
➡️ No → save KEY_HAS_SCALE=false, skip to web view
- KEY_HAS_SCALE pref controls whether the gateway is auto-launched
both after wizard completion and on every subsequent app start
- checkGatewayStatus(): uses string resources (multilingual)
- checkGatewayUpdate(): fetches GitHub release, compares version;
if gateway needs an update shows '📥 Update Scale Gateway' button
that triggers triggerApkDownload() (full PackageInstaller flow)
- onResume step-3 re-check only fires when status card is visible
(i.e. user already answered 'Yes') — handles return from install
Multi-language: strings.xml added for EN (default), IT, DE
strings: wizard_step3_question/yes/no, wizard_gateway_installed/
not_installed/checking/up_to_date/update_available/update_detail,
btn_back/launch/launch_no_scale/download_gateway/update_gateway
This commit is contained in:
@@ -77,6 +77,8 @@ class KioskActivity : AppCompatActivity() {
|
||||
private lateinit var scaleStatusIcon: TextView
|
||||
private lateinit var scaleStatusText: TextView
|
||||
private lateinit var scaleStatusDetail: TextView
|
||||
private lateinit var scaleQuestionLayout: LinearLayout
|
||||
private lateinit var step3BottomButtons: LinearLayout
|
||||
// Update banner (native, shown at the top over the WebView)
|
||||
private lateinit var updateBanner: LinearLayout
|
||||
private lateinit var tvUpdateMessage: TextView
|
||||
@@ -106,6 +108,7 @@ class KioskActivity : AppCompatActivity() {
|
||||
private const val PREFS_NAME = "evershelf_kiosk"
|
||||
private const val KEY_URL = "evershelf_url"
|
||||
private const val KEY_SETUP_COMPLETE = "setup_complete"
|
||||
private const val KEY_HAS_SCALE = "has_scale"
|
||||
private const val GATEWAY_PACKAGE = "it.dadaloop.evershelf.scalegate"
|
||||
private const val GATEWAY_DOWNLOAD_URL = "https://github.com/dadaloop82/EverShelf/releases/latest/download/evershelf-scale-gateway.apk"
|
||||
private const val KIOSK_DOWNLOAD_URL = "https://github.com/dadaloop82/EverShelf/releases/latest/download/evershelf-kiosk.apk"
|
||||
@@ -166,6 +169,8 @@ class KioskActivity : AppCompatActivity() {
|
||||
scaleStatusIcon = findViewById(R.id.scaleStatusIcon)
|
||||
scaleStatusText = findViewById(R.id.scaleStatusText)
|
||||
scaleStatusDetail = findViewById(R.id.scaleStatusDetail)
|
||||
scaleQuestionLayout = findViewById(R.id.scaleQuestionLayout)
|
||||
step3BottomButtons = findViewById(R.id.step3BottomButtons)
|
||||
|
||||
// Update banner
|
||||
updateBanner = findViewById(R.id.updateBanner)
|
||||
@@ -204,10 +209,21 @@ class KioskActivity : AppCompatActivity() {
|
||||
goToStep(2)
|
||||
}
|
||||
findViewById<MaterialButton>(R.id.btnFinish).setOnClickListener {
|
||||
prefs.edit().putBoolean(KEY_HAS_SCALE, true).apply()
|
||||
launchGatewayInBackground()
|
||||
finishWizard()
|
||||
}
|
||||
findViewById<MaterialButton>(R.id.btnSkipScale).setOnClickListener {
|
||||
// "Yes" → reveal gateway status and proceed flow
|
||||
findViewById<MaterialButton>(R.id.btnScaleYes).setOnClickListener {
|
||||
scaleQuestionLayout.visibility = View.GONE
|
||||
val statusCard = findViewById<LinearLayout>(R.id.scaleStatusCard)
|
||||
statusCard.visibility = View.VISIBLE
|
||||
step3BottomButtons.visibility = View.VISIBLE
|
||||
checkGatewayStatus()
|
||||
}
|
||||
// "No" → save pref and skip to web view
|
||||
findViewById<MaterialButton>(R.id.btnScaleNo).setOnClickListener {
|
||||
prefs.edit().putBoolean(KEY_HAS_SCALE, false).apply()
|
||||
finishWizard()
|
||||
}
|
||||
|
||||
@@ -320,7 +336,12 @@ class KioskActivity : AppCompatActivity() {
|
||||
updateStepIndicator()
|
||||
|
||||
if (step == 3) {
|
||||
checkGatewayStatus()
|
||||
// Reset to question state every time step 3 is entered
|
||||
scaleQuestionLayout.visibility = View.VISIBLE
|
||||
val statusCard = findViewById<LinearLayout>(R.id.scaleStatusCard)
|
||||
statusCard.visibility = View.GONE
|
||||
step3BottomButtons.visibility = View.GONE
|
||||
findViewById<MaterialButton>(R.id.btnSkipScale).visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,6 +397,7 @@ class KioskActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
private fun launchGatewayInBackground() {
|
||||
if (!prefs.getBoolean(KEY_HAS_SCALE, false)) return
|
||||
if (!isGatewayInstalled()) return
|
||||
val launchIntent = packageManager.getLaunchIntentForPackage(GATEWAY_PACKAGE) ?: return
|
||||
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
@@ -389,32 +411,93 @@ class KioskActivity : AppCompatActivity() {
|
||||
|
||||
private fun checkGatewayStatus() {
|
||||
if (isGatewayInstalled()) {
|
||||
scaleStatusIcon.text = "✅"
|
||||
scaleStatusText.text = "Scale Gateway is installed"
|
||||
scaleStatusDetail.text = "It will be launched in the background when you proceed"
|
||||
scaleStatusDetail.setTextColor(0xFF34d399.toInt())
|
||||
scaleStatusIcon.text = "\u2705"
|
||||
scaleStatusText.text = getString(R.string.wizard_gateway_installed)
|
||||
scaleStatusDetail.text = getString(R.string.wizard_gateway_checking)
|
||||
scaleStatusDetail.setTextColor(0xFF94a3b8.toInt())
|
||||
findViewById<MaterialButton>(R.id.btnSkipScale).visibility = View.GONE
|
||||
findViewById<MaterialButton>(R.id.btnFinish).text = "🚀 Launch EverShelf"
|
||||
findViewById<MaterialButton>(R.id.btnFinish).text = getString(R.string.btn_launch)
|
||||
// Check async if a newer version is available
|
||||
checkGatewayUpdate()
|
||||
} else {
|
||||
scaleStatusIcon.text = "📥"
|
||||
scaleStatusText.text = "Scale Gateway not installed"
|
||||
scaleStatusDetail.text = "Install the Scale Gateway app to use a Bluetooth scale"
|
||||
scaleStatusIcon.text = "\uD83D\uDCE5"
|
||||
scaleStatusText.text = getString(R.string.wizard_gateway_not_installed)
|
||||
scaleStatusDetail.text = getString(R.string.wizard_gateway_not_installed_detail)
|
||||
scaleStatusDetail.setTextColor(0xFFfbbf24.toInt())
|
||||
|
||||
findViewById<MaterialButton>(R.id.btnFinish).text = "🚀 Launch without scale"
|
||||
|
||||
findViewById<MaterialButton>(R.id.btnFinish).text = getString(R.string.btn_launch_no_scale)
|
||||
findViewById<MaterialButton>(R.id.btnSkipScale).apply {
|
||||
text = "📥 Download Scale Gateway"
|
||||
setTextColor(0xFF7c3aed.toInt())
|
||||
text = getString(R.string.btn_download_gateway)
|
||||
setTextColor(0xFFa78bfa.toInt())
|
||||
visibility = View.VISIBLE
|
||||
setOnClickListener {
|
||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(GATEWAY_DOWNLOAD_URL))
|
||||
startActivity(intent)
|
||||
}
|
||||
setOnClickListener { triggerApkDownload(GATEWAY_DOWNLOAD_URL) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Fetches the latest GitHub release and, if the gateway has an available update,
|
||||
* shows the update button in the wizard status card. */
|
||||
private fun checkGatewayUpdate() {
|
||||
val currentVersion = try {
|
||||
packageManager.getPackageInfo(GATEWAY_PACKAGE, 0).versionName ?: return
|
||||
} catch (_: Exception) { return }
|
||||
|
||||
Thread {
|
||||
try {
|
||||
val conn = URL(GITHUB_RELEASES_API).openConnection() as java.net.HttpURLConnection
|
||||
conn.setRequestProperty("Accept", "application/vnd.github+json")
|
||||
conn.connectTimeout = 5000
|
||||
conn.readTimeout = 5000
|
||||
val json = JSONObject(conn.inputStream.bufferedReader().readText())
|
||||
conn.disconnect()
|
||||
|
||||
val latestTag = json.optString("tag_name", "")
|
||||
if (latestTag.isEmpty()) { showGatewayUpToDate(); return@Thread }
|
||||
|
||||
val isSemver = latestTag.trimStart('v').matches(Regex("\\d+\\.\\d+.*"))
|
||||
val norm = { v: String -> v.trimStart('v') }
|
||||
val needsUpdate = !isSemver || norm(latestTag) != norm(currentVersion)
|
||||
|
||||
if (!needsUpdate) { showGatewayUpToDate(); return@Thread }
|
||||
|
||||
// Locate the gateway APK among release assets
|
||||
var apkUrl = GATEWAY_DOWNLOAD_URL
|
||||
val assets = json.optJSONArray("assets")
|
||||
if (assets != null) {
|
||||
for (i in 0 until assets.length()) {
|
||||
val a = assets.getJSONObject(i)
|
||||
val name = a.optString("name", "").lowercase()
|
||||
val url = a.optString("browser_download_url", "")
|
||||
if ((name.contains("gateway") || name.contains("scale")) && url.isNotEmpty()) {
|
||||
apkUrl = url; break
|
||||
}
|
||||
}
|
||||
}
|
||||
val finalUrl = apkUrl
|
||||
runOnUiThread {
|
||||
scaleStatusIcon.text = "\uD83D\uDD04"
|
||||
scaleStatusText.text = getString(R.string.wizard_gateway_update_available)
|
||||
scaleStatusDetail.text = getString(R.string.wizard_gateway_update_detail)
|
||||
scaleStatusDetail.setTextColor(0xFFfbbf24.toInt())
|
||||
pendingInstallPkg = GATEWAY_PACKAGE
|
||||
pendingApkDownloadUrl = finalUrl
|
||||
findViewById<MaterialButton>(R.id.btnSkipScale).apply {
|
||||
text = getString(R.string.btn_update_gateway)
|
||||
setTextColor(0xFFfbbf24.toInt())
|
||||
visibility = View.VISIBLE
|
||||
setOnClickListener { triggerApkDownload(finalUrl) }
|
||||
}
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
showGatewayUpToDate()
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
private fun showGatewayUpToDate() = runOnUiThread {
|
||||
scaleStatusDetail.text = getString(R.string.wizard_gateway_installed_detail)
|
||||
scaleStatusDetail.setTextColor(0xFF34d399.toInt())
|
||||
}
|
||||
|
||||
// ── Connection Test ───────────────────────────────────────────────────
|
||||
|
||||
private fun testConnection() {
|
||||
@@ -996,7 +1079,9 @@ class KioskActivity : AppCompatActivity() {
|
||||
showWizard()
|
||||
}
|
||||
if (currentStep == 3 && wizardContainer.visibility == View.VISIBLE) {
|
||||
checkGatewayStatus()
|
||||
val statusCard = findViewById<LinearLayout>(R.id.scaleStatusCard)
|
||||
// Only re-check if the user has already answered "Yes" (status card visible)
|
||||
if (statusCard.visibility == View.VISIBLE) checkGatewayStatus()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -302,7 +302,7 @@
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Smart Scale (Optional)"
|
||||
android:text="@string/wizard_step3_title"
|
||||
android:textColor="#f1f5f9"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
@@ -311,14 +311,56 @@
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="To use a Bluetooth kitchen scale, you need the EverShelf Scale Gateway app installed separately."
|
||||
android:text="@string/wizard_step3_description"
|
||||
android:textColor="#94a3b8"
|
||||
android:textSize="15sp"
|
||||
android:gravity="center"
|
||||
android:lineSpacingExtra="4dp"
|
||||
android:layout_marginBottom="24dp" />
|
||||
|
||||
<!-- Scale status card -->
|
||||
<!-- Scale question card — shown first, hidden after answer -->
|
||||
<LinearLayout
|
||||
android:id="@+id/scaleQuestionLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/card_background"
|
||||
android:padding="20dp"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/wizard_step3_question"
|
||||
android:textColor="#f1f5f9"
|
||||
android:textSize="17sp"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="20dp" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnScaleYes"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:text="@string/wizard_step3_yes"
|
||||
android:textSize="15sp"
|
||||
android:textAllCaps="false"
|
||||
android:backgroundTint="#059669"
|
||||
android:layout_marginBottom="10dp" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnScaleNo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:text="@string/wizard_step3_no"
|
||||
android:textSize="15sp"
|
||||
android:textAllCaps="false"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
android:strokeColor="#334155"
|
||||
android:textColor="#94a3b8" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Scale status card — shown after user answers "Yes" -->
|
||||
<LinearLayout
|
||||
android:id="@+id/scaleStatusCard"
|
||||
android:layout_width="match_parent"
|
||||
@@ -326,7 +368,8 @@
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/card_background"
|
||||
android:padding="20dp"
|
||||
android:layout_marginBottom="16dp">
|
||||
android:layout_marginBottom="16dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/scaleStatusIcon"
|
||||
@@ -357,19 +400,22 @@
|
||||
android:gravity="center" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Bottom nav (Back / Launch) — hidden until user answers the question -->
|
||||
<LinearLayout
|
||||
android:id="@+id/step3BottomButtons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="16dp">
|
||||
android:layout_marginTop="16dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnStep3Back"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_weight="1"
|
||||
android:text="Back"
|
||||
android:text="@string/btn_back"
|
||||
android:textSize="15sp"
|
||||
android:textAllCaps="false"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
@@ -382,22 +428,24 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_weight="2"
|
||||
android:text="🚀 Launch EverShelf"
|
||||
android:text="@string/btn_launch"
|
||||
android:textSize="16sp"
|
||||
android:textAllCaps="false"
|
||||
android:backgroundTint="#059669" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Install/Update gateway button — shown by checkGatewayStatus() as needed -->
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnSkipScale"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="36dp"
|
||||
android:text="Skip — I don't have a scale"
|
||||
android:textSize="13sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textAllCaps="false"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:textColor="#64748b"
|
||||
android:layout_marginTop="12dp" />
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
android:strokeColor="#7c3aed"
|
||||
android:textColor="#a78bfa"
|
||||
android:layout_marginTop="12dp"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">EverShelf Kiosk</string>
|
||||
|
||||
<!-- Wizard Schritt 3: Smart-Waage -->
|
||||
<string name="wizard_step3_title">Smart-Waage (Optional)</string>
|
||||
<string name="wizard_step3_description">Um eine Bluetooth-Küchenwaage zu verwenden, musst du die EverShelf Scale Gateway App separat installieren.</string>
|
||||
<string name="wizard_step3_question">Hast du eine Bluetooth-Küchenwaage?</string>
|
||||
<string name="wizard_step3_yes">✅ Ja, ich habe eine Waage</string>
|
||||
<string name="wizard_step3_no">➡️ Nein, überspringen</string>
|
||||
|
||||
<!-- Gateway-Statusmeldungen -->
|
||||
<string name="wizard_gateway_installed">Scale Gateway installiert ✅</string>
|
||||
<string name="wizard_gateway_installed_detail">Wird beim Fortfahren im Hintergrund gestartet.</string>
|
||||
<string name="wizard_gateway_not_installed">Scale Gateway nicht installiert</string>
|
||||
<string name="wizard_gateway_not_installed_detail">Installiere die Scale Gateway App, um eine Bluetooth-Waage zu nutzen.</string>
|
||||
<string name="wizard_gateway_checking">Prüfe auf Updates…</string>
|
||||
<string name="wizard_gateway_up_to_date">Scale Gateway ist aktuell.</string>
|
||||
<string name="wizard_gateway_update_available">Update für Scale Gateway verfügbar</string>
|
||||
<string name="wizard_gateway_update_detail">Tippe auf den Button, um jetzt zu aktualisieren.</string>
|
||||
|
||||
<!-- Schaltflächen -->
|
||||
<string name="btn_back">Zurück</string>
|
||||
<string name="btn_launch">🚀 EverShelf starten</string>
|
||||
<string name="btn_launch_no_scale">🚀 Ohne Waage starten</string>
|
||||
<string name="btn_download_gateway">📥 Scale Gateway installieren</string>
|
||||
<string name="btn_update_gateway">📥 Scale Gateway aktualisieren</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">EverShelf Kiosk</string>
|
||||
|
||||
<!-- Wizard Step 3: Bilancia smart -->
|
||||
<string name="wizard_step3_title">Bilancia Smart (Opzionale)</string>
|
||||
<string name="wizard_step3_description">Per usare una bilancia da cucina Bluetooth, devi installare l\'app EverShelf Scale Gateway separatamente.</string>
|
||||
<string name="wizard_step3_question">Hai una bilancia smart Bluetooth?</string>
|
||||
<string name="wizard_step3_yes">✅ Sì, ho una bilancia</string>
|
||||
<string name="wizard_step3_no">➡️ No, salta questo passaggio</string>
|
||||
|
||||
<!-- Messaggi stato gateway -->
|
||||
<string name="wizard_gateway_installed">Scale Gateway installato ✅</string>
|
||||
<string name="wizard_gateway_installed_detail">Verrà avviato in background quando procedi.</string>
|
||||
<string name="wizard_gateway_not_installed">Scale Gateway non installato</string>
|
||||
<string name="wizard_gateway_not_installed_detail">Installa l\'app Scale Gateway per usare una bilancia Bluetooth.</string>
|
||||
<string name="wizard_gateway_checking">Controllo aggiornamenti…</string>
|
||||
<string name="wizard_gateway_up_to_date">Scale Gateway è aggiornato.</string>
|
||||
<string name="wizard_gateway_update_available">Aggiornamento disponibile per Scale Gateway</string>
|
||||
<string name="wizard_gateway_update_detail">Tocca il pulsante qui sotto per aggiornarlo ora.</string>
|
||||
|
||||
<!-- Pulsanti -->
|
||||
<string name="btn_back">Indietro</string>
|
||||
<string name="btn_launch">🚀 Avvia EverShelf</string>
|
||||
<string name="btn_launch_no_scale">🚀 Avvia senza bilancia</string>
|
||||
<string name="btn_download_gateway">📥 Installa Scale Gateway</string>
|
||||
<string name="btn_update_gateway">📥 Aggiorna Scale Gateway</string>
|
||||
</resources>
|
||||
@@ -1,3 +1,27 @@
|
||||
<resources>
|
||||
<string name="app_name">EverShelf Kiosk</string>
|
||||
|
||||
<!-- Wizard Step 3: Smart scale -->
|
||||
<string name="wizard_step3_title">Smart Scale (Optional)</string>
|
||||
<string name="wizard_step3_description">To use a Bluetooth kitchen scale, you need the EverShelf Scale Gateway app installed separately.</string>
|
||||
<string name="wizard_step3_question">Do you have a Bluetooth smart scale?</string>
|
||||
<string name="wizard_step3_yes">✅ Yes, I have a scale</string>
|
||||
<string name="wizard_step3_no">➡️ No, skip this step</string>
|
||||
|
||||
<!-- Gateway status messages -->
|
||||
<string name="wizard_gateway_installed">Scale Gateway installed ✅</string>
|
||||
<string name="wizard_gateway_installed_detail">Will be launched in the background when you proceed.</string>
|
||||
<string name="wizard_gateway_not_installed">Scale Gateway not installed</string>
|
||||
<string name="wizard_gateway_not_installed_detail">Install the Scale Gateway app to use a Bluetooth scale.</string>
|
||||
<string name="wizard_gateway_checking">Checking for updates…</string>
|
||||
<string name="wizard_gateway_up_to_date">Scale Gateway is up to date.</string>
|
||||
<string name="wizard_gateway_update_available">Update available for Scale Gateway</string>
|
||||
<string name="wizard_gateway_update_detail">Tap the button below to update it now.</string>
|
||||
|
||||
<!-- Buttons -->
|
||||
<string name="btn_back">Back</string>
|
||||
<string name="btn_launch">🚀 Launch EverShelf</string>
|
||||
<string name="btn_launch_no_scale">🚀 Launch without scale</string>
|
||||
<string name="btn_download_gateway">📥 Install Scale Gateway</string>
|
||||
<string name="btn_update_gateway">📥 Update Scale Gateway</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user