fix(kiosk,gateway): use RECEIVER_EXPORTED for DownloadManager broadcast

Root cause of 'stuck on downloading' bug (Android 13+):

DownloadManager.ACTION_DOWNLOAD_COMPLETE is sent by the system process,
which is external to our app. Registering the receiver with
RECEIVER_NOT_EXPORTED silently drops the broadcast — the BroadcastReceiver
never fires, the install never starts, and the UI stays frozen at
whatever progress percentage the poller last saw.

Fix: use RECEIVER_EXPORTED for the DownloadManager completion receiver in
both kiosk and scale-gateway apps.

The PackageInstaller result receiver (internal PendingIntent broadcast,
same package) correctly keeps RECEIVER_NOT_EXPORTED — that one is
intentionally app-private.
This commit is contained in:
dadaloop82
2026-05-03 19:19:44 +00:00
parent 0dac10d05e
commit 645162f063
2 changed files with 6 additions and 2 deletions
@@ -1082,7 +1082,9 @@ class KioskActivity : AppCompatActivity() {
} }
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE), RECEIVER_NOT_EXPORTED) // RECEIVER_EXPORTED required: ACTION_DOWNLOAD_COMPLETE is sent by the system DownloadManager
// (an external process), so NOT_EXPORTED would silently block the broadcast on API 33+.
registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE), RECEIVER_EXPORTED)
} else { } else {
@Suppress("UnspecifiedRegisterReceiverFlag") @Suppress("UnspecifiedRegisterReceiverFlag")
registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
@@ -541,7 +541,9 @@ class MainActivity : AppCompatActivity(), BleScaleListener, ServerEventListener
} }
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE), RECEIVER_NOT_EXPORTED) // RECEIVER_EXPORTED required: ACTION_DOWNLOAD_COMPLETE is sent by the system DownloadManager
// (an external process), so NOT_EXPORTED would silently block the broadcast on API 33+.
registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE), RECEIVER_EXPORTED)
} else { } else {
@Suppress("UnspecifiedRegisterReceiverFlag") @Suppress("UnspecifiedRegisterReceiverFlag")
registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))