Skip to content

Commit

Permalink
Merge pull request chenxiaolong#57 from chenxiaolong/notification
Browse files Browse the repository at this point in the history
Send notification when an error occurs during call recording
  • Loading branch information
chenxiaolong authored May 31, 2022
2 parents 23d4dbc + 1b35721 commit e2e2623
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 22 deletions.
27 changes: 22 additions & 5 deletions app/src/main/java/com/chiller3/bcr/RecorderApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import com.google.android.material.color.DynamicColors

class RecorderApplication : Application() {
companion object {
const val CHANNEL_ID = "persistent"
const val CHANNEL_ID_PERSISTENT = "persistent"
const val CHANNEL_ID_ALERTS = "alerts"
}

override fun onCreate() {
Expand All @@ -16,16 +17,32 @@ class RecorderApplication : Application() {
// Enable Material You colors
DynamicColors.applyToActivitiesIfAvailable(this)

createNotificationChannel()
createPersistentChannel()
createAlertsChannel()
}

/**
* Create a low priority notification channel for the persistent notification.
*/
private fun createNotificationChannel() {
val name: CharSequence = getString(R.string.notification_channel_persistent_name)
private fun createPersistentChannel() {
val name = getString(R.string.notification_channel_persistent_name)
val description = getString(R.string.notification_channel_persistent_desc)
val channel = NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_LOW)
val channel = NotificationChannel(
CHANNEL_ID_PERSISTENT, name, NotificationManager.IMPORTANCE_LOW)
channel.description = description

val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channel)
}

/**
* Create a high priority notification channel for alerts.
*/
private fun createAlertsChannel() {
val name = getString(R.string.notification_channel_alerts_name)
val description = getString(R.string.notification_channel_alerts_desc)
val channel = NotificationChannel(
CHANNEL_ID_ALERTS, name, NotificationManager.IMPORTANCE_HIGH)
channel.description = description

val notificationManager = getSystemService(NotificationManager::class.java)
Expand Down
57 changes: 46 additions & 11 deletions app/src/main/java/com/chiller3/bcr/RecorderInCallService.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.chiller3.bcr

import android.app.Notification
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Intent
import android.net.Uri
Expand Down Expand Up @@ -30,6 +31,8 @@ class RecorderInCallService : InCallService(), RecorderThread.OnRecordingComplet
*/
private var pendingExit = 0

private var failedNotificationId = 2

private val callback = object : Call.Callback() {
override fun onStateChanged(call: Call, state: Int) {
super.onStateChanged(call, state)
Expand Down Expand Up @@ -134,19 +137,46 @@ class RecorderInCallService : InCallService(), RecorderThread.OnRecordingComplet
val pendingIntent = PendingIntent.getActivity(
this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
)
val builder = Notification.Builder(this, RecorderApplication.CHANNEL_ID)
builder.setContentTitle(getText(R.string.recording_in_progress))
builder.setSmallIcon(R.drawable.ic_launcher_foreground)
builder.setContentIntent(pendingIntent)
builder.setOngoing(true)

// Inhibit 10-second delay when showing persistent notification
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
builder.setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_IMMEDIATE)

return Notification.Builder(this, RecorderApplication.CHANNEL_ID_PERSISTENT).run {
setContentTitle(getText(R.string.notification_recording_in_progress))
setSmallIcon(R.drawable.ic_launcher_foreground)
setContentIntent(pendingIntent)
setOngoing(true)

// Inhibit 10-second delay when showing persistent notification
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_IMMEDIATE)
}
build()
}
return builder.build()
}

private fun createRecordingFailedNotification(errorMsg: String?, uri: Uri?): Notification =
Notification.Builder(this, RecorderApplication.CHANNEL_ID_ALERTS).run {
val text = buildString {
val errorMsgTrimmed = errorMsg?.trim()
if (!errorMsgTrimmed.isNullOrBlank()) {
append(errorMsgTrimmed)
}
if (uri != null) {
if (!isEmpty()) {
append("\n\n")
}
append(uri)
}
}

setContentTitle(getString(R.string.notification_recording_failed))
if (text.isNotBlank()) {
setContentText(text)
style = Notification.BigTextStyle()
}
setSmallIcon(R.drawable.ic_launcher_foreground)

build()
}

