From 6500d22242d91824c7891f89a6163f188c7c4255 Mon Sep 17 00:00:00 2001 From: dadaloop82 Date: Tue, 5 May 2026 16:01:47 +0000 Subject: [PATCH] kiosk: fix install dialog + screensaver always-on MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fallback install (Intent.ACTION_VIEW): - Remove FLAG_ACTIVITY_NEW_TASK: it caused startActivityForResult to return RESULT_CANCELED immediately, making the system installer dialog disappear in ~1s - After fallback returns with app not installed: show 'πŸ”„ Riprova installazione' button that calls tryFallbackInstall() directly (skips PackageInstaller which is known to give STATUS=1 on this device) Screensaver: - KioskActivity.applyScreensaverFlag(): always add FLAG_KEEP_SCREEN_ON, never clear it β€” screen must ALWAYS stay on in kiosk mode - The 'salvaschermo' toggle controls the in-app JS clock overlay (webapp setting), NOT the Android screen timeout - finishSetup(): always push screensaver_enabled to webapp API (not just when scale is configured) - SettingsActivity save: remove FLAG_KEEP_SCREEN_ON conditional; push screensaver_enabled to server API on save - Update setup wizard description + strings to clarify in-app overlay vs screen off Bump version to 1.5.2 (versionCode 8) --- evershelf-kiosk/app/build.gradle.kts | 4 +- .../dadaloop/evershelf/kiosk/KioskActivity.kt | 9 +- .../evershelf/kiosk/SettingsActivity.kt | 24 ++++-- .../dadaloop/evershelf/kiosk/SetupActivity.kt | 84 +++++++++++++------ .../src/main/res/layout/activity_setup.xml | 2 +- .../app/src/main/res/values/strings.xml | 6 +- 6 files changed, 86 insertions(+), 43 deletions(-) diff --git a/evershelf-kiosk/app/build.gradle.kts b/evershelf-kiosk/app/build.gradle.kts index 3321b1d..ea19834 100644 --- a/evershelf-kiosk/app/build.gradle.kts +++ b/evershelf-kiosk/app/build.gradle.kts @@ -11,8 +11,8 @@ android { applicationId = "it.dadaloop.evershelf.kiosk" minSdk = 24 targetSdk = 34 - versionCode = 7 - versionName = "1.5.1" + versionCode = 8 + versionName = "1.5.2" } signingConfigs { diff --git a/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/KioskActivity.kt b/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/KioskActivity.kt index 3dc50e3..079a7a6 100644 --- a/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/KioskActivity.kt +++ b/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/KioskActivity.kt @@ -439,11 +439,10 @@ class KioskActivity : AppCompatActivity() { } private fun applyScreensaverFlag() { - if (prefs.getBoolean(KEY_SCREENSAVER, false)) { - window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) - } else { - window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) - } + // The kiosk screen must ALWAYS stay on β€” the in-app screensaver is a JS overlay + // (clock + info) shown by the webapp after inactivity, not an Android screen timeout. + // Never clear FLAG_KEEP_SCREEN_ON regardless of the screensaver preference. + window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) } // ── Inject kiosk overlay (exit + refresh buttons) ──────────────────── diff --git a/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SettingsActivity.kt b/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SettingsActivity.kt index 86c4452..a53e5ff 100644 --- a/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SettingsActivity.kt +++ b/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SettingsActivity.kt @@ -106,12 +106,24 @@ class SettingsActivity : AppCompatActivity() { .putString(KEY_URL, url) .putBoolean(KEY_SCREENSAVER, screensaverOn) .apply() - // Apply FLAG_KEEP_SCREEN_ON immediately based on new setting - if (screensaverOn) { - window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) - } else { - window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) - } + // Screen always stays on in kiosk mode β€” no FLAG_KEEP_SCREEN_ON change needed here. + // Push screensaver preference to the webapp so the in-app clock overlay is toggled. + Thread { + try { + val apiUrl = "$url/api/index.php?action=save_settings" + val body = "{\"screensaver_enabled\":$screensaverOn}" + val conn = (java.net.URL(apiUrl).openConnection() as java.net.HttpURLConnection).apply { + requestMethod = "POST" + setRequestProperty("Content-Type", "application/json") + connectTimeout = 5000 + readTimeout = 5000 + doOutput = true + } + conn.outputStream.use { it.write(body.toByteArray()) } + conn.inputStream.close() + conn.disconnect() + } catch (_: Exception) {} + }.start() Toast.makeText(this, "Impostazioni salvate", Toast.LENGTH_SHORT).show() finish() } diff --git a/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SetupActivity.kt b/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SetupActivity.kt index 119bbca..c217c86 100644 --- a/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SetupActivity.kt +++ b/evershelf-kiosk/app/src/main/kotlin/it/dadaloop/evershelf/kiosk/SetupActivity.kt @@ -1068,31 +1068,35 @@ class SetupActivity : AppCompatActivity() { private fun finishSetup() { prefs.edit().putBoolean(KEY_SETUP_COMPLETE, true).apply() - // ── Pre-configure Scale Gateway URL in webapp settings ────────────────── - // If the user has a scale and the gateway is installed, write the WebSocket - // URL and enable the scale in the webapp's server settings (.env via API) - // so the webapp works out-of-the-box without manual settings configuration. - if (prefs.getBoolean(KEY_HAS_SCALE, false) && isGatewayInstalled()) { - val baseUrl = (prefs.getString(KEY_URL, "") ?: "").trimEnd('/') - if (baseUrl.isNotEmpty()) { - val gwUrl = "ws://127.0.0.1:8765" - Thread { - try { - val url = "$baseUrl/api/index.php?action=save_settings" - val body = """{"scale_enabled":true,"scale_gateway_url":"$gwUrl"}""" - val conn = (java.net.URL(url).openConnection() as java.net.HttpURLConnection).apply { - requestMethod = "POST" - setRequestProperty("Content-Type", "application/json") - connectTimeout = 5000 - readTimeout = 5000 - doOutput = true + // ── Sync settings to webapp API ───────────────────────────────────────── + // Always push: screensaver_enabled (in-app clock overlay preference). + // Conditionally add: scale settings when gateway is installed. + val baseUrl = (prefs.getString(KEY_URL, "") ?: "").trimEnd('/') + if (baseUrl.isNotEmpty()) { + val hasScale = prefs.getBoolean(KEY_HAS_SCALE, false) && isGatewayInstalled() + val screensaver = prefs.getBoolean(KEY_SCREENSAVER, false) + Thread { + try { + val url = "$baseUrl/api/index.php?action=save_settings" + val body = buildString { + append("{\"screensaver_enabled\":$screensaver") + if (hasScale) { + append(",\"scale_enabled\":true,\"scale_gateway_url\":\"ws://127.0.0.1:8765\"") } - conn.outputStream.use { it.write(body.toByteArray()) } - conn.inputStream.close() - conn.disconnect() - } catch (_: Exception) {} - }.start() - } + append("}") + } + val conn = (java.net.URL(url).openConnection() as java.net.HttpURLConnection).apply { + requestMethod = "POST" + setRequestProperty("Content-Type", "application/json") + connectTimeout = 5000 + readTimeout = 5000 + doOutput = true + } + conn.outputStream.use { it.write(body.toByteArray()) } + conn.inputStream.close() + conn.disconnect() + } catch (_: Exception) {} + }.start() } setResult(RESULT_OK) finish() @@ -1148,7 +1152,33 @@ class SetupActivity : AppCompatActivity() { getString(R.string.install_success_detail), 0xFF34d399.toInt(), btnEnabled = false) Handler(Looper.getMainLooper()).postDelayed({ checkGatewayStatus() }, 1500) } else { - checkGatewayStatus() + // Install failed or user cancelled. Show an explicit retry button + // that re-launches the system installer directly (skipping PackageInstaller, + // which is known to give STATUS=1 on this device). + val retryFile = pendingInstallFile + val retryPkg = pendingInstallPkg + setGatewayUI( + "⚠️", + "Installazione non completata", + "L'app non risulta installata. Premi il pulsante sotto per riprovare.", + 0xFFfbbf24.toInt() + ) + btnInstallGateway.visibility = View.VISIBLE + btnInstallGateway.text = "πŸ”„ Riprova installazione" + btnInstallGateway.setOnClickListener { + // Reset button back to default before retrying + btnInstallGateway.text = "πŸ“₯ Installa Scale Gateway" + btnInstallGateway.setOnClickListener { + pendingApkDownloadUrl = GATEWAY_DOWNLOAD_URL + triggerApkDownload(GATEWAY_DOWNLOAD_URL) + } + if (retryFile != null && retryFile.exists()) { + tryFallbackInstall(retryFile, retryPkg) + } else { + pendingApkDownloadUrl = GATEWAY_DOWNLOAD_URL + triggerApkDownload(GATEWAY_DOWNLOAD_URL) + } + } } }, 800) } @@ -1162,7 +1192,9 @@ class SetupActivity : AppCompatActivity() { ) val intent = Intent(Intent.ACTION_VIEW).apply { setDataAndType(uri, "application/vnd.android.package-archive") - flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NEW_TASK + // Note: do NOT add FLAG_ACTIVITY_NEW_TASK β€” it breaks startActivityForResult: + // Android would return RESULT_CANCELED immediately without waiting for the user. + flags = Intent.FLAG_GRANT_READ_URI_PERMISSION } pendingInstallFile = file pendingInstallPkg = targetPkg diff --git a/evershelf-kiosk/app/src/main/res/layout/activity_setup.xml b/evershelf-kiosk/app/src/main/res/layout/activity_setup.xml index 2360e06..d95d274 100644 --- a/evershelf-kiosk/app/src/main/res/layout/activity_setup.xml +++ b/evershelf-kiosk/app/src/main/res/layout/activity_setup.xml @@ -985,7 +985,7 @@ android:id="@+id/tvScreensaverDesc" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="Mostra un orologio con fatti utili dopo 5 minuti di inattivitΓ . Di default Γ¨ disattivato (lo schermo resta sempre acceso)." + android:text="Dopo 5 minuti di inattivitΓ  mostra un overlay con l'orologio e informazioni utili (statistiche, piano pasti). Lo schermo rimane SEMPRE acceso β€” questa opzione riguarda solo l'overlay visivo in-app." android:textColor="#94a3b8" android:textSize="15sp" android:gravity="center" diff --git a/evershelf-kiosk/app/src/main/res/values/strings.xml b/evershelf-kiosk/app/src/main/res/values/strings.xml index f51f91c..940abab 100644 --- a/evershelf-kiosk/app/src/main/res/values/strings.xml +++ b/evershelf-kiosk/app/src/main/res/values/strings.xml @@ -59,10 +59,10 @@ Server not reachable ⚠️ Install errors won\'t reach GitHub Issues. Check the URL entered in step 2. - Screensaver + Salvaschermo in-app Shows a clock with useful facts after 5 minutes of inactivity. Off by default (screen stays always on). - Enable screensaver - If disabled, the screen stays always on. + Abilita salvaschermo orologio + Mostra l'overlay orologio dopo 5 min. Lo schermo resta sempre acceso. Language