feat: Show hint on SettingsScreen if user is recording

This commit is contained in:
Myzel394 2023-08-06 00:33:17 +02:00
parent 8e2449ab4e
commit 86d19d6cda
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
4 changed files with 70 additions and 20 deletions

View File

@ -1,6 +1,7 @@
package app.myzel394.locationtest.services package app.myzel394.locationtest.services
import android.app.Service import android.app.Service
import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.ServiceConnection import android.content.ServiceConnection
@ -11,8 +12,14 @@ import android.os.Handler
import android.os.IBinder import android.os.IBinder
import android.os.Looper import android.os.Looper
import android.util.Log import android.util.Log
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import app.myzel394.locationtest.R import app.myzel394.locationtest.R
@ -397,3 +404,27 @@ data class Settings(
} }
} }
@Composable
fun bindToRecorderService(): Pair<ServiceConnection, RecorderService?> {
val context = LocalContext.current
var service by remember { mutableStateOf<RecorderService?>(null) }
val connection = remember {
object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
service = (binder as RecorderService.LocalBinder).getService()
}
override fun onServiceDisconnected(name: ComponentName?) {
}
}
}
LaunchedEffect(Unit) {
Intent(context, RecorderService::class.java).also { intent ->
context.bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
}
return connection to service
}

View File

@ -22,6 +22,7 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.navigation.NavController import androidx.navigation.NavController
import app.myzel394.locationtest.services.RecorderService import app.myzel394.locationtest.services.RecorderService
import app.myzel394.locationtest.services.bindToRecorderService
import app.myzel394.locationtest.ui.components.AudioRecorder.molecules.RecordingStatus import app.myzel394.locationtest.ui.components.AudioRecorder.molecules.RecordingStatus
import app.myzel394.locationtest.ui.components.AudioRecorder.molecules.StartRecording import app.myzel394.locationtest.ui.components.AudioRecorder.molecules.StartRecording
import app.myzel394.locationtest.ui.enums.Screen import app.myzel394.locationtest.ui.enums.Screen
@ -33,21 +34,8 @@ fun AudioRecorder(
navController: NavController, navController: NavController,
) { ) {
val context = LocalContext.current val context = LocalContext.current
val saveFile = rememberFileSaverDialog("audio/aac") val saveFile = rememberFileSaverDialog("audio/aac")
var service by remember { mutableStateOf<RecorderService?>(null) } val (connection, service) = bindToRecorderService()
val connection = remember {
object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
service = (binder as RecorderService.LocalBinder).getService().also { service ->
}
}
override fun onServiceDisconnected(name: ComponentName?) {
}
}
}
val isRecording = service?.isRecording?.value ?: false val isRecording = service?.isRecording?.value ?: false
LaunchedEffect(Unit) { LaunchedEffect(Unit) {

View File

@ -2,8 +2,10 @@ package app.myzel394.locationtest.ui.screens
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -38,6 +40,7 @@ import androidx.navigation.NavController
import app.myzel394.locationtest.dataStore import app.myzel394.locationtest.dataStore
import app.myzel394.locationtest.db.AppSettings import app.myzel394.locationtest.db.AppSettings
import app.myzel394.locationtest.db.AudioRecorderSettings import app.myzel394.locationtest.db.AudioRecorderSettings
import app.myzel394.locationtest.services.bindToRecorderService
import app.myzel394.locationtest.ui.components.SettingsScreen.atoms.BitrateTile import app.myzel394.locationtest.ui.components.SettingsScreen.atoms.BitrateTile
import app.myzel394.locationtest.ui.components.SettingsScreen.atoms.EncoderTile import app.myzel394.locationtest.ui.components.SettingsScreen.atoms.EncoderTile
import app.myzel394.locationtest.ui.components.SettingsScreen.atoms.ForceExactMaxDurationTile import app.myzel394.locationtest.ui.components.SettingsScreen.atoms.ForceExactMaxDurationTile
@ -46,6 +49,8 @@ import app.myzel394.locationtest.ui.components.SettingsScreen.atoms.MaxDurationT
import app.myzel394.locationtest.ui.components.SettingsScreen.atoms.OutputFormatTile import app.myzel394.locationtest.ui.components.SettingsScreen.atoms.OutputFormatTile
import app.myzel394.locationtest.ui.components.SettingsScreen.atoms.SamplingRateTile import app.myzel394.locationtest.ui.components.SettingsScreen.atoms.SamplingRateTile
import app.myzel394.locationtest.ui.components.atoms.GlobalSwitch import app.myzel394.locationtest.ui.components.atoms.GlobalSwitch
import app.myzel394.locationtest.ui.components.atoms.MessageBox
import app.myzel394.locationtest.ui.components.atoms.MessageType
import app.myzel394.locationtest.ui.components.atoms.SettingsTile import app.myzel394.locationtest.ui.components.atoms.SettingsTile
import app.myzel394.locationtest.ui.utils.formatDuration import app.myzel394.locationtest.ui.utils.formatDuration
import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState
@ -60,6 +65,8 @@ import kotlinx.coroutines.launch
fun SettingsScreen( fun SettingsScreen(
navController: NavController navController: NavController
) { ) {
val (connection, service) = bindToRecorderService()
val isRecording = service?.isRecording?.value ?: false
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior( val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(
rememberTopAppBarState() rememberTopAppBarState()
) )
@ -98,6 +105,18 @@ fun SettingsScreen(
.collectAsState(initial = AppSettings.getDefaultInstance()) .collectAsState(initial = AppSettings.getDefaultInstance())
.value .value
// Show alert
if (isRecording)
Box(
modifier = Modifier
.padding(16.dp)
) {
MessageBox(
type = MessageType.WARNING,
title = "You are recording",
message = "Your changes will be applied the next time you start recording",
)
}
GlobalSwitch( GlobalSwitch(
label = "Advanced Settings", label = "Advanced Settings",
checked = settings.showAdvancedSettings, checked = settings.showAdvancedSettings,

View File

@ -3,19 +3,31 @@ package app.myzel394.locationtest.ui.utils
import kotlin.math.floor import kotlin.math.floor
fun formatDuration(durationInMilliseconds: Long): String { fun formatDuration(
durationInMilliseconds: Long,
formatFull: Boolean = false,
): String {
val totalSeconds = durationInMilliseconds / 1000
val hours = floor(totalSeconds / 3600.0).toInt()
val minutes = floor(totalSeconds / 60.0).toInt() % 60
val seconds = totalSeconds - (minutes * 60)
if (formatFull) {
return "" +
hours.toString().padStart(2, '0') +
":" + minutes.toString().padStart(2, '0') +
":" + seconds.toString().padStart(2, '0') +
"." + (durationInMilliseconds % 1000).toString()
}
if (durationInMilliseconds < 1000) { if (durationInMilliseconds < 1000) {
return "00:00.$durationInMilliseconds" return "00:00.$durationInMilliseconds"
} }
val totalSeconds = durationInMilliseconds / 1000
if (totalSeconds < 60) { if (totalSeconds < 60) {
return "00:${totalSeconds.toString().padStart(2, '0')}" return "00:${totalSeconds.toString().padStart(2, '0')}"
} }
val minutes = floor(totalSeconds / 60.0).toInt()
val seconds = totalSeconds - (minutes * 60)
return "${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}" return "${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}"
} }