From d7aadff5983cbeeaa6c77c52c7dc2a5fcf90bd08 Mon Sep 17 00:00:00 2001 From: dadaloop82 Date: Mon, 18 May 2026 19:04:32 +0000 Subject: [PATCH] fix(kiosk): target SDK 35 + setInstallReason for Android 16 compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - compileSdk/targetSdk 34 → 35 (Android 15 stable) - versionCode 17 → 18, versionName 1.7.16 → 1.7.17 - PackageInstaller.SessionParams: add setInstallReason(INSTALL_REASON_USER) on API 26+ — required on Android 14+ to avoid STATUS_FAILURE=1 on self-update - DownloadManager failure: report dm_status + dm_reason in error payload so future issues include the HTTP error code (e.g. 404 vs network error) Fixes #91 #92 --- evershelf-kiosk/app/build.gradle.kts | 8 ++++---- .../dadaloop/evershelf/kiosk/KioskActivity.kt | 20 +++++++++++++++++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/evershelf-kiosk/app/build.gradle.kts b/evershelf-kiosk/app/build.gradle.kts index 9f00586..a152b2a 100644 --- a/evershelf-kiosk/app/build.gradle.kts +++ b/evershelf-kiosk/app/build.gradle.kts @@ -5,14 +5,14 @@ plugins { android { namespace = "it.dadaloop.evershelf.kiosk" - compileSdk = 34 + compileSdk = 35 defaultConfig { applicationId = "it.dadaloop.evershelf.kiosk" minSdk = 24 - targetSdk = 34 - versionCode = 17 - versionName = "1.7.16" + targetSdk = 35 + versionCode = 18 + versionName = "1.7.17" } 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 769e3a5..b276849 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 @@ -774,7 +774,13 @@ class KioskActivity : AppCompatActivity() { val q = DownloadManager.Query().setFilterById(downloadId) val c = (getSystemService(DOWNLOAD_SERVICE) as DownloadManager).query(q) var ok = false - if (c.moveToFirst()) ok = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL + var dmStatus = -1 + var dmReason = -1 + if (c.moveToFirst()) { + dmStatus = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS)) + dmReason = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_REASON)) + ok = dmStatus == DownloadManager.STATUS_SUCCESSFUL + } c.close() if (ok) { pollHandler.removeCallbacksAndMessages(null); activeDownloadId = -1 @@ -784,7 +790,12 @@ class KioskActivity : AppCompatActivity() { pollHandler.removeCallbacksAndMessages(null); activeDownloadId = -1 setInstallUI("\u274C", getString(R.string.install_error_download), getString(R.string.install_error_download_detail), 0xFFf87171.toInt(), btnEnabled = true, progress = -2) runOnUiThread { activeInstallBtn?.text = getString(R.string.install_btn_retry) } - ErrorReporter.reportMessage("install_download_failed", "DownloadManager returned failure for URL: $apkUrl") + ErrorReporter.reportMessage( + "install_download_failed", + "DownloadManager returned failure for URL: $apkUrl", + mapOf("dm_status" to dmStatus, "dm_reason" to dmReason, + "device" to buildDeviceLabel()) + ) } } } @@ -868,6 +879,11 @@ class KioskActivity : AppCompatActivity() { val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL) // Note: setAppPackageName() is intentionally omitted — it causes STATUS_FAILURE (1) // on some OEM/Android versions even when the package name is correct. + // setInstallReason is required on Android 14+ (API 34+) for PackageInstaller + // to accept self-updates; without it Android 16 returns STATUS_FAILURE=1. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + params.setInstallReason(android.content.pm.PackageManager.INSTALL_REASON_USER) + } val sessionId = pi.createSession(params) val session = pi.openSession(sessionId) try {