From cc52442be3da7635bd071d0f17ef6bc017478da6 Mon Sep 17 00:00:00 2001 From: M57 <41645758+Hy4ri@users.noreply.github.com> Date: Fri, 19 Jun 2026 22:15:47 +0300 Subject: [PATCH] fix(#65): request POST_NOTIFICATIONS runtime permission on Android 13+ (#97) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(#65): request POST_NOTIFICATIONS runtime permission on Android 13+ On API 33+ the manifest declaration alone is not enough — the app must request POST_NOTIFICATIONS via ActivityResultContracts.RequestPermission at runtime before it can show any notification, including the foreground service notification from ChatNotificationService. - Added rememberLauncherForActivityResult for POST_NOTIFICATIONS - Added LaunchedEffect(Unit) that fires the permission request on first composition when running on API 33+ and permission is not yet granted - The next lifecycle event (ON_STOP → NotificationHelper.start) picks up the permission if granted * fix: add missing import android.os.Build for POST_NOTIFICATIONS permission check * fix: add missing import for rememberLauncherForActivityResult (androidx.activity.compose) --------- Co-authored-by: M57 --- .../m57/hermescontrol/ui/chat/ChatScreen.kt | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt b/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt index 28158026..6cbe392a 100644 --- a/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt +++ b/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt @@ -1,5 +1,8 @@ package com.m57.hermescontrol.ui.chat +import android.os.Build +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.animateContentSize import androidx.compose.animation.core.LinearEasing @@ -85,6 +88,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.core.content.ContextCompat import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import com.m57.hermescontrol.notification.NotificationHelper @@ -136,6 +140,26 @@ fun ChatScreen( } } + // Request POST_NOTIFICATIONS runtime permission on Android 13+ (API 33). + // The manifest declaration alone is insufficient — on API 33+ the system + // requires a runtime permission prompt before the app can post any + // notification, including the foreground service notification. + val requestNotificationPermission = + rememberLauncherForActivityResult( + contract = ActivityResultContracts.RequestPermission(), + ) { /* granted — next lifecycle event will pick it up */ } + LaunchedEffect(Unit) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + val permission = android.Manifest.permission.POST_NOTIFICATIONS + if ( + ContextCompat.checkSelfPermission(context, permission) != + android.content.pm.PackageManager.PERMISSION_GRANTED + ) { + requestNotificationPermission.launch(permission) + } + } + } + // Auto-scroll to bottom on new messages LaunchedEffect(state.messages.size, state.currentStreamingText) { if (state.messages.isNotEmpty()) {