diff --git a/app/src/main/java/app/myzel394/alibi/db/AppSettingsSerializer.kt b/app/src/main/java/app/myzel394/alibi/db/AppSettingsSerializer.kt index ca91a75..5f8e60e 100644 --- a/app/src/main/java/app/myzel394/alibi/db/AppSettingsSerializer.kt +++ b/app/src/main/java/app/myzel394/alibi/db/AppSettingsSerializer.kt @@ -13,7 +13,7 @@ import java.io.InputStream import java.io.OutputStream import java.time.LocalDateTime -class AppSettingsSerializer: Serializer { +class AppSettingsSerializer : Serializer { override val defaultValue: AppSettings = AppSettings.getDefaultInstance() override suspend fun readFrom(input: InputStream): AppSettings { @@ -39,8 +39,9 @@ class AppSettingsSerializer: Serializer { } } -class LocalDateTimeSerializer: KSerializer { - override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING) +class LocalDateTimeSerializer : KSerializer { + override val descriptor: SerialDescriptor = + PrimitiveSerialDescriptor("LocalDateTime", PrimitiveKind.STRING) override fun deserialize(decoder: Decoder): LocalDateTime { return LocalDateTime.parse(decoder.decodeString()) diff --git a/app/src/main/java/app/myzel394/alibi/services/RecorderService.kt b/app/src/main/java/app/myzel394/alibi/services/RecorderService.kt index 939f933..35c7e14 100644 --- a/app/src/main/java/app/myzel394/alibi/services/RecorderService.kt +++ b/app/src/main/java/app/myzel394/alibi/services/RecorderService.kt @@ -23,7 +23,7 @@ import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.TimeUnit -abstract class RecorderService: Service() { +abstract class RecorderService : Service() { private val binder = RecorderBinder() private var isPaused: Boolean = false @@ -40,6 +40,7 @@ abstract class RecorderService: Service() { private set private lateinit var recordingTimeTimer: ScheduledExecutorService var onRecordingTimeChange: ((Long) -> Unit)? = null + var notificationDetails: NotificationDetails? = null protected abstract fun start() protected abstract fun pause() @@ -61,7 +62,7 @@ abstract class RecorderService: Service() { return super.onStartCommand(intent, flags, startId) } - inner class RecorderBinder: Binder() { + inner class RecorderBinder : Binder() { fun getService(): RecorderService = this@RecorderService } @@ -95,10 +96,12 @@ abstract class RecorderService: Service() { start() } } + RecorderState.PAUSED -> { pause() isPaused = true } + RecorderState.IDLE -> { stop() onDestroy() @@ -109,6 +112,7 @@ abstract class RecorderService: Service() { RecorderState.RECORDING -> { createRecordingTimeTimer() } + RecorderState.PAUSED, RecorderState.IDLE -> { recordingTimeTimer.shutdown() } @@ -121,7 +125,7 @@ abstract class RecorderService: Service() { RecorderState.PAUSED ).contains(newState) && PermissionHelper.hasGranted(this, android.Manifest.permission.POST_NOTIFICATIONS) - ){ + ) { val notification = buildNotification() NotificationManagerCompat.from(this).notify( NotificationHelper.RECORDER_CHANNEL_NOTIFICATION_ID, @@ -148,19 +152,24 @@ abstract class RecorderService: Service() { changeState(RecorderState.IDLE) stopForeground(STOP_FOREGROUND_REMOVE) - NotificationManagerCompat.from(this).cancel(NotificationHelper.RECORDER_CHANNEL_NOTIFICATION_ID) + NotificationManagerCompat.from(this) + .cancel(NotificationHelper.RECORDER_CHANNEL_NOTIFICATION_ID) stopSelf() } - private fun buildStartNotification(): Notification = NotificationCompat.Builder(this, NotificationHelper.RECORDER_CHANNEL_ID) - .setContentTitle(getString(R.string.ui_audioRecorder_state_recording_title)) - .setContentText(getString(R.string.ui_audioRecorder_state_recording_description)) - .setSmallIcon(R.drawable.launcher_foreground) - .setPriority(NotificationCompat.PRIORITY_LOW) - .setCategory(NotificationCompat.CATEGORY_SERVICE) - .build() + private fun buildStartNotification(): Notification = + NotificationCompat.Builder(this, NotificationHelper.RECORDER_CHANNEL_ID) + .setContentTitle(getString(R.string.ui_audioRecorder_state_recording_title)) + .setContentText(getString(R.string.ui_audioRecorder_state_recording_description)) + .setSmallIcon(R.drawable.launcher_foreground) + .setPriority(NotificationCompat.PRIORITY_LOW) + .setCategory(NotificationCompat.CATEGORY_SERVICE) + .build() - private fun getNotificationChangeStateIntent(newState: RecorderState, requestCode: Int): PendingIntent { + private fun getNotificationChangeStateIntent( + newState: RecorderState, + requestCode: Int + ): PendingIntent { return PendingIntent.getService( this, requestCode, @@ -172,14 +181,13 @@ abstract class RecorderService: Service() { ) } - private fun buildNotification(): Notification = when(state) { - RecorderState.RECORDING -> NotificationCompat.Builder(this, NotificationHelper.RECORDER_CHANNEL_ID) - .setContentTitle(getString(R.string.ui_audioRecorder_state_recording_title)) - .setContentText(getString(R.string.ui_audioRecorder_state_recording_description)) - .setSmallIcon(R.drawable.launcher_foreground) + private fun buildNotification(): Notification = when (state) { + RecorderState.RECORDING -> NotificationCompat.Builder( + this, + NotificationHelper.RECORDER_CHANNEL_ID + ) .setPriority(NotificationCompat.PRIORITY_LOW) .setCategory(NotificationCompat.CATEGORY_SERVICE) - .setOngoing(true) .setWhen( Date.from( Calendar @@ -210,8 +218,24 @@ abstract class RecorderService: Service() { getString(R.string.ui_audioRecorder_action_pause_label), getNotificationChangeStateIntent(RecorderState.PAUSED, 2), ) + .apply { + setContentTitle( + notificationDetails?.title + ?: getString(R.string.ui_audioRecorder_state_recording_title) + ) + setContentText( + notificationDetails?.description + ?: getString(R.string.ui_audioRecorder_state_recording_description) + ) + setSmallIcon(notificationDetails?.icon ?: R.drawable.launcher_foreground) + setOngoing(notificationDetails?.isOngoing ?: true) + } .build() - RecorderState.PAUSED -> NotificationCompat.Builder(this, NotificationHelper.RECORDER_CHANNEL_ID) + + RecorderState.PAUSED -> NotificationCompat.Builder( + this, + NotificationHelper.RECORDER_CHANNEL_ID + ) .setContentTitle(getString(R.string.ui_audioRecorder_state_paused_title)) .setContentText(getString(R.string.ui_audioRecorder_state_paused_description)) .setSmallIcon(R.drawable.launcher_foreground) @@ -236,6 +260,14 @@ abstract class RecorderService: Service() { getNotificationChangeStateIntent(RecorderState.RECORDING, 3), ) .build() + else -> throw IllegalStateException("Invalid state passed to `buildNotification()`") } + + data class NotificationDetails( + val title: String, + val description: String, + val icon: Int, + val isOngoing: Boolean, + ) } \ No newline at end of file diff --git a/app/src/main/java/app/myzel394/alibi/ui/models/AudioRecorderModel.kt b/app/src/main/java/app/myzel394/alibi/ui/models/AudioRecorderModel.kt index e9638cf..3b666cb 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/models/AudioRecorderModel.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/models/AudioRecorderModel.kt @@ -18,7 +18,7 @@ import app.myzel394.alibi.enums.RecorderState import app.myzel394.alibi.services.AudioRecorderService import app.myzel394.alibi.services.RecorderService -class AudioRecorderModel: ViewModel() { +class AudioRecorderModel : ViewModel() { var recorderState by mutableStateOf(RecorderState.IDLE) private set var recordingTime by mutableStateOf(null) @@ -48,28 +48,29 @@ class AudioRecorderModel: ViewModel() { private val connection = object : ServiceConnection { override fun onServiceConnected(className: ComponentName, service: IBinder) { - recorderService = ((service as RecorderService.RecorderBinder).getService() as AudioRecorderService).also {recorder -> - recorder.onStateChange = { state -> - recorderState = state - } - recorder.onRecordingTimeChange = { time -> - recordingTime = time - } - recorder.onAmplitudeChange = { amps -> - amplitudes = amps - onAmplitudeChange() - } - recorder.onError = { - recorderService!!.createLastRecording() - onError() - } - }.also { - it.startRecording() + recorderService = + ((service as RecorderService.RecorderBinder).getService() as AudioRecorderService).also { recorder -> + recorder.onStateChange = { state -> + recorderState = state + } + recorder.onRecordingTimeChange = { time -> + recordingTime = time + } + recorder.onAmplitudeChange = { amps -> + amplitudes = amps + onAmplitudeChange() + } + recorder.onError = { + recorderService!!.createLastRecording() + onError() + } + }.also { + it.startRecording() - recorderState = it.state - recordingTime = it.recordingTime - amplitudes = it.amplitudes - } + recorderState = it.state + recordingTime = it.recordingTime + amplitudes = it.amplitudes + } } override fun onServiceDisconnected(arg0: ComponentName) { @@ -117,6 +118,10 @@ class AudioRecorderModel: ViewModel() { recorderService!!.changeState(RecorderState.RECORDING) } + fun setNotificationDetails(details: RecorderService.NotificationDetails) { + recorderService?.notificationDetails = details + } + fun setMaxAmplitudesAmount(amount: Int) { recorderService?.amplitudesAmount = amount }