From f7662fa6bd279f337af673e3ad7e1176eda5f282 Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Sat, 21 Feb 2026 21:56:15 +0200 Subject: [PATCH] Cancel full screen notification when call is closed Generate missed call notification also when baresip app is not visible --- .../com/tutpro/baresip/BaresipService.kt | 73 ++++++++++--------- .../kotlin/com/tutpro/baresip/MainActivity.kt | 2 +- .../kotlin/com/tutpro/baresip/MainScreen.kt | 14 +++- 3 files changed, 51 insertions(+), 38 deletions(-) diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index 001d4c3f..c606acf0 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -1081,8 +1081,8 @@ class BaresipService: Service() { } "call closed" -> { Log.d(TAG, "AoR $aor call $callp is closed prm: ${ev[1]}") + nm.cancel(CALL_NOTIFICATION_ID) if (call != null) { - nm.cancel(CALL_NOTIFICATION_ID) stopRinging() stopMediaPlayer() aec?.release() @@ -1109,7 +1109,8 @@ class BaresipService: Service() { val tone = ev[2] if (tone == "busy") { playBusy() - } else if (!Call.inCall()) { + } + else if (!Call.inCall()) { resetCallVolume() abandonAudioFocus(applicationContext) proximitySensing(false) @@ -1162,49 +1163,49 @@ class BaresipService: Service() { } ua.account.missedCalls = ua.account.missedCalls || missed } - if (!Utils.isVisible()) { - if (missed) { - val piFlags = PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT - val caller = Utils.friendlyUri(this, call.peerUri, ua.account) - val intent = Intent(applicationContext, MainActivity::class.java) - intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or - Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK - intent.putExtra("action", "call missed") - .putExtra("uap", uap) - val pi = PendingIntent.getActivity(applicationContext, CALL_REQ_CODE, - intent, piFlags) - val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID) - nb.setSmallIcon(R.drawable.ic_notification_call_missed) - .setColor(ContextCompat.getColor(this, R.color.colorPrimary)) - .setContentIntent(pi) - .setCategory(Notification.CATEGORY_CALL) - .setAutoCancel(true) - var missedCalls = 0 - for (notification in nm.activeNotifications) - if (notification.id == CALL_MISSED_NOTIFICATION_ID) - missedCalls++ - if (missedCalls == 0) { - nb.setContentTitle(getString(R.string.missed_call_from)) - nb.setContentText(caller) - } else { - nb.setContentTitle(getString(R.string.missed_calls)) - nb.setContentText( - String.format(getString(R.string.missed_calls_count), - missedCalls + 1)) - } - nm.notify(CALL_MISSED_NOTIFICATION_ID, nb.build()) + if (missed) { + val piFlags = PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT + val caller = Utils.friendlyUri(this, call.peerUri, ua.account) + val intent = Intent(applicationContext, MainActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or + Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK + intent.putExtra("action", "call missed") + .putExtra("uap", uap) + val pi = PendingIntent.getActivity(applicationContext, CALL_REQ_CODE, + intent, piFlags) + val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID) + nb.setSmallIcon(R.drawable.ic_notification_call_missed) + .setColor(ContextCompat.getColor(this, R.color.colorPrimary)) + .setContentIntent(pi) + .setCategory(Notification.CATEGORY_CALL) + .setAutoCancel(true) + var missedCalls = 0 + for (notification in nm.activeNotifications) + if (notification.id == CALL_MISSED_NOTIFICATION_ID) + missedCalls++ + if (missedCalls == 0) { + nb.setContentTitle(getString(R.string.missed_call_from)) + nb.setContentText(caller) } - return + else { + nb.setContentTitle(getString(R.string.missed_calls)) + nb.setContentText( + String.format(getString(R.string.missed_calls_count), + missedCalls + 1)) + } + nm.notify(CALL_MISSED_NOTIFICATION_ID, nb.build()) } + if (!Utils.isVisible()) + return } val reason = ev[1].trim() if ((reason != "") && (ua.calls().isEmpty())) { if (reason[0].isDigit()) { if (reason[0] != '3') toast("${getString(R.string.call_failed)}: $reason") - } else { - toast("${getString(R.string.call_closed)}: ${Api.call_peer_uri(callp)}: $reason") } + else + toast("${getString(R.string.call_closed)}: ${Api.call_peer_uri(callp)}: $reason") } } } diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt index c626ee3f..44e1ce90 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt @@ -111,7 +111,7 @@ class MainActivity : ComponentActivity() { exitProcess(0) } } else - handleServiceEvent(applicationContext, viewModel, first.event, first.params) + handleServiceEvent(this, viewModel, first.event, first.params) } } else diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt index b6738e9a..7f7d2661 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt @@ -3,7 +3,9 @@ package com.tutpro.baresip import android.Manifest.permission.READ_EXTERNAL_STORAGE import android.Manifest.permission.RECORD_AUDIO import android.Manifest.permission.WRITE_EXTERNAL_STORAGE +import android.app.Activity import android.app.Activity.RESULT_OK +import android.app.KeyguardManager import android.content.Context import android.content.Intent import android.content.res.Configuration @@ -655,7 +657,7 @@ private fun TopAppBar( onClick = { if (Build.VERSION.SDK_INT >= 31) Log.d(TAG, "Toggling speakerphone when dev/mode is " + - "${am.communicationDevice!!.type}/${am.mode}") + "${am.communicationDevice!!.type}/${am.mode}") isSpeakerOn.value = !Utils.isSpeakerPhoneOn(am) Utils.toggleSpeakerPhone(ContextCompat.getMainExecutor(ctx), am) }, @@ -1342,11 +1344,13 @@ private fun CallUriRow( alertMessage.value = ctx.getString(R.string.call_not_secure) showAlert.value = true } + R.color.colorTrafficYellow -> { alertTitle.value = ctx.getString(R.string.alert) alertMessage.value = ctx.getString(R.string.peer_not_verified) showAlert.value = true } + R.color.colorTrafficGreen -> { dialogTitle.value = ctx.getString(R.string.info) dialogMessage.value = ctx.getString(R.string.call_is_secure) @@ -2460,6 +2464,14 @@ fun handleServiceEvent(ctx: Context, viewModel: ViewModel, event: String, params showCall(ctx, viewModel, ua) } "call closed" -> { + val activity = ctx as? Activity + if (activity != null) { + val kgm = activity.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager + if (kgm.isKeyguardLocked) { + activity.finishAndRemoveTask() + return + } + } if (aor == viewModel.selectedAor.value) { viewModel.dialerState.callButtonsEnabled.value = true ua.account.resumeUri = ""