diff --git a/app/src/main/java/com/rtbishop/look4sat/MainApplication.kt b/app/src/main/java/com/rtbishop/look4sat/MainApplication.kt index 570eead7..5fcba384 100644 --- a/app/src/main/java/com/rtbishop/look4sat/MainApplication.kt +++ b/app/src/main/java/com/rtbishop/look4sat/MainApplication.kt @@ -18,6 +18,9 @@ package com.rtbishop.look4sat import android.app.Application +import android.os.StrictMode +import android.os.StrictMode.ThreadPolicy +import android.os.StrictMode.VmPolicy import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -28,6 +31,7 @@ class MainApplication : Application() { lateinit var container: MainContainer override fun onCreate() { + if (BuildConfig.DEBUG) enableStrictMode() super.onCreate() container = MainContainer(this) container.mainScope.launch { checkAutoUpdate() } @@ -37,11 +41,21 @@ class MainApplication : Application() { val settingsRepo = container.settingsRepo if (settingsRepo.otherSettings.value.updateState) { val timeDelta = System.currentTimeMillis() - settingsRepo.databaseState.value.timestamp - if (timeDelta > 172800000) { // 48 hours in ms + if (timeDelta > AUTO_UPDATE_DELTA_MS) { val sdf = SimpleDateFormat("d MMM yyyy - HH:mm:ss", Locale.getDefault()) println("Started periodic data update on ${sdf.format(Date())}") container.databaseRepo.updateFromRemote() } } } + + private fun enableStrictMode() { + StrictMode.setThreadPolicy(ThreadPolicy.Builder().detectAll().penaltyLog().build()) + StrictMode.setVmPolicy(VmPolicy.Builder().detectAll().penaltyLog().build()) + } + + companion object { + private const val AUTO_UPDATE_DELTA_MS = 172_800_000L // 48 hours in ms + const val MAX_OKHTTP_CACHE_SIZE = 10_000_000L // 10 Megabytes + } } diff --git a/app/src/main/java/com/rtbishop/look4sat/MainContainer.kt b/app/src/main/java/com/rtbishop/look4sat/MainContainer.kt index ce4cc1f8..47b4bae5 100644 --- a/app/src/main/java/com/rtbishop/look4sat/MainContainer.kt +++ b/app/src/main/java/com/rtbishop/look4sat/MainContainer.kt @@ -84,7 +84,7 @@ class MainContainer(private val context: Context) { } private fun provideRemoteSource(): IRemoteSource { - val cache = Cache(context.cacheDir, 1000 * 1000 * 10L) + val cache = Cache(context.cacheDir, MainApplication.MAX_OKHTTP_CACHE_SIZE) val httpClient = OkHttpClient.Builder().cache(cache).build() return RemoteSource(httpClient, Dispatchers.IO) } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/FilterDialog.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/FilterDialog.kt index 277252fc..21f23650 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/FilterDialog.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/dialogs/FilterDialog.kt @@ -26,7 +26,8 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.mutableDoubleStateOf +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -43,35 +44,35 @@ private fun FilterDialogPreview() { @Composable fun FilterDialog(hours: Int, elevation: Double, toggle: () -> Unit, save: (Int, Double) -> Unit) { - val hoursValue = rememberSaveable { mutableStateOf(hours) } - val elevValue = rememberSaveable { mutableStateOf(elevation) } + val hoursValue = rememberSaveable { mutableIntStateOf(hours) } + val elevValue = rememberSaveable { mutableDoubleStateOf(elevation) } Dialog(onDismissRequest = { toggle() }) { ElevatedCard { Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth(1f)) { Text(text = "Filter passes", color = MaterialTheme.colorScheme.primary) Text(text = "Show passes that occur within X hours") - OutlinedTextField(value = hoursValue.value.toString(), onValueChange = { newValue -> + OutlinedTextField(value = hoursValue.intValue.toString(), onValueChange = { newValue -> val hoursAhead = try { newValue.toInt() } catch (exception: Exception) { 12 } - hoursValue.value = hoursAhead + hoursValue.intValue = hoursAhead }) Text(text = "Show passes with max elevation above") - OutlinedTextField(value = elevValue.value.toString(), onValueChange = { newValue -> + OutlinedTextField(value = elevValue.doubleValue.toString(), onValueChange = { newValue -> val maxElevation = try { newValue.toDouble() } catch (exception: Exception) { 16.0 } - elevValue.value = maxElevation + elevValue.doubleValue = maxElevation }) Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) { CardButton(onClick = { toggle() }, text = "Cancel") CardButton( onClick = { - save(hoursValue.value, elevValue.value) + save(hoursValue.intValue, elevValue.doubleValue) toggle() }, text = "Accept" ) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesViewModel.kt index bb805536..bb7554c1 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/passes/PassesViewModel.kt @@ -70,7 +70,7 @@ class PassesViewModel( val millisBeforeStart = nextPass.aosTime.minus(timeNow) val timerString = millisBeforeStart.toTimerString() _timerText.emit(Triple("Next - Id:$catNum", name, timerString)) - } catch (e: NoSuchElementException) { + } catch (exception: NoSuchElementException) { val lastPass = newPasses.last() val catNum = lastPass.catNum val name = lastPass.name diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/pullRefresh/PullRefreshModifier.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/pullRefresh/PullRefreshModifier.kt index 2a6299af..54139050 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/pullRefresh/PullRefreshModifier.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/pullRefresh/PullRefreshModifier.kt @@ -18,7 +18,7 @@ package com.rtbishop.look4sat.presentation.pullRefresh import androidx.compose.animation.core.LinearOutSlowInEasing import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier @@ -48,7 +48,7 @@ fun Modifier.pullRefreshIndicatorTransform( properties["state"] = state properties["scale"] = scale }) { - var height by remember { mutableStateOf(0) } + var height by remember { mutableIntStateOf(0) } Modifier .onSizeChanged { height = it.height } .graphicsLayer { diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/pullRefresh/PullRefreshState.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/pullRefresh/PullRefreshState.kt index 4c72dff2..7d6405fa 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/pullRefresh/PullRefreshState.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/pullRefresh/PullRefreshState.kt @@ -22,6 +22,7 @@ import androidx.compose.runtime.SideEffect import androidx.compose.runtime.State import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -103,8 +104,8 @@ class PullRefreshState internal constructor( private val adjustedDistancePulled by derivedStateOf { distancePulled * DRAG_MULTIPLIER } private var _refreshing by mutableStateOf(false) - private var _position by mutableStateOf(0f) - private var distancePulled by mutableStateOf(0f) + private var _position by mutableFloatStateOf(0f) + private var distancePulled by mutableFloatStateOf(0f) internal fun onPull(pullDelta: Float): Float { if (this._refreshing) return 0f // Already refreshing, do nothing. diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarView.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarView.kt index d62b0ce2..0fff1ea9 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarView.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/radar/RadarView.kt @@ -1,5 +1,3 @@ -@file:OptIn(ExperimentalTextApi::class) - package com.rtbishop.look4sat.presentation.radar import androidx.compose.animation.core.animateFloat @@ -9,6 +7,7 @@ import androidx.compose.animation.core.tween import androidx.compose.foundation.Canvas import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier @@ -25,7 +24,6 @@ import androidx.compose.ui.graphics.drawscope.Fill import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.graphics.drawscope.rotate import androidx.compose.ui.graphics.drawscope.translate -import androidx.compose.ui.text.ExperimentalTextApi import androidx.compose.ui.text.TextMeasurer import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.drawText @@ -47,7 +45,7 @@ fun RadarViewCompose(item: SatPos, items: List, azimElev: Pair(tween(1000)) val animScale = animTransition.animateFloat(16f, 64f, animSpec, label = "animScale") val measurer = rememberTextMeasurer() - val sweepDegrees = remember { mutableStateOf(0f) } + val sweepDegrees = remember { mutableFloatStateOf(0f) } val trackCreated = remember { mutableStateOf(false) } val trackPath = remember { mutableStateOf(Path()) } val trackEffect = remember { mutableStateOf(PathEffect.cornerPathEffect(0f)) } @@ -59,7 +57,7 @@ fun RadarViewCompose(item: SatPos, items: List, azimElev: Pair, azimElev: Pair 0) drawPosition(item, radius, animScale.value, primaryColor) drawAim(azimElev.first, azimElev.second, radius, strokeWidth, secondaryColor) } - sweepDegrees.value = (sweepDegrees.value + 360 / 12.0f / 60) % 360 + sweepDegrees.floatValue = (sweepDegrees.floatValue + 360 / 12.0f / 60) % 360 } } } @@ -113,7 +111,7 @@ private fun DrawScope.drawAim(azim: Float, elev: Float, radius: Float, width: Fl drawLine(color, center.copy(aimX, -aimY - size), center.copy(aimX, -aimY + size), width) drawCircle(color, size / 2, center.copy(aimX, -aimY), style = Stroke(width)) } catch (exception: Exception) { -// Timber.d(exception) + println(exception) } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsViewModel.kt index 66fd28f9..2d7ede83 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/settings/SettingsViewModel.kt @@ -109,7 +109,7 @@ class SettingsViewModel( databaseRepo.updateFromRemote() } catch (exception: Exception) { _dataSettings.value = _dataSettings.value.copy(isUpdating = false) - println(exception.printStackTrace()) + println(exception) } } @@ -119,7 +119,7 @@ class SettingsViewModel( databaseRepo.updateFromFile(uri) } catch (exception: Exception) { _dataSettings.value = _dataSettings.value.copy(isUpdating = false) - println(exception.printStackTrace()) + println(exception) } } diff --git a/data/src/main/java/com/rtbishop/look4sat/data/repository/SettingsRepo.kt b/data/src/main/java/com/rtbishop/look4sat/data/repository/SettingsRepo.kt index dac86330..e50d8ffc 100644 --- a/data/src/main/java/com/rtbishop/look4sat/data/repository/SettingsRepo.kt +++ b/data/src/main/java/com/rtbishop/look4sat/data/repository/SettingsRepo.kt @@ -18,7 +18,6 @@ package com.rtbishop.look4sat.data.repository import android.content.SharedPreferences -import android.location.Criteria import android.location.LocationManager import androidx.core.content.edit import androidx.core.location.LocationManagerCompat @@ -66,7 +65,9 @@ class SettingsRepo( //region # Station position settings private val _stationPosition = MutableStateFlow(loadStationPosition()) - private val defaultProvider = LocationManager.PASSIVE_PROVIDER + private val providerDef = LocationManager.PASSIVE_PROVIDER + private val providerGps = LocationManager.GPS_PROVIDER + private val providerNet = LocationManager.NETWORK_PROVIDER private val executor = Executors.newSingleThreadExecutor() private val timeoutSignal = CancellationSignal().apply { setOnCancelListener { _stationPosition.value = loadStationPosition() } @@ -76,14 +77,15 @@ class SettingsRepo( override fun setGpsPosition(): Boolean { if (!LocationManagerCompat.isLocationEnabled(locationManager)) return false try { - val criteria = Criteria().apply { isCostAllowed = true } - val provider = locationManager.getBestProvider(criteria, true) ?: defaultProvider + val hasGps = LocationManagerCompat.hasProvider(locationManager, providerGps) + val hasNet = LocationManagerCompat.hasProvider(locationManager, providerNet) + val provider = if (hasGps) providerGps else if (hasNet) providerNet else providerDef println("Requesting location for $provider provider") LocationManagerCompat.getCurrentLocation(locationManager, provider, timeoutSignal, executor) { it?.let { setGeoPosition(it.latitude, it.longitude, it.altitude) } } } catch (exception: SecurityException) { - println("No permissions were given") + println("No permissions were given - $exception") } return true }