diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 5ed56135..4d440399 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -6,16 +6,16 @@ plugins { } kotlin { - jvmToolchain(17) + jvmToolchain(21) } android { namespace = "com.rtbishop.look4sat" - compileSdk = 35 + compileSdk = 36 defaultConfig { applicationId = "com.rtbishop.look4sat" minSdk = 24 - targetSdk = 35 + targetSdk = 36 versionCode = 400 versionName = "4.0.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/com/rtbishop/look4sat/MainContainer.kt b/app/src/main/java/com/rtbishop/look4sat/MainContainer.kt index f8454e4f..e1ec2f9a 100644 --- a/app/src/main/java/com/rtbishop/look4sat/MainContainer.kt +++ b/app/src/main/java/com/rtbishop/look4sat/MainContainer.kt @@ -90,7 +90,7 @@ class MainContainer(private val context: Context) { private fun provideLocalSource(): ILocalSource { val builder = Room.databaseBuilder(context, Look4SatDb::class.java, "Look4SatDBv313") - val database = builder.apply { fallbackToDestructiveMigration() }.build() + val database = builder.apply { fallbackToDestructiveMigration(false) }.build() return LocalSource(database.look4SatDao()) } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/components/Common.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/components/Common.kt index 34025f91..4f15470d 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/components/Common.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/components/Common.kt @@ -2,7 +2,6 @@ package com.rtbishop.look4sat.presentation.components import android.content.Context import android.content.Intent -import android.net.Uri import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -46,6 +45,7 @@ import com.rtbishop.look4sat.presentation.MainTheme import java.text.SimpleDateFormat import java.util.Date import java.util.Locale +import androidx.core.net.toUri private val sdfTime = SimpleDateFormat("HH:mm:ss", Locale.ENGLISH) @@ -225,7 +225,7 @@ fun CardLoadingIndicator() { } fun gotoUrl(context: Context, url: String) { - context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url))) + context.startActivity(Intent(Intent.ACTION_VIEW, url.toUri())) } fun getDefaultPass(): OrbitalPass { diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/map/MapScreen.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/map/MapScreen.kt index dd30d36b..e2844fc3 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/map/MapScreen.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/map/MapScreen.kt @@ -1,13 +1,11 @@ package com.rtbishop.look4sat.presentation.map -import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.Color import android.graphics.ColorMatrix import android.graphics.ColorMatrixColorFilter import android.graphics.Paint import android.graphics.Rect -import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -56,6 +54,9 @@ import org.osmdroid.views.MapView import org.osmdroid.views.overlay.FolderOverlay import org.osmdroid.views.overlay.Marker import org.osmdroid.views.overlay.Polyline +import androidx.core.graphics.toColorInt +import androidx.core.graphics.createBitmap +import androidx.core.graphics.drawable.toDrawable private val minLat = MapView.getTileSystem().minLatitude private val maxLat = MapView.getTileSystem().maxLatitude @@ -69,12 +70,12 @@ private val trackPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { private val footprintPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { strokeWidth = 3f style = Paint.Style.FILL_AND_STROKE - color = Color.parseColor("#FFE082") + color = "#FFE082".toColorInt() } private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { textSize = 36f style = Paint.Style.FILL - color = Color.parseColor("#FFE082") + color = "#FFE082".toColorInt() setShadowLayer(3f, 3f, 3f, Color.BLACK) } private val labelRect = Rect() @@ -205,12 +206,12 @@ private fun getCustomTextIcon(textLabel: String, mapView: MapView): Drawable { val iconSize = 10f val width = labelRect.width() + iconSize * 2f val height = textPaint.textSize * 3f + iconSize * 2f - val bitmap = Bitmap.createBitmap(width.toInt(), height.toInt(), Bitmap.Config.ARGB_8888) + val bitmap = createBitmap(width.toInt(), height.toInt()) Canvas(bitmap).run { drawCircle(width / 2f, height / 2f, iconSize, textPaint) drawText(textLabel, iconSize / 2f, height - iconSize, textPaint) } - return BitmapDrawable(mapView.context.resources, bitmap) + return bitmap.toDrawable(mapView.context.resources) } private fun setSatelliteTrack(satTrack: List>, mapView: MapView) { diff --git a/data/src/main/java/com/rtbishop/look4sat/data/repository/DatabaseRepo.kt b/data/src/main/java/com/rtbishop/look4sat/data/repository/DatabaseRepo.kt index ec24465e..2fdeadb6 100644 --- a/data/src/main/java/com/rtbishop/look4sat/data/repository/DatabaseRepo.kt +++ b/data/src/main/java/com/rtbishop/look4sat/data/repository/DatabaseRepo.kt @@ -50,7 +50,7 @@ class DatabaseRepo( val importedRadios = mutableListOf() // fetch val jobsMap = Sources.satelliteDataUrls.mapValues { async { remoteSource.getNetworkStream(it.value) } } - val jobRadios = async { remoteSource.getNetworkStream(Sources.radioDataUrl) } + val jobRadios = async { remoteSource.getNetworkStream(Sources.RADIO_DATA_URL) } // parse jobsMap.mapValues { job -> job.value.await() }.forEach { entry -> entry.value?.let { stream -> diff --git a/data/src/main/java/com/rtbishop/look4sat/data/source/RemoteSource.kt b/data/src/main/java/com/rtbishop/look4sat/data/source/RemoteSource.kt index 1993ed0d..876ce11a 100644 --- a/data/src/main/java/com/rtbishop/look4sat/data/source/RemoteSource.kt +++ b/data/src/main/java/com/rtbishop/look4sat/data/source/RemoteSource.kt @@ -18,13 +18,13 @@ package com.rtbishop.look4sat.data.source import android.content.ContentResolver -import android.net.Uri import com.rtbishop.look4sat.domain.source.IRemoteSource import java.io.InputStream import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import okhttp3.Request +import androidx.core.net.toUri class RemoteSource( private val dispatcher: CoroutineDispatcher, @@ -34,7 +34,7 @@ class RemoteSource( override suspend fun getFileStream(uri: String): InputStream? = withContext(dispatcher) { try { - val fileUri = Uri.parse(uri) + val fileUri = uri.toUri() contentResolver.openInputStream(fileUri) } catch (exception: Exception) { println("RemoteSource file stream exception: $exception") diff --git a/data/src/main/java/com/rtbishop/look4sat/data/usecase/OpenWebUrl.kt b/data/src/main/java/com/rtbishop/look4sat/data/usecase/OpenWebUrl.kt index eb235285..b1da8534 100644 --- a/data/src/main/java/com/rtbishop/look4sat/data/usecase/OpenWebUrl.kt +++ b/data/src/main/java/com/rtbishop/look4sat/data/usecase/OpenWebUrl.kt @@ -3,13 +3,13 @@ package com.rtbishop.look4sat.data.usecase import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent -import android.net.Uri import com.rtbishop.look4sat.domain.usecase.IOpenWebUrl +import androidx.core.net.toUri class OpenWebUrl(private val context: Context) : IOpenWebUrl { override fun invoke(url: String) { try { - context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply { + context.startActivity(Intent(Intent.ACTION_VIEW, url.toUri()).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }) } catch (_: ActivityNotFoundException) { diff --git a/domain/src/main/java/com/rtbishop/look4sat/domain/predict/DeepSpaceObject.kt b/domain/src/main/java/com/rtbishop/look4sat/domain/predict/DeepSpaceObject.kt index 76b6c379..536c6fec 100644 --- a/domain/src/main/java/com/rtbishop/look4sat/domain/predict/DeepSpaceObject.kt +++ b/domain/src/main/java/com/rtbishop/look4sat/domain/predict/DeepSpaceObject.kt @@ -112,7 +112,7 @@ class DeepSpaceObject(data: OrbitalData) : OrbitalObject(data) { dsv.t = tSince deep.dpsec(data) val a = (XKE / dsv.xn).pow(TWO_THIRDS) * tempa * tempa - dsv.em = dsv.em - tempe + dsv.em -= tempe deep.dpper() val xl = dsv.xll + dsv.omgadf + dsv.xnode val beta = sqrt(1.0 - dsv.em * dsv.em) @@ -606,37 +606,37 @@ class DeepSpaceObject(data: OrbitalData) : OrbitalObject(data) { } pgh = sghs + sghl ph = shs + sh1 - dsv.xinc = dsv.xinc + pinc - dsv.em = dsv.em + pe + dsv.xinc += pinc + dsv.em += pe if (xqncl >= 0.2) { /* Apply periodics directly */ ph /= dsv.sinio pgh -= dsv.cosio * ph - dsv.omgadf = dsv.omgadf + pgh - dsv.xnode = dsv.xnode + ph - dsv.xll = dsv.xll + pl + dsv.omgadf += pgh + dsv.xnode += ph + dsv.xll += pl } else { applyPeriodics() // This is a patch to Lyddane modification suggested by Rob Matson if (abs(xnoh - dsv.xnode) > PI) { if (dsv.xnode < xnoh) dsv.xnode += TWO_PI else dsv.xnode -= TWO_PI } - dsv.xll = dsv.xll + pl + dsv.xll += pl dsv.omgadf = xls - dsv.xll - cos(dsv.xinc) * dsv.xnode } } // Entrance for deep space secular effects fun dpsec(params: OrbitalData) { - dsv.xll = dsv.xll + ssl * dsv.t - dsv.omgadf = dsv.omgadf + ssg * dsv.t - dsv.xnode = dsv.xnode + ssh * dsv.t + dsv.xll += ssl * dsv.t + dsv.omgadf += ssg * dsv.t + dsv.xnode += ssh * dsv.t dsv.em = params.eccn + sse * dsv.t dsv.xinc = params.xincl + ssi * dsv.t if (dsv.xinc < 0) { dsv.xinc = -dsv.xinc - dsv.xnode = dsv.xnode + PI - dsv.omgadf = dsv.omgadf - PI + dsv.xnode += PI + dsv.omgadf -= PI } if (!resonance) return do processEpochRestartLoop() while (doLoop && epochRestart) @@ -788,10 +788,10 @@ class DeepSpaceObject(data: OrbitalData) : OrbitalObject(data) { doLoop = doLoop or epochRestart } if (synchronous) { - xndot = del1 * sin(xli - fasx2) + del2 * sin(2.0 * (xli - fasx4)) - +del3 * sin(3.0 * (xli - fasx6)) - xnddt = del1 * cos(xli - fasx2) + 2 * del2 * cos(2.0 * (xli - fasx4)) - +3.0 * del3 * cos(3.0 * (xli - fasx6)) + xndot = del1 * sin(xli - fasx2) + del2 * sin(2.0 * (xli - fasx4)) + + del3 * sin(3.0 * (xli - fasx6)) + xnddt = del1 * cos(xli - fasx2) + 2 * del2 * cos(2.0 * (xli - fasx4)) + + 3.0 * del3 * cos(3.0 * (xli - fasx6)) } else { xomi = omegaq + dsv.omgdot * atime x2omi = xomi + xomi diff --git a/domain/src/main/java/com/rtbishop/look4sat/domain/source/Sources.kt b/domain/src/main/java/com/rtbishop/look4sat/domain/source/Sources.kt index f46092a2..7c1466ab 100644 --- a/domain/src/main/java/com/rtbishop/look4sat/domain/source/Sources.kt +++ b/domain/src/main/java/com/rtbishop/look4sat/domain/source/Sources.kt @@ -1,7 +1,7 @@ package com.rtbishop.look4sat.domain.source object Sources { - const val radioDataUrl = "https://db.satnogs.org/api/transmitters/?format=json&status=active" + const val RADIO_DATA_URL = "https://db.satnogs.org/api/transmitters/?format=json&status=active" val satelliteDataUrls = mapOf( "All" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=active&FORMAT=csv", "Amsat" to "https://amsat.org/tle/current/nasabare.txt", diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 66377895..09ee4a0e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,24 +1,24 @@ [versions] -android-gradle-plugin = "8.8.1" -google-ksp = "2.1.10-1.0.30" -kotlin = "2.1.10" +android-gradle-plugin = "8.10.1" +google-ksp = "2.1.21-2.0.2" +kotlin = "2.1.21" -androidx-core-ktx = "1.15.0" +androidx-core-ktx = "1.16.0" androidx-core-splashscreen = "1.0.1" -androidx-room = "2.6.1" +androidx-room = "2.7.1" -compose-bom = "2025.02.00" -compose-activity = "1.10.0" -compose-lifecycle = "2.8.7" -compose-navigation = "2.8.7" +compose-bom = "2025.06.00" +compose-activity = "1.10.1" +compose-lifecycle = "2.9.1" +compose-navigation = "2.9.0" -other-coroutines = "1.10.1" -other-json = "20240303" +other-coroutines = "1.10.2" +other-json = "20250517" other-okhttp = "4.12.0" other-osmdroid = "6.1.20" test-junit4 = "4.13.2" -test-mockk = "1.13.14" +test-mockk = "1.14.2" androidTest-junit = "1.2.1" androidTest-espresso = "3.6.1" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a6f1f963..48711d76 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Sat Jan 04 21:11:19 GMT 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists