Replace Realm with Room.

This commit is contained in:
azuo 2021-09-23 00:23:42 +08:00
parent 183901534c
commit 5d9dcd9701
7 changed files with 106 additions and 85 deletions

View File

@ -7,8 +7,6 @@ apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: 'realm-android'
def apikeyPropertiesFile = rootProject.file("apikey.properties") def apikeyPropertiesFile = rootProject.file("apikey.properties")
def apikeyProperties = new Properties() def apikeyProperties = new Properties()
apikeyProperties.load(new FileInputStream(apikeyPropertiesFile)) apikeyProperties.load(new FileInputStream(apikeyPropertiesFile))
@ -88,6 +86,10 @@ dependencies {
// EventBus // EventBus
implementation 'org.greenrobot:eventbus:3.2.0' implementation 'org.greenrobot:eventbus:3.2.0'
// Room
implementation "androidx.room:room-runtime:2.3.0"
kapt "androidx.room:room-compiler:2.3.0"
// Navigation // Navigation
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'

View File

@ -7,10 +7,6 @@ import androidx.appcompat.app.AppCompatDelegate
import com.chibatching.kotpref.Kotpref import com.chibatching.kotpref.Kotpref
import com.google.firebase.crashlytics.FirebaseCrashlytics import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import io.realm.Realm
import io.realm.RealmConfiguration
import net.danlew.android.joda.JodaTimeAndroid
class AWApplication : Application() { class AWApplication : Application() {
override fun onCreate() { override fun onCreate() {
@ -24,12 +20,5 @@ class AWApplication : Application() {
// Dark theme // Dark theme
AppCompatDelegate.setDefaultNightMode(Preferences.darkThemePreference) AppCompatDelegate.setDefaultNightMode(Preferences.darkThemePreference)
// Realm
Realm.init(this)
val config = RealmConfiguration.Builder()
.deleteRealmIfMigrationNeeded()
.build()
Realm.setDefaultConfiguration(config)
} }
} }

View File

@ -3,32 +3,37 @@ package com.tommasoberlose.anotherwidget.db
import android.content.Context import android.content.Context
import android.provider.CalendarContract import android.provider.CalendarContract
import android.util.Log import android.util.Log
import androidx.room.Dao
import androidx.room.Database
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Room
import androidx.room.RoomDatabase
import com.chibatching.kotpref.bulk import com.chibatching.kotpref.bulk
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper.applyFilters import com.tommasoberlose.anotherwidget.helpers.CalendarHelper.applyFilters
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper.sortEvents
import com.tommasoberlose.anotherwidget.models.Event import com.tommasoberlose.anotherwidget.models.Event
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import io.realm.Realm
import io.realm.RealmResults
import java.util.* import java.util.*
import kotlin.Comparator import kotlin.Comparator
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
class EventRepository(val context: Context) { class EventRepository(val context: Context) {
private val realm by lazy { Realm.getDefaultInstance() } private val db by lazy { EventDatabase.getDatabase(context) }
fun saveEvents(eventList: List<Event>) { fun saveEvents(eventList: List<Event>) {
realm.executeTransaction { realm -> db.runInTransaction{
realm.where(Event::class.java).findAll().deleteAllFromRealm() db.dao().run {
realm.copyToRealm(eventList) deleteAll()
insertAll(eventList)
}
} }
} }
fun clearEvents() { fun clearEvents() {
realm.executeTransaction { realm -> db.dao().deleteAll()
realm.where(Event::class.java).findAll().deleteAllFromRealm()
}
} }
fun resetNextEventData() { fun resetNextEventData() {
@ -44,11 +49,11 @@ class EventRepository(val context: Context) {
} }
fun saveNextEventData(event: Event) { fun saveNextEventData(event: Event) {
Preferences.nextEventId = event.eventID Preferences.nextEventId = event.id
} }
fun getNextEvent(): Event? { fun getNextEvent(): Event? {
val nextEvent = getEventByEventId(Preferences.nextEventId) val nextEvent = getEventById(Preferences.nextEventId)
val now = Calendar.getInstance().timeInMillis val now = Calendar.getInstance().timeInMillis
val limit = Calendar.getInstance().apply { val limit = Calendar.getInstance().apply {
timeInMillis = now timeInMillis = now
@ -64,43 +69,33 @@ class EventRepository(val context: Context) {
else -> add(Calendar.HOUR, 6) else -> add(Calendar.HOUR, 6)
} }
} }
val event = if (nextEvent != null && nextEvent.endDate > now && nextEvent.startDate <= limit.timeInMillis) { return if (nextEvent != null && nextEvent.endDate > now && nextEvent.startDate <= limit.timeInMillis) {
nextEvent nextEvent
} else { } else {
val events = getEvents() val events = getEvents()
if (events.isNotEmpty()) { if (events.isNotEmpty()) {
val newNextEvent = events.first() val newNextEvent = events.first()
Preferences.nextEventId = newNextEvent.eventID Preferences.nextEventId = newNextEvent.id
newNextEvent newNextEvent
} else { } else {
resetNextEventData() resetNextEventData()
null null
} }
} }
return try {
realm.copyFromRealm(event!!)
} catch (ex: Exception) {
event
}
} }
fun getEventByEventId(id: Long): Event? { fun getEventById(id: Long): Event? {
val event = realm.where(Event::class.java).equalTo("eventID", id).findFirst() return db.dao().findById(id)
return try {
realm.copyFromRealm(event!!)
} catch (ex: Exception) {
event
}
} }
fun goToNextEvent() { fun goToNextEvent() {
val eventList = getEvents() val eventList = getEvents()
if (eventList.isNotEmpty()) { if (eventList.isNotEmpty()) {
val index = eventList.indexOfFirst { it.eventID == Preferences.nextEventId } val index = eventList.indexOfFirst { it.id == Preferences.nextEventId }
if (index > -1 && index < eventList.size - 1) { if (index > -1 && index < eventList.size - 1) {
Preferences.nextEventId = eventList[index + 1].eventID Preferences.nextEventId = eventList[index + 1].id
} else { } else {
Preferences.nextEventId = eventList.first().eventID Preferences.nextEventId = eventList.first().id
} }
} else { } else {
resetNextEventData() resetNextEventData()
@ -114,11 +109,11 @@ class EventRepository(val context: Context) {
fun goToPreviousEvent() { fun goToPreviousEvent() {
val eventList = getEvents() val eventList = getEvents()
if (eventList.isNotEmpty()) { if (eventList.isNotEmpty()) {
val index = eventList.indexOfFirst { it.eventID == Preferences.nextEventId } val index = eventList.indexOfFirst { it.id == Preferences.nextEventId }
if (index > 0) { if (index > 0) {
Preferences.nextEventId = eventList[index - 1].eventID Preferences.nextEventId = eventList[index - 1].id
} else { } else {
Preferences.nextEventId = eventList.last().eventID Preferences.nextEventId = eventList.last().id
} }
} else { } else {
resetNextEventData() resetNextEventData()
@ -130,13 +125,7 @@ class EventRepository(val context: Context) {
} }
fun getFutureEvents(): List<Event> { fun getFutureEvents(): List<Event> {
val now = Calendar.getInstance().timeInMillis return db.dao().findFuture(Calendar.getInstance().timeInMillis).applyFilters().sortEvents()
realm.refresh()
return realm
.where(Event::class.java)
.greaterThan("endDate", now)
.findAll()
.applyFilters()
} }
private fun getEvents(): List<Event> { private fun getEvents(): List<Event> {
@ -155,18 +144,54 @@ class EventRepository(val context: Context) {
else -> add(Calendar.HOUR, 6) else -> add(Calendar.HOUR, 6)
} }
} }
realm.refresh() return db.dao().find(now, limit.timeInMillis).applyFilters().sortEvents()
return realm
.where(Event::class.java)
.greaterThan("endDate", now)
.lessThanOrEqualTo("startDate", limit.timeInMillis)
.findAll()
.applyFilters()
} }
fun getEventsCount(): Int = getEvents().size fun getEventsCount(): Int = getEvents().size
fun close() { fun close() {
realm.close() // db.close()
} }
}
@Dao
interface EventDao {
@Query("SELECT * FROM events WHERE id = :id LIMIT 1")
fun findById(id: Long) : Event?
@Query("SELECT * FROM events WHERE end_date > :from")
fun findFuture(from: Long) : List<Event>
@Query("SELECT * FROM events WHERE end_date > :from and start_date <= :to")
fun find(from: Long, to: Long) : List<Event>
@Insert
fun insertAll(events: List<Event>)
@Query("DELETE FROM events")
fun deleteAll()
}
@Database(entities = arrayOf(Event::class), version = 1, exportSchema = false)
abstract class EventDatabase : RoomDatabase() {
abstract fun dao(): EventDao
companion object {
private var INSTANCE: EventDatabase? = null
fun getDatabase(context: Context): EventDatabase {
// if the INSTANCE is not null, then return it,
// if it is, then create the database
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
EventDatabase::class.java,
"events"
).allowMainThreadQueries().build()
INSTANCE = instance
// return instance
instance
}
}
}
}
}

View File

@ -1,26 +1,35 @@
package com.tommasoberlose.anotherwidget.models package com.tommasoberlose.anotherwidget.models
import android.provider.CalendarContract import android.provider.CalendarContract
import io.realm.RealmObject import androidx.room.ColumnInfo
import java.util.Date import androidx.room.Entity
import androidx.room.PrimaryKey
/** /**
* Created by tommaso on 05/10/17. * Created by tommaso on 05/10/17.
*/ */
open class Event( @Entity(tableName = "events")
var id: Long = 0, data class Event(
var eventID: Long = 0, @PrimaryKey
var title: String = "", val id: Long = 0,
var startDate: Long = 0, @ColumnInfo(name = "event_id")
var endDate: Long = 0, val eventID: Long = 0,
var calendarID: Int = 0, val title: String = "",
var allDay: Boolean = false, @ColumnInfo(name = "start_date")
var address: String = "", val startDate: Long = 0,
var selfAttendeeStatus: Int = CalendarContract.Attendees.ATTENDEE_STATUS_NONE, @ColumnInfo(name = "end_date")
var availability: Int = CalendarContract.EventsEntity.AVAILABILITY_BUSY val endDate: Long = 0,
) : RealmObject() { @ColumnInfo(name = "calendar_id")
val calendarID: Long = 0,
@ColumnInfo(name = "all_day")
val allDay: Boolean = false,
val address: String = "",
@ColumnInfo(name = "self_attendee_status")
val selfAttendeeStatus: Int = CalendarContract.Attendees.ATTENDEE_STATUS_NONE,
val availability: Int = CalendarContract.EventsEntity.AVAILABILITY_BUSY
)/* {
override fun toString(): String { override fun toString(): String {
return "Event:\nEVENT ID: " + eventID + "\nTITLE: " + title + "\nSTART DATE: " + Date(startDate) + "\nEND DATE: " + Date(endDate) + "\nCAL ID: " + calendarID + "\nADDRESS: " + address return "Event:\nEVENT ID: " + eventID + "\nTITLE: " + title + "\nSTART DATE: " + Date(startDate) + "\nEND DATE: " + Date(endDate) + "\nCAL ID: " + calendarID + "\nADDRESS: " + address
} }
} }*/

View File

@ -95,7 +95,7 @@ class UpdatesReceiver : BroadcastReceiver() {
setEventUpdate(context, event) setEventUpdate(context, event)
} }
} else { } else {
val event = eventRepository.getEventByEventId(eventId) val event = eventRepository.getEventById(eventId)
if (event != null) { if (event != null) {
setEventUpdate(context, event) setEventUpdate(context, event)
} }
@ -166,11 +166,11 @@ class UpdatesReceiver : BroadcastReceiver() {
fireTime.coerceAtLeast(now.timeInMillis + 1000 * 60), fireTime.coerceAtLeast(now.timeInMillis + 1000 * 60),
PendingIntent.getBroadcast( PendingIntent.getBroadcast(
context, context,
event.eventID.toInt(), event.id.toInt(),
Intent(context, UpdatesReceiver::class.java).apply { Intent(context, UpdatesReceiver::class.java).apply {
action = Actions.ACTION_TIME_UPDATE action = Actions.ACTION_TIME_UPDATE
if (event.startDate > now.timeInMillis) if (event.startDate > now.timeInMillis)
putExtra(EVENT_ID, event.eventID) putExtra(EVENT_ID, event.id)
}, },
PendingIntent.FLAG_UPDATE_CURRENT PendingIntent.FLAG_UPDATE_CURRENT
) )
@ -185,7 +185,7 @@ class UpdatesReceiver : BroadcastReceiver() {
}, 0)) }, 0))
val eventRepository = EventRepository(context) val eventRepository = EventRepository(context)
eventRepository.getFutureEvents().forEach { eventRepository.getFutureEvents().forEach {
cancel(PendingIntent.getBroadcast(context, it.eventID.toInt(), Intent(context, UpdatesReceiver::class.java).apply { cancel(PendingIntent.getBroadcast(context, it.id.toInt(), Intent(context, UpdatesReceiver::class.java).apply {
action = Actions.ACTION_TIME_UPDATE action = Actions.ACTION_TIME_UPDATE
}, 0)) }, 0))
} }

View File

@ -143,7 +143,7 @@ class UpdateCalendarService : Service() {
title = e.title ?: "", title = e.title ?: "",
startDate = instance.begin, startDate = instance.begin,
endDate = instance.end, endDate = instance.end,
calendarID = e.calendarId.toInt(), calendarID = e.calendarId,
allDay = e.allDay, allDay = e.allDay,
address = e.eventLocation ?: "", address = e.eventLocation ?: "",
selfAttendeeStatus = e.selfAttendeeStatus.toInt(), selfAttendeeStatus = e.selfAttendeeStatus.toInt(),

View File

@ -7,7 +7,6 @@ buildscript {
jcenter() jcenter()
maven { url 'https://jitpack.io' } maven { url 'https://jitpack.io' }
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.2.0' classpath 'com.android.tools.build:gradle:4.2.0'
@ -17,8 +16,6 @@ buildscript {
// Add the Crashlytics Gradle plugin. // Add the Crashlytics Gradle plugin.
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.5.2' classpath 'com.google.firebase:firebase-crashlytics-gradle:2.5.2'
classpath 'io.realm:realm-gradle-plugin:10.4.0'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
} }
@ -30,7 +27,6 @@ allprojects {
jcenter() jcenter()
maven { url 'https://jitpack.io' } maven { url 'https://jitpack.io' }
mavenCentral() mavenCentral()
} }
} }