From 18b00cd2a6e774bd01a1b7f3da001ae2a5247497 Mon Sep 17 00:00:00 2001 From: yunnysunny Date: Thu, 11 Sep 2025 19:36:54 +0800 Subject: [PATCH 1/7] feat: add auto start apps ability --- app/build.gradle.kts | 3 + .../nl/ndat/tvlauncher/LauncherActivity.kt | 6 +- .../nl/ndat/tvlauncher/LauncherApplication.kt | 3 + .../data/receiver/PackageChangeReceiver.kt | 21 +++-- .../data/repository/AppRepository.kt | 5 ++ .../tvlauncher/data/resolver/AppResolver.kt | 1 + .../tvlauncher/service/AutoStartService.kt | 76 +++++++++++++++++++ .../ndat/tvlauncher/ui/tab/apps/AppPopup.kt | 17 ++++- .../nl/ndat/tvlauncher/ui/tab/apps/AppsTab.kt | 4 + .../ui/tab/apps/AppsTabViewModel.kt | 5 ++ .../ndat/tvlauncher/ui/tab/home/AppPopup.kt | 22 +++++- .../ui/tab/home/HomeTabViewModel.kt | 5 ++ .../tvlauncher/ui/tab/home/row/AppCardRow.kt | 4 + .../tvlauncher/ui/toolbar/ToolbarClock.kt | 6 +- app/src/main/sqldelight/migrations/1.sqm | 3 + .../nl/ndat/tvlauncher/data/sqldelight/App.sq | 26 ++++++- gradle.properties | 1 + 17 files changed, 190 insertions(+), 18 deletions(-) create mode 100644 app/src/main/kotlin/nl/ndat/tvlauncher/service/AutoStartService.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f3b153c4..81e6d609 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -4,6 +4,7 @@ plugins { alias(libs.plugins.kotlin.compose) alias(libs.plugins.sqldelight) alias(libs.plugins.kotlin.serialization) + id("com.google.devtools.ksp") version "2.2.10-1.0.13" } kotlin { @@ -60,4 +61,6 @@ dependencies { implementation(libs.androidx.tv.material) implementation(libs.coil.compose) debugImplementation(libs.androidx.compose.ui.tooling) + + ksp("androidx.room:room-compiler:2.6.1") } diff --git a/app/src/main/kotlin/nl/ndat/tvlauncher/LauncherActivity.kt b/app/src/main/kotlin/nl/ndat/tvlauncher/LauncherActivity.kt index ec2e46d7..21c0725e 100644 --- a/app/src/main/kotlin/nl/ndat/tvlauncher/LauncherActivity.kt +++ b/app/src/main/kotlin/nl/ndat/tvlauncher/LauncherActivity.kt @@ -18,9 +18,7 @@ import nl.ndat.tvlauncher.data.repository.ChannelRepository import nl.ndat.tvlauncher.data.repository.InputRepository import nl.ndat.tvlauncher.ui.AppBase import nl.ndat.tvlauncher.util.DefaultLauncherHelper -import org.koin.android.ext.android.getKoin import org.koin.android.ext.android.inject -import org.koin.compose.KoinContext @SuppressLint("RestrictedApi") val PERMISSION_READ_CHANNELS = TvContractCompat.PERMISSION_READ_TV_LISTINGS @@ -42,9 +40,7 @@ class LauncherActivity : ComponentActivity() { super.onCreate(savedInstanceState) setContent { - KoinContext(getKoin()) { - AppBase() - } + AppBase() } validateDefaultLauncher() diff --git a/app/src/main/kotlin/nl/ndat/tvlauncher/LauncherApplication.kt b/app/src/main/kotlin/nl/ndat/tvlauncher/LauncherApplication.kt index 01ec0672..5ee3b37b 100644 --- a/app/src/main/kotlin/nl/ndat/tvlauncher/LauncherApplication.kt +++ b/app/src/main/kotlin/nl/ndat/tvlauncher/LauncherApplication.kt @@ -11,6 +11,7 @@ import nl.ndat.tvlauncher.data.repository.InputRepository import nl.ndat.tvlauncher.data.resolver.AppResolver import nl.ndat.tvlauncher.data.resolver.ChannelResolver import nl.ndat.tvlauncher.data.resolver.InputResolver +import nl.ndat.tvlauncher.service.AutoStartService import nl.ndat.tvlauncher.ui.tab.apps.AppsTabViewModel import nl.ndat.tvlauncher.ui.tab.home.HomeTabViewModel import nl.ndat.tvlauncher.util.DefaultLauncherHelper @@ -34,6 +35,8 @@ private val launcherModule = module { single { InputRepository(get(), get(), get()) } single { InputResolver() } + single { AutoStartService() } + viewModel { HomeTabViewModel(get(), get()) } viewModel { AppsTabViewModel(get()) } } diff --git a/app/src/main/kotlin/nl/ndat/tvlauncher/data/receiver/PackageChangeReceiver.kt b/app/src/main/kotlin/nl/ndat/tvlauncher/data/receiver/PackageChangeReceiver.kt index a3541281..bac6fcbe 100644 --- a/app/src/main/kotlin/nl/ndat/tvlauncher/data/receiver/PackageChangeReceiver.kt +++ b/app/src/main/kotlin/nl/ndat/tvlauncher/data/receiver/PackageChangeReceiver.kt @@ -7,6 +7,7 @@ import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import nl.ndat.tvlauncher.data.repository.AppRepository +import nl.ndat.tvlauncher.service.AutoStartService import org.koin.core.component.KoinComponent import org.koin.core.component.inject @@ -21,6 +22,7 @@ class PackageChangeReceiver : BroadcastReceiver(), KoinComponent { } private val appRepository: AppRepository by inject() + private val autoStartService: AutoStartService by inject() override fun onReceive(context: Context, intent: Intent) { val pendingIntent = goAsync() @@ -28,13 +30,20 @@ class PackageChangeReceiver : BroadcastReceiver(), KoinComponent { @OptIn(DelicateCoroutinesApi::class) GlobalScope.launch { try { - val packageName = when { - intent.action in packageActions && intent.data?.scheme == "package" -> intent.data?.schemeSpecificPart - else -> null - } + when (intent.action) { + Intent.ACTION_BOOT_COMPLETED -> { + // 系统启动完成,启动自启动应用 + autoStartService.startAutoStartApps(context) + } + in packageActions -> { + val packageName = if (intent.data?.scheme == "package") { + intent.data?.schemeSpecificPart + } else null - if (packageName != null) appRepository.refreshApplication(packageName) - else appRepository.refreshAllApplications() + if (packageName != null) appRepository.refreshApplication(packageName) + else appRepository.refreshAllApplications() + } + } } finally { pendingIntent.finish() } diff --git a/app/src/main/kotlin/nl/ndat/tvlauncher/data/repository/AppRepository.kt b/app/src/main/kotlin/nl/ndat/tvlauncher/data/repository/AppRepository.kt index 3882e267..c444a5e1 100644 --- a/app/src/main/kotlin/nl/ndat/tvlauncher/data/repository/AppRepository.kt +++ b/app/src/main/kotlin/nl/ndat/tvlauncher/data/repository/AppRepository.kt @@ -52,9 +52,14 @@ class AppRepository( fun getApps() = database.apps.getAll().executeAsListFlow() fun getFavoriteApps() = database.apps.getAllFavorites(::App).executeAsListFlow() + fun getAutoStartApps() = database.apps.getAllAutoStartApps(::App).executeAsListFlow() suspend fun getByPackageName(packageName: String) = withContext(Dispatchers.IO) { database.apps.getByPackageName(packageName).awaitAsOneOrNull() } suspend fun favorite(id: String) = withContext(Dispatchers.IO) { database.apps.updateFavoriteAdd(id) } suspend fun unfavorite(id: String) = withContext(Dispatchers.IO) { database.apps.updateFavoriteRemove(id) } suspend fun updateFavoriteOrder(id: String, order: Int) = withContext(Dispatchers.IO) { database.apps.updateFavoriteOrder(id, order.toLong()) } + + suspend fun addAutoStart(id: String) = withContext(Dispatchers.IO) { database.apps.updateAutoStartAdd(id) } + suspend fun removeAutoStart(id: String) = withContext(Dispatchers.IO) { database.apps.updateAutoStartRemove(id) } + suspend fun updateAutoStartOrder(id: String, order: Int) = withContext(Dispatchers.IO) { database.apps.updateAutoStartOrder(id, order.toLong()) } } diff --git a/app/src/main/kotlin/nl/ndat/tvlauncher/data/resolver/AppResolver.kt b/app/src/main/kotlin/nl/ndat/tvlauncher/data/resolver/AppResolver.kt index 65ec19a8..9c54164a 100644 --- a/app/src/main/kotlin/nl/ndat/tvlauncher/data/resolver/AppResolver.kt +++ b/app/src/main/kotlin/nl/ndat/tvlauncher/data/resolver/AppResolver.kt @@ -65,5 +65,6 @@ class AppResolver { launchIntentUriLeanback = packageManager.getLeanbackLaunchIntentForPackage(activityInfo.packageName)?.toUri(0), favoriteOrder = null, + autoStartOrder = null, ) } diff --git a/app/src/main/kotlin/nl/ndat/tvlauncher/service/AutoStartService.kt b/app/src/main/kotlin/nl/ndat/tvlauncher/service/AutoStartService.kt new file mode 100644 index 00000000..e5f2fedd --- /dev/null +++ b/app/src/main/kotlin/nl/ndat/tvlauncher/service/AutoStartService.kt @@ -0,0 +1,76 @@ +package nl.ndat.tvlauncher.service + +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.util.Log +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import nl.ndat.tvlauncher.data.repository.AppRepository +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject + +class AutoStartService : KoinComponent { + companion object { + private const val TAG = "AutoStartService" + private const val STARTUP_DELAY_MS = 3000L // 3秒延迟启动 + private const val APP_START_INTERVAL_MS = 1000L // 应用间启动间隔1秒 + } + + private val appRepository: AppRepository by inject() + + @OptIn(DelicateCoroutinesApi::class) + fun startAutoStartApps(context: Context) { + Log.d(TAG, "开始启动自启动应用") + + GlobalScope.launch { + try { + // 等待系统完全启动 + delay(STARTUP_DELAY_MS) + + val autoStartApps = appRepository.getAutoStartApps().collect { apps -> + Log.d(TAG, "找到 ${apps.size} 个自启动应用") + + apps.forEachIndexed { index, app -> + try { + Log.d(TAG, "启动应用: ${app.displayName} (${app.packageName})") + + val intent = when { + app.launchIntentUriLeanback != null -> { + Intent.parseUri(app.launchIntentUriLeanback, 0) + } + app.launchIntentUriDefault != null -> { + Intent.parseUri(app.launchIntentUriDefault, 0) + } + else -> { + context.packageManager.getLaunchIntentForPackage(app.packageName) + } + } + + if (intent != null) { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + context.startActivity(intent) + Log.d(TAG, "成功启动应用: ${app.displayName}") + } else { + Log.w(TAG, "无法启动应用: ${app.displayName} - 没有找到启动Intent") + } + + // 应用间启动间隔 + if (index < apps.size - 1) { + delay(APP_START_INTERVAL_MS) + } + } catch (e: Exception) { + Log.e(TAG, "启动应用失败: ${app.displayName}", e) + } + } + } + } catch (e: Exception) { + Log.e(TAG, "自启动服务执行失败", e) + } + } + } +} + + diff --git a/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/apps/AppPopup.kt b/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/apps/AppPopup.kt index e91b79c4..861ad0ea 100644 --- a/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/apps/AppPopup.kt +++ b/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/apps/AppPopup.kt @@ -6,6 +6,8 @@ import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Favorite import androidx.compose.material.icons.filled.FavoriteBorder +import androidx.compose.material.icons.filled.PlayArrow +import androidx.compose.material.icons.outlined.PlayArrow import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -18,6 +20,8 @@ import androidx.tv.material3.IconButtonDefaults fun AppPopup( isFavorite: Boolean, onToggleFavorite: (favorite: Boolean) -> Unit, + isAutoStart: Boolean, + onToggleAutoStart: (autoStart: Boolean) -> Unit, ) { Row( horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterHorizontally), @@ -28,7 +32,18 @@ fun AppPopup( ) { Icon( imageVector = if (isFavorite) Icons.Default.Favorite else Icons.Default.FavoriteBorder, - contentDescription = null, + contentDescription = if (isFavorite) "取消收藏" else "添加到收藏", + modifier = Modifier.size(IconButtonDefaults.SmallIconSize) + ) + } + + IconButton( + modifier = Modifier.size(IconButtonDefaults.SmallButtonSize), + onClick = { onToggleAutoStart(!isAutoStart) } + ) { + Icon( + imageVector = if (isAutoStart) Icons.Default.PlayArrow else Icons.Outlined.PlayArrow, + contentDescription = if (isAutoStart) "取消开机自启动" else "设置开机自启动", modifier = Modifier.size(IconButtonDefaults.SmallIconSize) ) } diff --git a/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/apps/AppsTab.kt b/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/apps/AppsTab.kt index 80406c2a..e63d8e1b 100644 --- a/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/apps/AppsTab.kt +++ b/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/apps/AppsTab.kt @@ -52,6 +52,10 @@ fun AppsTab( isFavorite = app.favoriteOrder != null, onToggleFavorite = { favorite -> viewModel.favoriteApp(app, favorite) + }, + isAutoStart = app.autoStartOrder != null, + onToggleAutoStart = { autoStart -> + viewModel.toggleAutoStart(app, autoStart) } ) } diff --git a/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/apps/AppsTabViewModel.kt b/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/apps/AppsTabViewModel.kt index 9c9a4c46..629a8802 100644 --- a/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/apps/AppsTabViewModel.kt +++ b/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/apps/AppsTabViewModel.kt @@ -22,4 +22,9 @@ class AppsTabViewModel( if (favorite) appRepository.favorite(app.id) else appRepository.unfavorite(app.id) } + + fun toggleAutoStart(app: App, autoStart: Boolean) = viewModelScope.launch { + if (autoStart) appRepository.addAutoStart(app.id) + else appRepository.removeAutoStart(app.id) + } } diff --git a/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/home/AppPopup.kt b/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/home/AppPopup.kt index 70260e21..8c544526 100644 --- a/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/home/AppPopup.kt +++ b/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/home/AppPopup.kt @@ -8,6 +8,8 @@ import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight import androidx.compose.material.icons.filled.Favorite import androidx.compose.material.icons.filled.FavoriteBorder +import androidx.compose.material.icons.filled.PlayArrow +import androidx.compose.material.icons.outlined.PlayArrow import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -22,6 +24,8 @@ fun AppPopup( isLast: Boolean, isFavorite: Boolean, onToggleFavorite: (favorite: Boolean) -> Unit, + isAutoStart: Boolean, + onToggleAutoStart: (autoStart: Boolean) -> Unit, onMove: (relativePosition: Int) -> Unit, ) { Row( @@ -34,7 +38,7 @@ fun AppPopup( ) { Icon( imageVector = Icons.AutoMirrored.Default.KeyboardArrowLeft, - contentDescription = null, + contentDescription = "向左移动", modifier = Modifier.size(IconButtonDefaults.SmallIconSize) ) } @@ -45,7 +49,18 @@ fun AppPopup( ) { Icon( imageVector = if (isFavorite) Icons.Default.Favorite else Icons.Default.FavoriteBorder, - contentDescription = null, + contentDescription = if (isFavorite) "取消收藏" else "添加到收藏", + modifier = Modifier.size(IconButtonDefaults.SmallIconSize) + ) + } + + IconButton( + modifier = Modifier.size(IconButtonDefaults.SmallButtonSize), + onClick = { onToggleAutoStart(!isAutoStart) } + ) { + Icon( + imageVector = if (isAutoStart) Icons.Default.PlayArrow else Icons.Outlined.PlayArrow, + contentDescription = if (isAutoStart) "取消开机自启动" else "设置开机自启动", modifier = Modifier.size(IconButtonDefaults.SmallIconSize) ) } @@ -56,7 +71,8 @@ fun AppPopup( onClick = { onMove(+1) }, ) { Icon( - imageVector = Icons.AutoMirrored.Default.KeyboardArrowRight, contentDescription = null, + imageVector = Icons.AutoMirrored.Default.KeyboardArrowRight, + contentDescription = "向右移动", modifier = Modifier.size(IconButtonDefaults.SmallIconSize) ) } diff --git a/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/home/HomeTabViewModel.kt b/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/home/HomeTabViewModel.kt index dffd8f45..ce83b648 100644 --- a/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/home/HomeTabViewModel.kt +++ b/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/home/HomeTabViewModel.kt @@ -38,4 +38,9 @@ class HomeTabViewModel( if (app.favoriteOrder == null) appRepository.favorite(app.id) appRepository.updateFavoriteOrder(app.id, order) } + + fun toggleAutoStart(app: App, autoStart: Boolean) = viewModelScope.launch { + if (autoStart) appRepository.addAutoStart(app.id) + else appRepository.removeAutoStart(app.id) + } } diff --git a/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/home/row/AppCardRow.kt b/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/home/row/AppCardRow.kt index 14f8c246..e2e3b032 100644 --- a/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/home/row/AppCardRow.kt +++ b/app/src/main/kotlin/nl/ndat/tvlauncher/ui/tab/home/row/AppCardRow.kt @@ -45,6 +45,10 @@ fun AppCardRow( onToggleFavorite = { favorite -> viewModel.favoriteApp(app, favorite) }, + isAutoStart = app.autoStartOrder != null, + onToggleAutoStart = { autoStart -> + viewModel.toggleAutoStart(app, autoStart) + }, onMove = { relativePosition -> val newIndex = index + relativePosition viewModel.setFavoriteOrder(app, newIndex) diff --git a/app/src/main/kotlin/nl/ndat/tvlauncher/ui/toolbar/ToolbarClock.kt b/app/src/main/kotlin/nl/ndat/tvlauncher/ui/toolbar/ToolbarClock.kt index a4aad43b..d0f4be99 100644 --- a/app/src/main/kotlin/nl/ndat/tvlauncher/ui/toolbar/ToolbarClock.kt +++ b/app/src/main/kotlin/nl/ndat/tvlauncher/ui/toolbar/ToolbarClock.kt @@ -11,6 +11,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.sp import androidx.core.os.ConfigurationCompat @@ -21,8 +22,9 @@ import java.util.Calendar @Composable fun ToolbarClock() { val context = LocalContext.current - val pattern = remember(context) { - val locale = requireNotNull(ConfigurationCompat.getLocales(context.resources.configuration)[0]) + val configuration = LocalConfiguration.current + val pattern = remember(configuration) { + val locale = requireNotNull(ConfigurationCompat.getLocales(configuration)[0]) val is24HourFormat = DateFormat.is24HourFormat(context) val pattern = when { is24HourFormat -> "Hm" diff --git a/app/src/main/sqldelight/migrations/1.sqm b/app/src/main/sqldelight/migrations/1.sqm index 44203a90..a5b849d1 100644 --- a/app/src/main/sqldelight/migrations/1.sqm +++ b/app/src/main/sqldelight/migrations/1.sqm @@ -1,2 +1,5 @@ ALTER TABLE App ADD COLUMN favoriteOrder INTEGER; CREATE INDEX appFavoriteOrder ON App(favoriteOrder); + +ALTER TABLE App ADD COLUMN autoStartOrder INTEGER; +CREATE INDEX appAutoStartOrder ON App(autoStartOrder); diff --git a/app/src/main/sqldelight/nl/ndat/tvlauncher/data/sqldelight/App.sq b/app/src/main/sqldelight/nl/ndat/tvlauncher/data/sqldelight/App.sq index 4a13287d..f6850bd9 100644 --- a/app/src/main/sqldelight/nl/ndat/tvlauncher/data/sqldelight/App.sq +++ b/app/src/main/sqldelight/nl/ndat/tvlauncher/data/sqldelight/App.sq @@ -6,11 +6,13 @@ CREATE TABLE App ( launchIntentUriDefault TEXT, launchIntentUriLeanback TEXT, - favoriteOrder INTEGER + favoriteOrder INTEGER, + autoStartOrder INTEGER ); CREATE INDEX appPackageName ON App(packageName); CREATE INDEX appFavoriteOrder ON App(favoriteOrder); +CREATE INDEX appAutoStartOrder ON App(autoStartOrder); getAll: SELECT * FROM App ORDER BY displayName ASC; @@ -18,6 +20,9 @@ SELECT * FROM App ORDER BY displayName ASC; getAllFavorites: SELECT * FROM App WHERE favoriteOrder IS NOT NULL ORDER BY favoriteOrder ASC; +getAllAutoStartApps: +SELECT * FROM App WHERE autoStartOrder IS NOT NULL ORDER BY autoStartOrder ASC; + getById: SELECT * FROM App WHERE id = :id LIMIT 1; @@ -66,6 +71,25 @@ updateFavoriteOrder { UPDATE App SET favoriteOrder = :order WHERE id = :id; } +updateAutoStartAdd: +UPDATE App SET autoStartOrder = COALESCE((SELECT MAX(autoStartOrder) FROM App), -1) + 1 WHERE id = :id; + +updateAutoStartRemove { + -- Decrease the order for all items after this item + UPDATE App SET autoStartOrder = autoStartOrder - 1 WHERE autoStartOrder > (SELECT autoStartOrder FROM App WHERE id = :id) AND id != :id; + -- Update requested item + UPDATE App SET autoStartOrder = NULL WHERE id = :id; +} + +updateAutoStartOrder { + -- Decrease the order for all items after the old order + UPDATE App SET autoStartOrder = autoStartOrder - 1 WHERE autoStartOrder > (SELECT autoStartOrder FROM App WHERE id = :id) AND id != :id; + -- Increase the order for all items after the new order + UPDATE App SET autoStartOrder = autoStartOrder + 1 WHERE autoStartOrder >= :order AND id != :id; + -- Update requested item + UPDATE App SET autoStartOrder = :order WHERE id = :id; +} + removeById: DELETE FROM App WHERE id = :id; diff --git a/gradle.properties b/gradle.properties index 9fd447a2..7cf94ead 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,6 @@ # Gradle org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +org.gradle.jvmargs=-Dorg.sqlite.tmpdir=build/sqlite-tmp # Android android.useAndroidX=true From 4917dae9e3ef9f865ec142f8eed949e1d935686c Mon Sep 17 00:00:00 2001 From: yunnysunny Date: Thu, 11 Sep 2025 21:18:39 +0800 Subject: [PATCH 2/7] ci: trying to fix build error --- app/build.gradle.kts | 8 ++++++-- build.gradle.kts | 11 +++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 81e6d609..83698410 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -4,7 +4,7 @@ plugins { alias(libs.plugins.kotlin.compose) alias(libs.plugins.sqldelight) alias(libs.plugins.kotlin.serialization) - id("com.google.devtools.ksp") version "2.2.10-1.0.13" + id("com.google.devtools.ksp") } kotlin { @@ -62,5 +62,9 @@ dependencies { implementation(libs.coil.compose) debugImplementation(libs.androidx.compose.ui.tooling) - ksp("androidx.room:room-compiler:2.6.1") + // ✅ Room with KSP + val roomVersion = "2.6.1" + implementation("androidx.room:room-runtime:$roomVersion") + ksp("androidx.room:room-compiler:$roomVersion") + implementation("androidx.room:room-ktx:$roomVersion") } diff --git a/build.gradle.kts b/build.gradle.kts index e69de29b..18b07160 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -0,0 +1,11 @@ +plugins { + // Android Gradle Plugin + Kotlin 插件的版本 + alias(libs.plugins.android.app) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.kotlin.compose) apply false + alias(libs.plugins.kotlin.serialization) apply false + alias(libs.plugins.sqldelight) apply false + + // ✅ KSP must been defined here + id("com.google.devtools.ksp") version "2.2.10-1.0.13" apply false +} From b371bd48971064e15162c5db9944eafa7d08aaa7 Mon Sep 17 00:00:00 2001 From: yunnysunny Date: Fri, 12 Sep 2025 10:13:04 +0800 Subject: [PATCH 3/7] ci: change google repostity order --- settings.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index f0adf1c0..5d24a5e8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,9 +6,9 @@ include(":app") pluginManagement { repositories { + google() gradlePluginPortal() mavenCentral() - google() } } @@ -16,7 +16,7 @@ dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { - mavenCentral() google() + mavenCentral() } } From f3af5fea19632015757eaa0e9a3da332fe0e7955 Mon Sep 17 00:00:00 2001 From: yunnysunny Date: Fri, 12 Sep 2025 10:50:23 +0800 Subject: [PATCH 4/7] ci: down the ksp version to 2.2.0 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 18b07160..45f980c5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,5 +7,5 @@ plugins { alias(libs.plugins.sqldelight) apply false // ✅ KSP must been defined here - id("com.google.devtools.ksp") version "2.2.10-1.0.13" apply false + id("com.google.devtools.ksp") version "2.2.0-1.0.21" apply false } From 9b5e31a9532109fc223da610e072ebae9aed32dc Mon Sep 17 00:00:00 2001 From: yunnysunny Date: Fri, 12 Sep 2025 10:53:07 +0800 Subject: [PATCH 5/7] ci: change ksp to 2.2.10-2.0.2 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 45f980c5..71647a12 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,5 +7,5 @@ plugins { alias(libs.plugins.sqldelight) apply false // ✅ KSP must been defined here - id("com.google.devtools.ksp") version "2.2.0-1.0.21" apply false + id("com.google.devtools.ksp") version "2.2.10-2.0.2" apply false } From ef50fefd05b4b97a3cc217652c01d33d227f1fe2 Mon Sep 17 00:00:00 2001 From: yunnysunny Date: Fri, 12 Sep 2025 13:36:46 +0800 Subject: [PATCH 6/7] ci: bump ksp to latest --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 71647a12..391a1d45 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,5 +7,5 @@ plugins { alias(libs.plugins.sqldelight) apply false // ✅ KSP must been defined here - id("com.google.devtools.ksp") version "2.2.10-2.0.2" apply false + id("com.google.devtools.ksp") version "2.2.20-2.0.3" apply false } From 75f90b9659545d14453c36f93f53e59929297a7f Mon Sep 17 00:00:00 2001 From: yunnysunny Date: Fri, 12 Sep 2025 13:44:47 +0800 Subject: [PATCH 7/7] ci: add dependsOn config --- app/build.gradle.kts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 83698410..988b2de4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -68,3 +68,10 @@ dependencies { ksp("androidx.room:room-compiler:$roomVersion") implementation("androidx.room:room-ktx:$roomVersion") } + +tasks.named("kspDebugKotlin") { + dependsOn("generateDebugDatabaseInterface") +} +tasks.named("kspReleaseKotlin") { + dependsOn("generateReleaseDatabaseInterface") +}