Cancel full screen notification when call is closed

Generate missed call notification also when baresip app is not visible
This commit is contained in:
Juha Heinanen
2026-02-21 21:56:15 +02:00
parent edbcf6e3d6
commit f7662fa6bd
3 changed files with 51 additions and 38 deletions
@@ -1081,8 +1081,8 @@ class BaresipService: Service() {
} }
"call closed" -> { "call closed" -> {
Log.d(TAG, "AoR $aor call $callp is closed prm: ${ev[1]}") Log.d(TAG, "AoR $aor call $callp is closed prm: ${ev[1]}")
nm.cancel(CALL_NOTIFICATION_ID)
if (call != null) { if (call != null) {
nm.cancel(CALL_NOTIFICATION_ID)
stopRinging() stopRinging()
stopMediaPlayer() stopMediaPlayer()
aec?.release() aec?.release()
@@ -1109,7 +1109,8 @@ class BaresipService: Service() {
val tone = ev[2] val tone = ev[2]
if (tone == "busy") { if (tone == "busy") {
playBusy() playBusy()
} else if (!Call.inCall()) { }
else if (!Call.inCall()) {
resetCallVolume() resetCallVolume()
abandonAudioFocus(applicationContext) abandonAudioFocus(applicationContext)
proximitySensing(false) proximitySensing(false)
@@ -1162,49 +1163,49 @@ class BaresipService: Service() {
} }
ua.account.missedCalls = ua.account.missedCalls || missed ua.account.missedCalls = ua.account.missedCalls || missed
} }
if (!Utils.isVisible()) { if (missed) {
if (missed) { val piFlags = PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
val piFlags = PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT val caller = Utils.friendlyUri(this, call.peerUri, ua.account)
val caller = Utils.friendlyUri(this, call.peerUri, ua.account) val intent = Intent(applicationContext, MainActivity::class.java)
val intent = Intent(applicationContext, MainActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK intent.putExtra("action", "call missed")
intent.putExtra("action", "call missed") .putExtra("uap", uap)
.putExtra("uap", uap) val pi = PendingIntent.getActivity(applicationContext, CALL_REQ_CODE,
val pi = PendingIntent.getActivity(applicationContext, CALL_REQ_CODE, intent, piFlags)
intent, piFlags) val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID)
val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID) nb.setSmallIcon(R.drawable.ic_notification_call_missed)
nb.setSmallIcon(R.drawable.ic_notification_call_missed) .setColor(ContextCompat.getColor(this, R.color.colorPrimary))
.setColor(ContextCompat.getColor(this, R.color.colorPrimary)) .setContentIntent(pi)
.setContentIntent(pi) .setCategory(Notification.CATEGORY_CALL)
.setCategory(Notification.CATEGORY_CALL) .setAutoCancel(true)
.setAutoCancel(true) var missedCalls = 0
var missedCalls = 0 for (notification in nm.activeNotifications)
for (notification in nm.activeNotifications) if (notification.id == CALL_MISSED_NOTIFICATION_ID)
if (notification.id == CALL_MISSED_NOTIFICATION_ID) missedCalls++
missedCalls++ if (missedCalls == 0) {
if (missedCalls == 0) { nb.setContentTitle(getString(R.string.missed_call_from))
nb.setContentTitle(getString(R.string.missed_call_from)) nb.setContentText(caller)
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())
} }
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() val reason = ev[1].trim()
if ((reason != "") && (ua.calls().isEmpty())) { if ((reason != "") && (ua.calls().isEmpty())) {
if (reason[0].isDigit()) { if (reason[0].isDigit()) {
if (reason[0] != '3') if (reason[0] != '3')
toast("${getString(R.string.call_failed)}: $reason") 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")
} }
} }
} }
@@ -111,7 +111,7 @@ class MainActivity : ComponentActivity() {
exitProcess(0) exitProcess(0)
} }
} else } else
handleServiceEvent(applicationContext, viewModel, first.event, first.params) handleServiceEvent(this, viewModel, first.event, first.params)
} }
} }
else else
@@ -3,7 +3,9 @@ package com.tutpro.baresip
import android.Manifest.permission.READ_EXTERNAL_STORAGE import android.Manifest.permission.READ_EXTERNAL_STORAGE
import android.Manifest.permission.RECORD_AUDIO import android.Manifest.permission.RECORD_AUDIO
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.app.Activity
import android.app.Activity.RESULT_OK import android.app.Activity.RESULT_OK
import android.app.KeyguardManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.res.Configuration import android.content.res.Configuration
@@ -655,7 +657,7 @@ private fun TopAppBar(
onClick = { onClick = {
if (Build.VERSION.SDK_INT >= 31) if (Build.VERSION.SDK_INT >= 31)
Log.d(TAG, "Toggling speakerphone when dev/mode is " + Log.d(TAG, "Toggling speakerphone when dev/mode is " +
"${am.communicationDevice!!.type}/${am.mode}") "${am.communicationDevice!!.type}/${am.mode}")
isSpeakerOn.value = !Utils.isSpeakerPhoneOn(am) isSpeakerOn.value = !Utils.isSpeakerPhoneOn(am)
Utils.toggleSpeakerPhone(ContextCompat.getMainExecutor(ctx), am) Utils.toggleSpeakerPhone(ContextCompat.getMainExecutor(ctx), am)
}, },
@@ -1342,11 +1344,13 @@ private fun CallUriRow(
alertMessage.value = ctx.getString(R.string.call_not_secure) alertMessage.value = ctx.getString(R.string.call_not_secure)
showAlert.value = true showAlert.value = true
} }
R.color.colorTrafficYellow -> { R.color.colorTrafficYellow -> {
alertTitle.value = ctx.getString(R.string.alert) alertTitle.value = ctx.getString(R.string.alert)
alertMessage.value = ctx.getString(R.string.peer_not_verified) alertMessage.value = ctx.getString(R.string.peer_not_verified)
showAlert.value = true showAlert.value = true
} }
R.color.colorTrafficGreen -> { R.color.colorTrafficGreen -> {
dialogTitle.value = ctx.getString(R.string.info) dialogTitle.value = ctx.getString(R.string.info)
dialogMessage.value = ctx.getString(R.string.call_is_secure) 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) showCall(ctx, viewModel, ua)
} }
"call closed" -> { "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) { if (aor == viewModel.selectedAor.value) {
viewModel.dialerState.callButtonsEnabled.value = true viewModel.dialerState.callButtonsEnabled.value = true
ua.account.resumeUri = "" ua.account.resumeUri = ""