diff --git a/app/src/main/java/com/eipsaferoad/owl/MainActivity.kt b/app/src/main/java/com/eipsaferoad/owl/MainActivity.kt index 1545146..a87b01a 100644 --- a/app/src/main/java/com/eipsaferoad/owl/MainActivity.kt +++ b/app/src/main/java/com/eipsaferoad/owl/MainActivity.kt @@ -12,6 +12,7 @@ import android.os.Bundle import android.os.VibrationEffect import android.os.Vibrator import android.os.VibratorManager +import android.util.Log import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.setContent @@ -49,6 +50,7 @@ import com.eipsaferoad.owl.presentation.home.Home import com.eipsaferoad.owl.presentation.login.Login import com.eipsaferoad.owl.presentation.settings.Settings import com.eipsaferoad.owl.presentation.theme.OwlTheme +import com.eipsaferoad.owl.utils.EnvEnum import com.eipsaferoad.owl.utils.LocalStorage import com.eipsaferoad.owl.utils.ReadEnvVar import com.google.android.gms.wearable.CapabilityClient @@ -100,6 +102,21 @@ class MainActivity : ComponentActivity(), setTheme(android.R.style.Theme_DeviceDefault) initVibration() url.value = ReadEnvVar.readEnvVar(this, ReadEnvVar.EnvVar.API_URL) + val alarm = LocalStorage.getData(this, EnvEnum.ALARM.value) + if (!alarm.isNullOrEmpty()) { + Log.d("PADOU", "${alarm == "1"}") + alarms.value.isAlarmActivate = alarm == "1"; + Log.d("PADOU", "${alarms.value.isAlarmActivate}") + } + val vibration = LocalStorage.getData(this, EnvEnum.VIBRATION_ALARM.value) + if (!vibration.isNullOrEmpty()) { + alarms.value.vibration.isActivate = vibration == "1"; + } + val sound = LocalStorage.getData(this, EnvEnum.SOUND_ALARM.value) + if (!sound.isNullOrEmpty()) { + alarms.value.sound.isActivate = sound[0] == '1'; + alarms.value.sound.actual = sound.substring(1).toFloat() + } setContent { WearApp(this, bpm, alarms, url.value, { token -> accessToken.value = token }, mVibrator, vibrationEffectSingle) @@ -209,8 +226,8 @@ class MainActivity : ComponentActivity(), @Composable fun WearApp(context: Context, currentHeartRate: MutableState, alarms: MutableState, apiUrl: String, setAccessToken: (token: String) -> Unit, mVibrator: Vibrator, vibrationEffectSingle: VibrationEffect) { val navController = rememberSwipeDismissableNavController() - val email = LocalStorage.getData(context, "email"); - val password = LocalStorage.getData(context, "password"); + val email = LocalStorage.getData(context, EnvEnum.EMAIL.value); + val password = LocalStorage.getData(context, EnvEnum.PASSWORD.value); if (email != null && password != null) { Authentication.login(context, apiUrl = apiUrl, email = email, password = password, navController = navController , setAccessToken = setAccessToken) } @@ -228,7 +245,7 @@ fun WearApp(context: Context, currentHeartRate: MutableState, alarms: Mu contentAlignment = Alignment.Center ) { TimeText() - Home(currentHeartRate, context, navController, alarms.value.isAlarmActivate) + Home(currentHeartRate, context, navController, alarms, mVibrator) } } composable(PagesEnum.LOGIN.value) { diff --git a/app/src/main/java/com/eipsaferoad/owl/core/Authentication.kt b/app/src/main/java/com/eipsaferoad/owl/core/Authentication.kt index 555ab2a..d247e1c 100644 --- a/app/src/main/java/com/eipsaferoad/owl/core/Authentication.kt +++ b/app/src/main/java/com/eipsaferoad/owl/core/Authentication.kt @@ -4,6 +4,7 @@ import android.content.Context import androidx.navigation.NavHostController import com.eipsaferoad.owl.api.Request import com.eipsaferoad.owl.presentation.PagesEnum +import com.eipsaferoad.owl.utils.EnvEnum import com.eipsaferoad.owl.utils.LocalStorage import okhttp3.FormBody import okhttp3.Headers @@ -35,8 +36,8 @@ class Authentication { setAccessToken(data.getString("token")) if (isNew) { - LocalStorage.setData(context, "email", email) - LocalStorage.setData(context, "password", password) + LocalStorage.setData(context, EnvEnum.EMAIL.value, email) + LocalStorage.setData(context, EnvEnum.PASSWORD.value, password) } navController.navigate(PagesEnum.HOME.value) } diff --git a/app/src/main/java/com/eipsaferoad/owl/models/VibrationAlarm.kt b/app/src/main/java/com/eipsaferoad/owl/models/VibrationAlarm.kt index ca92092..aae9b2b 100644 --- a/app/src/main/java/com/eipsaferoad/owl/models/VibrationAlarm.kt +++ b/app/src/main/java/com/eipsaferoad/owl/models/VibrationAlarm.kt @@ -9,8 +9,8 @@ class VibrationAlarm( isActivate: Boolean = false, ) : AlarmType(max, min, actual, isActivate) { private val vibrationLevels: Array = arrayOf( - VibrationEffect.EFFECT_TICK, - VibrationEffect.EFFECT_HEAVY_CLICK, + VibrationEffect.DEFAULT_AMPLITUDE, + VibrationEffect.DEFAULT_AMPLITUDE, VibrationEffect.DEFAULT_AMPLITUDE, VibrationEffect.DEFAULT_AMPLITUDE ) diff --git a/app/src/main/java/com/eipsaferoad/owl/presentation/home/Home.kt b/app/src/main/java/com/eipsaferoad/owl/presentation/home/Home.kt index e77eae0..4988176 100644 --- a/app/src/main/java/com/eipsaferoad/owl/presentation/home/Home.kt +++ b/app/src/main/java/com/eipsaferoad/owl/presentation/home/Home.kt @@ -1,6 +1,9 @@ package com.eipsaferoad.owl.presentation.home import android.content.Context +import android.os.VibrationEffect +import android.os.Vibrator +import android.util.Log import androidx.compose.animation.core.RepeatMode import androidx.compose.animation.core.animateFloat import androidx.compose.animation.core.infiniteRepeatable @@ -26,9 +29,12 @@ import androidx.compose.material.icons.rounded.Favorite import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush @@ -48,14 +54,19 @@ import androidx.wear.compose.material.ButtonDefaults import androidx.wear.compose.material.Icon import androidx.wear.compose.material.Text import androidx.wear.compose.navigation.rememberSwipeDismissableNavController +import com.eipsaferoad.owl.R +import com.eipsaferoad.owl.models.Alarm import com.eipsaferoad.owl.presentation.PagesEnum import com.eipsaferoad.owl.presentation.theme.OwlTheme +import com.eipsaferoad.owl.utils.EnvEnum import com.eipsaferoad.owl.utils.LocalStorage +import com.eipsaferoad.owl.utils.soundPlayer +import kotlinx.coroutines.delay @Composable -fun Home(currentHeartRate: MutableState, context: Context, navController: NavHostController, isAlarmActivated: Boolean) { - if (isAlarmActivated && currentHeartRate.value.toInt() < 50 && currentHeartRate.value.toInt() != 0) { - Alarm(currentHeartRate) +fun Home(currentHeartRate: MutableState, context: Context, navController: NavHostController, alarms: MutableState, mVibrator: Vibrator) { + if (alarms.value.isAlarmActivate && currentHeartRate.value.toInt() < 50 && currentHeartRate.value.toInt() != 0) { + Alarm(currentHeartRate, alarms, mVibrator) } else { NoAlarm(currentHeartRate.value, context, navController) } @@ -126,8 +137,8 @@ fun Buttons(context: Context, navController: NavHostController) { shape = RoundedCornerShape(10), colors = ButtonDefaults.buttonColors(backgroundColor = MaterialTheme.colorScheme.tertiary), onClick = { - LocalStorage.deleteData(context, "email") - LocalStorage.deleteData(context, "password") + LocalStorage.deleteData(context, EnvEnum.EMAIL.value) + LocalStorage.deleteData(context, EnvEnum.PASSWORD.value) navController.navigate(PagesEnum.LOGIN.value) } ) { @@ -191,7 +202,24 @@ fun borderBrushMultiColor(colors: List): Brush { } @Composable -fun Alarm(currentHeartRate: MutableState) { +fun Alarm(currentHeartRate: MutableState, alarms: MutableState, mVibrator: Vibrator) { + if (alarms.value.isAlarmActivate && alarms.value.sound.isActivate) { + soundPlayer(LocalContext.current, alarms.value.sound.actual, fileId = R.raw.default_alarm, loop = true) + } + var vibrationEffectSingle by remember { + mutableStateOf(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE)) + } + + LaunchedEffect(Unit) { + while(true) { + if (alarms.value.isAlarmActivate && alarms.value.vibration.isActivate) { + Log.d("PADOU", "vibration are called here") + mVibrator.vibrate(vibrationEffectSingle) + } + delay(2000) + } + } + Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center @@ -270,11 +298,11 @@ fun CircleIcon(icon: ImageVector, tint: Color) { @Composable @Preview(device = Devices.WEAR_OS_LARGE_ROUND, showSystemUi = true) fun PreviewHome() { - val bpm: MutableState = mutableStateOf("0") + /*val bpm: MutableState = mutableStateOf("0") val navController = rememberSwipeDismissableNavController() OwlTheme { Home(bpm, LocalContext.current, navController, true) - } + }*/ } @Composable @@ -289,10 +317,10 @@ fun PreviewButtons() { @Composable @Preview(device = Devices.WEAR_OS_LARGE_ROUND, showSystemUi = true) fun PreviewAlarm() { - val bpm: MutableState = mutableStateOf("0") + /*val bpm: MutableState = mutableStateOf("0") OwlTheme { Alarm(currentHeartRate = bpm) - } + }*/ } @Composable diff --git a/app/src/main/java/com/eipsaferoad/owl/presentation/settings/Settings.kt b/app/src/main/java/com/eipsaferoad/owl/presentation/settings/Settings.kt index 4b7a902..f9f42e2 100644 --- a/app/src/main/java/com/eipsaferoad/owl/presentation/settings/Settings.kt +++ b/app/src/main/java/com/eipsaferoad/owl/presentation/settings/Settings.kt @@ -5,6 +5,7 @@ import android.os.Build import android.os.VibrationEffect import android.os.Vibrator import android.os.VibratorManager +import android.util.Log import androidx.activity.ComponentActivity import androidx.annotation.RequiresApi import androidx.compose.foundation.clickable @@ -22,6 +23,8 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -45,6 +48,8 @@ import com.eipsaferoad.owl.R import com.eipsaferoad.owl.models.Alarm import com.eipsaferoad.owl.models.AlarmType import com.eipsaferoad.owl.presentation.theme.OwlTheme +import com.eipsaferoad.owl.utils.EnvEnum +import com.eipsaferoad.owl.utils.LocalStorage import com.eipsaferoad.owl.utils.soundPlayer @Composable @@ -57,15 +62,21 @@ fun Settings(context: Context, alarms: MutableState, mVibrator: Vibrator) verticalArrangement = Arrangement.spacedBy(10.dp), horizontalAlignment = Alignment.CenterHorizontally ) { - item { AlarmButton(alarms) } - item { VibrationButton(alarms, mVibrator) } + item { AlarmButton(context, alarms) } + item { VibrationButton(context, alarms, mVibrator) } item { SoundButton(alarms, context) } } } @Composable -fun AlarmButton(alarms: MutableState) { - var isAlarmActivate by remember { mutableStateOf(false) } +fun AlarmButton(context: Context, alarms: MutableState) { + var isAlarmActivate by remember { mutableStateOf(alarms.value.isAlarmActivate) } + + DisposableEffect(isAlarmActivate) { + onDispose { + LocalStorage.setData(context, EnvEnum.ALARM.value, if (isAlarmActivate) "1" else "0") + } + } Button( modifier = Modifier @@ -100,14 +111,18 @@ fun AlarmButton(alarms: MutableState) { } @Composable -fun VibrationButton(alarms: MutableState, mVibrator: Vibrator) { +fun VibrationButton(context: Context, alarms: MutableState, mVibrator: Vibrator) { var isVibrationSelected by remember { mutableStateOf(false) } - var isSoundSelected by remember { mutableStateOf(false) } var isVibrationActivate by remember { mutableStateOf(alarms.value.vibration.isActivate) } - var vibrationVal by remember { mutableStateOf(alarms.value.vibration.actual) } var vibrationEffectSingle by remember { mutableStateOf(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE)) } + + DisposableEffect(isVibrationActivate) { + onDispose { + LocalStorage.setData(context, EnvEnum.VIBRATION_ALARM.value, if (isVibrationActivate) "1" else "0") + } + } Button( modifier = Modifier @@ -115,12 +130,7 @@ fun VibrationButton(alarms: MutableState, mVibrator: Vibrator) { .height(if (isVibrationSelected) 80.dp else 40.dp), shape = RoundedCornerShape(10), colors = ButtonDefaults.buttonColors(backgroundColor = MaterialTheme.colorScheme.primary), - onClick = { - isVibrationSelected = !isVibrationSelected - if (isSoundSelected) { - isSoundSelected = false - } - } + onClick = {} ) { Column( modifier = Modifier @@ -138,7 +148,6 @@ fun VibrationButton(alarms: MutableState, mVibrator: Vibrator) { Text( text = "Vibration", ) - if (isVibrationSelected) { Switch( colors = SwitchDefaults.colors( checkedThumbColor = Color(0xFF00275B), @@ -149,54 +158,11 @@ fun VibrationButton(alarms: MutableState, mVibrator: Vibrator) { checked = isVibrationActivate, onCheckedChange = { alarms.value.vibration.isActivate = it; isVibrationActivate = it - } - ) - } - } - if (isVibrationSelected) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(start = 10.dp, end = 10.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text( - text = "-", - modifier = Modifier - .clickable { - vibrationEffectSingle = VibrationEffect.createOneShot(500, alarms.value.vibration.updateAlarm(false)) - if (vibrationVal > alarms.value.vibration.min.toFloat()) { - vibrationVal -= 1 - } - mVibrator.vibrate(vibrationEffectSingle) - } - ) - Box( - modifier = Modifier - .width(150.dp) - .height(5.dp) - .clip(RoundedCornerShape(8.dp)) - ) { - LinearProgressIndicator( - progress = vibrationVal / (alarms.value.vibration.max - alarms.value.vibration.min), - modifier = Modifier - .height(5.dp), - color = MaterialTheme.colorScheme.secondary - ) - } - Text( - text = "+", - modifier = Modifier - .clickable { - vibrationEffectSingle = VibrationEffect.createOneShot(500, alarms.value.vibration.updateAlarm()) - if (vibrationVal < alarms.value.vibration.max.toFloat()) { - vibrationVal += 1 - } + if (it) { mVibrator.vibrate(vibrationEffectSingle) } + } ) - } } } } @@ -209,6 +175,14 @@ fun SoundButton(alarms: MutableState, context: Context) { var isVibrationSelected by remember { mutableStateOf(false) } var isSoundSelected by remember { mutableStateOf(false) } + DisposableEffect(isSoundActivate, soundVal) { + onDispose { + var data = if (isSoundActivate) "1" else "0" + data += soundVal.toString() + LocalStorage.setData(context, EnvEnum.SOUND_ALARM.value, data) + } + } + Button( modifier = Modifier .width(200.dp) @@ -268,7 +242,7 @@ fun SoundButton(alarms: MutableState, context: Context) { if (soundVal > alarms.value.sound.min) { soundVal -= 0.2f } - soundPlayer(context, soundVal, fileId = R.raw.default_alarm) + soundPlayer(context, soundVal, fileId = R.raw.alarm_test) } ) Box( @@ -292,7 +266,7 @@ fun SoundButton(alarms: MutableState, context: Context) { if (soundVal < alarms.value.sound.max.toFloat()) { soundVal += 0.2f } - soundPlayer(context, soundVal, fileId = R.raw.default_alarm) + soundPlayer(context, soundVal, fileId = R.raw.alarm_test) } ) } diff --git a/app/src/main/java/com/eipsaferoad/owl/utils/LocalStorage.kt b/app/src/main/java/com/eipsaferoad/owl/utils/LocalStorage.kt index 64f0432..af59a4e 100644 --- a/app/src/main/java/com/eipsaferoad/owl/utils/LocalStorage.kt +++ b/app/src/main/java/com/eipsaferoad/owl/utils/LocalStorage.kt @@ -5,6 +5,14 @@ import java.security.KeyStore import javax.crypto.Cipher import javax.crypto.spec.SecretKeySpec +enum class EnvEnum(val value: String) { + EMAIL("email"), + PASSWORD("password"), + ALARM("alarm"), + VIBRATION_ALARM("vibration"), + SOUND_ALARM("sound"), +} + class LocalStorage { companion object { diff --git a/app/src/main/res/raw/alarm_test.mp3 b/app/src/main/res/raw/alarm_test.mp3 new file mode 100644 index 0000000..99808c8 Binary files /dev/null and b/app/src/main/res/raw/alarm_test.mp3 differ diff --git a/app/src/main/res/raw/default_alarm.mp3 b/app/src/main/res/raw/default_alarm.mp3 index 99808c8..da6c90c 100644 Binary files a/app/src/main/res/raw/default_alarm.mp3 and b/app/src/main/res/raw/default_alarm.mp3 differ diff --git a/app/src/test/java/com/eipsaferoad/owl/OwlTest.kt b/app/src/test/java/com/eipsaferoad/owl/OwlTest.kt index b9d7065..22af23c 100644 --- a/app/src/test/java/com/eipsaferoad/owl/OwlTest.kt +++ b/app/src/test/java/com/eipsaferoad/owl/OwlTest.kt @@ -27,10 +27,10 @@ class OwlTest { assertEquals(alarm.min, 0) assertEquals(alarm.actual, 0.0f) var res = alarm.updateAlarm() - assertEquals(res, VibrationEffect.EFFECT_HEAVY_CLICK) + assertEquals(res, VibrationEffect.DEFAULT_AMPLITUDE) assertEquals(alarm.actual, 1.0f) res = alarm.updateAlarm(false) - assertEquals(res, VibrationEffect.EFFECT_TICK) + assertEquals(res, VibrationEffect.DEFAULT_AMPLITUDE) assertEquals(alarm.actual, 0.0f) alarm.updateAlarm() alarm.updateAlarm()