feat: будильник с радиостанцией + выбор битрейта по умолчанию
Будильник (Settings → Будильник): несколько будильников, время, станция, дни недели, fade-in пробуждения. AlarmManager.setAlarmClock (вне doze) + фолбэк, BootReceiver перепланирует после перезагрузки, AlarmReceiver→PlayerService (foreground) → PlayerController.startAlarmPlayback (нарастание громкости). Room: AlarmEntity/Dao, БД v7. Выбор битрейта по умолчанию в Settings (Авто/Эконом/Стандарт/Высокое) → preferredBitrate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -4,10 +4,12 @@ import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.radiola.data.local.dao.AlarmDao
|
||||
import com.radiola.data.local.dao.RecordingDao
|
||||
import com.radiola.data.local.dao.StationDao
|
||||
import com.radiola.data.local.dao.TagDao
|
||||
import com.radiola.data.local.dao.TrackHistoryDao
|
||||
import com.radiola.data.local.entity.AlarmEntity
|
||||
import com.radiola.data.local.entity.RecordingEntity
|
||||
import com.radiola.data.local.entity.StationEntity
|
||||
import com.radiola.data.local.entity.TagEntity
|
||||
@@ -56,13 +58,34 @@ val MIGRATION_5_6 = object : Migration(5, 6) {
|
||||
}
|
||||
}
|
||||
|
||||
// Добавляем таблицу будильников
|
||||
val MIGRATION_6_7 = object : Migration(6, 7) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS alarms (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
hour INTEGER NOT NULL,
|
||||
minute INTEGER NOT NULL,
|
||||
daysMask INTEGER NOT NULL,
|
||||
stationId INTEGER NOT NULL,
|
||||
stationName TEXT NOT NULL,
|
||||
enabled INTEGER NOT NULL,
|
||||
fadeInSec INTEGER NOT NULL
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Database(
|
||||
entities = [StationEntity::class, TrackHistoryEntity::class, TagEntity::class, RecordingEntity::class],
|
||||
version = 6
|
||||
entities = [StationEntity::class, TrackHistoryEntity::class, TagEntity::class, RecordingEntity::class, AlarmEntity::class],
|
||||
version = 7
|
||||
)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun stationDao(): StationDao
|
||||
abstract fun trackHistoryDao(): TrackHistoryDao
|
||||
abstract fun tagDao(): TagDao
|
||||
abstract fun recordingDao(): RecordingDao
|
||||
abstract fun alarmDao(): AlarmDao
|
||||
}
|
||||
|
||||
30
app/src/main/java/com/radiola/data/local/dao/AlarmDao.kt
Normal file
30
app/src/main/java/com/radiola/data/local/dao/AlarmDao.kt
Normal file
@@ -0,0 +1,30 @@
|
||||
package com.radiola.data.local.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.radiola.data.local.entity.AlarmEntity
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface AlarmDao {
|
||||
|
||||
@Query("SELECT * FROM alarms ORDER BY hour ASC, minute ASC")
|
||||
fun getAll(): Flow<List<AlarmEntity>>
|
||||
|
||||
@Query("SELECT * FROM alarms ORDER BY hour ASC, minute ASC")
|
||||
suspend fun getAllOnce(): List<AlarmEntity>
|
||||
|
||||
@Query("SELECT * FROM alarms WHERE id = :id")
|
||||
suspend fun getById(id: Int): AlarmEntity?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun upsert(alarm: AlarmEntity): Long
|
||||
|
||||
@Query("DELETE FROM alarms WHERE id = :id")
|
||||
suspend fun delete(id: Int)
|
||||
|
||||
@Query("UPDATE alarms SET enabled = :enabled WHERE id = :id")
|
||||
suspend fun setEnabled(id: Int, enabled: Boolean)
|
||||
}
|
||||
@@ -42,4 +42,8 @@ interface StationDao {
|
||||
// не потерять отметки «избранное» (insertAll = REPLACE затирает строки).
|
||||
@Query("SELECT id FROM stations WHERE isFavorite = 1")
|
||||
suspend fun getFavoriteIdsOnce(): List<Int>
|
||||
|
||||
// Разовое чтение станции по id — используется в сервисе будильника.
|
||||
@Query("SELECT * FROM stations WHERE id = :id")
|
||||
suspend fun getByIdOnce(id: Int): StationEntity?
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.radiola.data.local.entity
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
/**
|
||||
* Будильник: время, дни недели, станция, fade-in.
|
||||
* daysMask — битовая маска Пн..Вс (биты 0..6); 0 = разовый (следующее совпадение).
|
||||
*/
|
||||
@Entity(tableName = "alarms")
|
||||
data class AlarmEntity(
|
||||
@PrimaryKey(autoGenerate = true) val id: Int = 0,
|
||||
val hour: Int,
|
||||
val minute: Int,
|
||||
val daysMask: Int, // 0 = разовый; бит 0=Пн, ..., бит 6=Вс
|
||||
val stationId: Int,
|
||||
val stationName: String,
|
||||
val enabled: Boolean = true,
|
||||
val fadeInSec: Int = 60
|
||||
)
|
||||
Reference in New Issue
Block a user