mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-03 03:17:21 +00:00
feat: check for updates page in settings
Add a full-screen update checker accessible from a button at the bottom of the settings page. It queries the fork's GitHub latest release and can download + install the APK in place. - UpdateRepository (core/data): fetch releases/latest via GitHub API, parse tag/description/APK asset, stream APK download to cacheDir - VersionComparator (core/domain): compare 4.4.6-ba7opf.N style tags (base version first, then build number; v-prefix tolerant) + tests - IMainContainer/MainContainer: inject updateRepo - UpdateCheckerScreen (feature/settings): shows current version, checks for updates, displays latest version + release notes, and a Download & install button; FileProvider hands the APK to the system installer - SettingsScreen: bottom entry button, full-screen page toggle - AndroidManifest: REQUEST_INSTALL_PACKAGES permission + FileProvider - i18n strings (en/zh)
This commit is contained in:
1 parent
1904a6b3e6
commit
604c2ec59d
15 files changed
+551
-6
No files matched your search
@@ -35,6 +35,7 @@ import com.rtbishop.look4sat.core.data.repository.SatelliteRepo
|
||||
import com.rtbishop.look4sat.core.data.repository.SelectionRepo
|
||||
import com.rtbishop.look4sat.core.data.repository.SensorsRepo
|
||||
import com.rtbishop.look4sat.core.data.repository.SettingsRepo
|
||||
import com.rtbishop.look4sat.core.data.repository.UpdateRepository
|
||||
import com.rtbishop.look4sat.core.data.source.LocalSource
|
||||
import com.rtbishop.look4sat.core.data.source.RemoteSource
|
||||
import com.rtbishop.look4sat.core.data.usecase.AddToCalendar
|
||||
@@ -79,6 +80,7 @@ class MainContainer(private val context: Context) : IMainContainer {
|
||||
override val satelliteRepo = provideSatelliteRepo()
|
||||
override val databaseRepo = provideDatabaseRepo()
|
||||
override val amSatRepo by lazy { AmSatRepository(remoteSource, appScope) }
|
||||
override val updateRepo by lazy { UpdateRepository(remoteSource) }
|
||||
override val radioTrackingService: IRadioTrackingService by lazy {
|
||||
val manager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||
RadioTrackingService(appScope, manager, satelliteRepo, settingsRepo)
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package com.rtbishop.look4sat.core.data.repository
|
||||
|
||||
import com.rtbishop.look4sat.core.domain.model.LatestRelease
|
||||
import com.rtbishop.look4sat.core.domain.repository.IUpdateRepository
|
||||
import com.rtbishop.look4sat.core.domain.source.IRemoteSource
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
|
||||
class UpdateRepository(
|
||||
private val remoteSource: IRemoteSource
|
||||
) : IUpdateRepository {
|
||||
|
||||
override suspend fun getLatestRelease(): LatestRelease? = withContext(Dispatchers.IO) {
|
||||
val result = remoteSource.getNetworkStream(LATEST_RELEASE_URL)
|
||||
val stream = result.stream ?: return@withContext null
|
||||
try {
|
||||
val json = stream.bufferedReader().use { it.readText() }
|
||||
parseRelease(json)
|
||||
} catch (e: Exception) {
|
||||
println("UpdateRepository parse failure: $e")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun downloadApk(url: String, dest: File): Boolean = withContext(Dispatchers.IO) {
|
||||
if (url.isBlank()) return@withContext false
|
||||
val result = remoteSource.getNetworkStream(url)
|
||||
val stream = result.stream ?: return@withContext false
|
||||
try {
|
||||
dest.outputStream().use { out -> stream.use { it.copyTo(out) } }
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
println("UpdateRepository download failure: $e")
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseRelease(json: String): LatestRelease? {
|
||||
val obj = JSONObject(json)
|
||||
val tag = obj.optString("tag_name")
|
||||
if (tag.isBlank()) return null
|
||||
val assets = obj.optJSONArray("assets")
|
||||
var apkUrl: String? = null
|
||||
if (assets != null) {
|
||||
for (i in 0 until assets.length()) {
|
||||
val asset = assets.optJSONObject(i) ?: continue
|
||||
val name = asset.optString("name", "")
|
||||
if (name.endsWith(".apk")) {
|
||||
apkUrl = asset.optString("browser_download_url", "").ifBlank { null }
|
||||
if (apkUrl != null) break
|
||||
}
|
||||
}
|
||||
}
|
||||
return LatestRelease(
|
||||
versionTag = tag,
|
||||
title = obj.optString("name", ""),
|
||||
body = obj.optString("body", ""),
|
||||
apkUrl = apkUrl
|
||||
)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val LATEST_RELEASE_URL = "https://api.github.com/repos/atsunatsu/Look4Sat/releases/latest"
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user