private fun onThreadExited() {
--pendingExit
updateForegroundState()
Expand All @@ -159,10 +189,15 @@ class RecorderInCallService : InCallService(), RecorderThread.OnRecordingComplet
}
}

override fun onRecordingFailed(thread: RecorderThread, uri: Uri?) {
override fun onRecordingFailed(thread: RecorderThread, errorMsg: String?, uri: Uri?) {
Log.w(TAG, "Recording failed: ${thread.id}: ${thread.redact(uri.toString())}")
handler.post {
onThreadExited()

val notification = createRecordingFailedNotification(errorMsg, uri)
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.notify(failedNotificationId, notification)
++failedNotificationId
}
}
}
6 changes: 4 additions & 2 deletions app/src/main/java/com/chiller3/bcr/RecorderThread.kt
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ class RecorderThread(

override fun run() {
var success = false
var errorMsg: String? = null
var resultUri: Uri? = null

try {
Expand Down Expand Up @@ -190,13 +191,14 @@ class RecorderThread(
}
} catch (e: Exception) {
logE("Error during recording", e)
errorMsg = e.localizedMessage
} finally {
logI("Recording thread completed")

if (success) {
listener.onRecordingCompleted(this, resultUri!!)
} else {
listener.onRecordingFailed(this, resultUri)
listener.onRecordingFailed(this, errorMsg, resultUri)
}
}
}
Expand Down Expand Up @@ -511,6 +513,6 @@ class RecorderThread(
* output file containing partially recorded audio. If [uri] is null, then either the output
* file could not be created or the thread was cancelled before it was started.
*/
fun onRecordingFailed(thread: RecorderThread, uri: Uri?)
fun onRecordingFailed(thread: RecorderThread, errorMsg: String?, uri: Uri?)
}
}
2 changes: 1 addition & 1 deletion app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<!-- Notifications -->
<string name="notification_channel_persistent_name">Servicios en segundo plano</string>
<string name="notification_channel_persistent_desc">Notificación persistente para grabación de llamadas en segundo plano</string>
<string name="recording_in_progress">Grabación de llamadas en curso</string>
<string name="notification_recording_in_progress">Grabación de llamadas en curso</string>

<!-- Quick settings tile -->
<string name="quick_settings_label">Grabación de llamada</string>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-ru/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<!-- Notifications -->
<string name="notification_channel_persistent_name">Фоновые сервисы</string>
<string name="notification_channel_persistent_desc">Постоянное уведомление для записи вызовов в фоновом режиме</string>
<string name="recording_in_progress">Происходит запись вызова</string>
<string name="notification_recording_in_progress">Происходит запись вызова</string>

<!-- Quick settings tile -->
<string name="quick_settings_label">Запись звонка</string>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values-tr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<!-- Notifications -->
<string name="notification_channel_persistent_name">Arka plan servisleri</string>
<string name="notification_channel_persistent_desc">Arka plan çağrı kaydı için kalıcı bildirim</string>
<string name="recording_in_progress">Çağrı kaydediliyor</string>
<string name="notification_recording_in_progress">Çağrı kaydediliyor</string>

<!-- Quick settings tile -->
<string name="quick_settings_label">Çağrı kaydı</string>
Expand Down
5 changes: 4 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
<!-- Notifications -->
<string name="notification_channel_persistent_name">Background services</string>
<string name="notification_channel_persistent_desc">Persistent notification for background call recording</string>
<string name="recording_in_progress">Call recording in progress</string>
<string name="notification_channel_alerts_name">Alerts</string>
<string name="notification_channel_alerts_desc">Alerts for errors during call recording</string>
<string name="notification_recording_in_progress">Call recording in progress</string>
<string name="notification_recording_failed">Failed to record call</string>

<!-- Quick settings tile -->
<string name="quick_settings_label">Call recording</string>
Expand Down

0 comments on commit e2e2623

Please sign in to comment.