chore: auto-merge develop → main
Triggered by: 38eb66c feat(kiosk): server reachability check in step 3 + uninstall-on-generic-failure
This commit is contained in:
@@ -88,6 +88,11 @@ class KioskActivity : AppCompatActivity() {
|
||||
private lateinit var downloadProgressBar: ProgressBar
|
||||
private lateinit var downloadProgressText: TextView
|
||||
private lateinit var bannerProgressBar: ProgressBar
|
||||
// Step 3: server-reachability check card
|
||||
private lateinit var serverStatusCard: LinearLayout
|
||||
private lateinit var serverCheckIcon: TextView
|
||||
private lateinit var serverCheckText: TextView
|
||||
private lateinit var serverCheckDetail: TextView
|
||||
private var pendingApkDownloadUrl: String = ""
|
||||
private var pendingInstallFile: java.io.File? = null
|
||||
private var pendingInstallPkg: String = ""
|
||||
@@ -189,6 +194,10 @@ class KioskActivity : AppCompatActivity() {
|
||||
downloadProgressBar = findViewById(R.id.downloadProgressBar)
|
||||
downloadProgressText = findViewById(R.id.downloadProgressText)
|
||||
bannerProgressBar = findViewById(R.id.bannerProgressBar)
|
||||
serverStatusCard = findViewById(R.id.serverStatusCard)
|
||||
serverCheckIcon = findViewById(R.id.serverCheckIcon)
|
||||
serverCheckText = findViewById(R.id.serverCheckText)
|
||||
serverCheckDetail = findViewById(R.id.serverCheckDetail)
|
||||
btnDismissUpdate.setOnClickListener {
|
||||
updateBanner.visibility = View.GONE
|
||||
bannerProgressBar.visibility = View.GONE
|
||||
@@ -523,6 +532,58 @@ class KioskActivity : AppCompatActivity() {
|
||||
scaleStatusDetail.setTextColor(0xFF34d399.toInt())
|
||||
}
|
||||
|
||||
/**
|
||||
* Pings the configured EverShelf server to verify it is reachable and that the
|
||||
* error-reporting API endpoint responds. Called every time step 3 is entered so
|
||||
* the user knows whether install failures will be automatically sent to GitHub Issues.
|
||||
*/
|
||||
private fun checkServerReachability() {
|
||||
val url = prefs.getString(KEY_URL, "") ?: ""
|
||||
serverCheckIcon.text = "⏳"
|
||||
serverCheckText.text = getString(R.string.wizard_server_checking)
|
||||
serverCheckText.setTextColor(0xFF94a3b8.toInt())
|
||||
serverCheckDetail.visibility = View.GONE
|
||||
|
||||
if (url.isEmpty()) {
|
||||
serverCheckIcon.text = "⚠️"
|
||||
serverCheckText.text = getString(R.string.wizard_server_error)
|
||||
serverCheckText.setTextColor(0xFFfbbf24.toInt())
|
||||
serverCheckDetail.text = getString(R.string.wizard_server_error_detail)
|
||||
serverCheckDetail.visibility = View.VISIBLE
|
||||
return
|
||||
}
|
||||
|
||||
Thread {
|
||||
var reachable = false
|
||||
try {
|
||||
val base = url.trimEnd('/')
|
||||
val conn = java.net.URL("$base/api/?action=check_update")
|
||||
.openConnection() as java.net.HttpURLConnection
|
||||
conn.requestMethod = "GET"
|
||||
conn.connectTimeout = 5000
|
||||
conn.readTimeout = 5000
|
||||
val code = conn.responseCode
|
||||
conn.disconnect()
|
||||
reachable = code in 200..499 // any HTTP response = server is up
|
||||
} catch (_: Exception) {}
|
||||
runOnUiThread {
|
||||
if (reachable) {
|
||||
serverCheckIcon.text = "✅"
|
||||
serverCheckText.text = getString(R.string.wizard_server_ok)
|
||||
serverCheckText.setTextColor(0xFF34d399.toInt())
|
||||
serverCheckDetail.text = getString(R.string.wizard_server_ok_detail)
|
||||
serverCheckDetail.visibility = View.VISIBLE
|
||||
} else {
|
||||
serverCheckIcon.text = "⚠️"
|
||||
serverCheckText.text = getString(R.string.wizard_server_error)
|
||||
serverCheckText.setTextColor(0xFFfbbf24.toInt())
|
||||
serverCheckDetail.text = getString(R.string.wizard_server_error_detail)
|
||||
serverCheckDetail.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
/**
|
||||
* Central UI updater for the download/install progress.
|
||||
* - Updates the wizard status card if it is currently visible (step 3).
|
||||
@@ -1223,6 +1284,33 @@ class KioskActivity : AppCompatActivity() {
|
||||
runOnUiThread { activeInstallBtn?.text = getString(R.string.install_btn_retry) }
|
||||
ErrorReporter.reportMessage("install_failure",
|
||||
"PackageInstaller status=$status msg=$msg pkg=$targetPkg")
|
||||
// Generic failure on an already-installed package often means
|
||||
// a signature conflict with the old version. Offer uninstall as
|
||||
// last resort (only after the system installer already failed).
|
||||
val pkgInstalled = try {
|
||||
packageManager.getPackageInfo(targetPkg, 0); true
|
||||
} catch (_: Exception) { false }
|
||||
if (pkgInstalled) {
|
||||
runOnUiThread {
|
||||
pendingInstallFile = file
|
||||
pendingInstallPkg = targetPkg
|
||||
androidx.appcompat.app.AlertDialog.Builder(this@KioskActivity)
|
||||
.setTitle("⚠️ Installazione fallita")
|
||||
.setMessage("Installazione fallita (status=$status).\n\n" +
|
||||
"Se la versione precedente usa una firma diversa " +
|
||||
"bisogna prima disinstallarla.\n\n" +
|
||||
"Disinstalla ora e riprova automaticamente?")
|
||||
.setPositiveButton("Disinstalla e riprova") { _, _ ->
|
||||
startActivityForResult(
|
||||
Intent(Intent.ACTION_DELETE,
|
||||
android.net.Uri.parse("package:$targetPkg")),
|
||||
UNINSTALL_REQUEST
|
||||
)
|
||||
}
|
||||
.setNegativeButton("Annulla", null)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,7 +316,54 @@
|
||||
android:textSize="15sp"
|
||||
android:gravity="center"
|
||||
android:lineSpacingExtra="4dp"
|
||||
android:layout_marginBottom="24dp" />
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
<!-- Server reachability check — shown as soon as step 3 is entered -->
|
||||
<LinearLayout
|
||||
android:id="@+id/serverStatusCard"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:background="@drawable/card_background"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/serverCheckIcon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="⏳"
|
||||
android:textSize="20sp"
|
||||
android:layout_marginEnd="12dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/serverCheckText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/wizard_server_checking"
|
||||
android:textColor="#94a3b8"
|
||||
android:textSize="13sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/serverCheckDetail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=""
|
||||
android:textColor="#64748b"
|
||||
android:textSize="11sp"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Scale question card — shown first, hidden after answer -->
|
||||
<LinearLayout
|
||||
|
||||
@@ -37,4 +37,11 @@
|
||||
<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>
|
||||
|
||||
<!-- Server-Erreichbarkeit prüfen (Wizard Schritt 3) -->
|
||||
<string name="wizard_server_checking">Server-Verbindung wird geprüft…</string>
|
||||
<string name="wizard_server_ok">Server erreichbar ✅</string>
|
||||
<string name="wizard_server_ok_detail">Fehlerberichterstattung aktiv — Installationsfehler werden automatisch an GitHub Issues gesendet.</string>
|
||||
<string name="wizard_server_error">Server nicht erreichbar ⚠️</string>
|
||||
<string name="wizard_server_error_detail">Fehler werden GitHub Issues nicht erreichen. URL in Schritt 2 prüfen.</string>
|
||||
</resources>
|
||||
|
||||
@@ -37,4 +37,11 @@
|
||||
<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>
|
||||
|
||||
<!-- Verifica raggiungibilità server (step 3 wizard) -->
|
||||
<string name="wizard_server_checking">Verifica connessione server…</string>
|
||||
<string name="wizard_server_ok">Server raggiungibile ✅</string>
|
||||
<string name="wizard_server_ok_detail">Segnalazione errori attiva — i problemi di installazione vengono inviati automaticamente alle GitHub Issues.</string>
|
||||
<string name="wizard_server_error">Server non raggiungibile ⚠️</string>
|
||||
<string name="wizard_server_error_detail">Gli errori non raggiungeranno GitHub Issues. Verifica l\'URL inserito al passaggio 2.</string>
|
||||
</resources>
|
||||
|
||||
@@ -36,4 +36,11 @@
|
||||
<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>
|
||||
|
||||
<!-- Server reachability check (wizard step 3) -->
|
||||
<string name="wizard_server_checking">Checking server connection…</string>
|
||||
<string name="wizard_server_ok">Server reachable ✅</string>
|
||||
<string name="wizard_server_ok_detail">Error reporting is active — install failures will be sent to GitHub Issues automatically.</string>
|
||||
<string name="wizard_server_error">Server not reachable ⚠️</string>
|
||||
<string name="wizard_server_error_detail">Install errors won\'t reach GitHub Issues. Check the URL entered in step 2.</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user