FreshRSSApplication.kt 3.86 KB
Newer Older
1 2 3
package fr.chenry.android.freshrss

import android.app.Application
Christophe Henry's avatar
Christophe Henry committed
4
import android.content.*
5 6
import android.os.Handler
import android.os.IBinder
Christophe Henry's avatar
Christophe Henry committed
7
import androidx.core.app.NotificationManagerCompat
8
import androidx.core.os.postDelayed
9 10
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
Christophe Henry's avatar
Christophe Henry committed
11
import androidx.room.Room
12
import fr.chenry.android.freshrss.RefresherService.RefresherBinder
13
import fr.chenry.android.freshrss.store.Store
14
import fr.chenry.android.freshrss.store.database.FreshRSSDabatabase
Christophe Henry's avatar
Christophe Henry committed
15
import fr.chenry.android.freshrss.store.database.FreshRSSDabatabase_Migrations
16
import fr.chenry.android.freshrss.utils.Try
17
import fr.chenry.android.freshrss.utils.whenNotNull
18 19
import nl.komponents.kovenant.android.startKovenant
import nl.komponents.kovenant.android.stopKovenant
Christophe Henry's avatar
Christophe Henry committed
20
import nl.komponents.kovenant.deferred
21
import java.util.Properties
22

Christophe Henry's avatar
Christophe Henry committed
23
class FreshRSSApplication : Application() {
24
    private val refreshDelay: Long get() = 30
25
    private val _refresherService = MutableLiveData<RefresherService>()
Christophe Henry's avatar
Christophe Henry committed
26 27
    private val serviceConnection = RefresherServiceConnection()

28
    val refresherService: LiveData<RefresherService> get() = _refresherService
29

Christophe Henry's avatar
Christophe Henry committed
30 31 32 33 34 35
    val database by lazy {
        val dbName = "${context.getString(R.string.app_name).toLowerCase()}.db"
        Room.databaseBuilder(context, FreshRSSDabatabase::class.java, dbName)
            .addMigrations(*FreshRSSDabatabase_Migrations.build())
            .build()
    }
36

37 38
    override fun onCreate() {
        super.onCreate()
39
        startKovenant()
Christophe Henry's avatar
Christophe Henry committed
40 41
        // Stupid hack because Android is still not able to provide the current
        // application globally even though it's an actual a singleton...
Christophe Henry's avatar
Christophe Henry committed
42
        FreshRSSApplication.applicationPromise.resolve(this)
43 44 45

        bindService(Intent(this, RefresherService::class.java), serviceConnection, Context.BIND_AUTO_CREATE)

46
        Store.debugMode = Try {
47 48 49
            val properties = Properties()
            properties.load(baseContext.assets.open("config.properties"))
            properties.getProperty("debug", "false")!!.toBoolean()
50
        }.getOrDefault(false)
Christophe Henry's avatar
Christophe Henry committed
51

52
        // Debug
Christophe Henry's avatar
Christophe Henry committed
53
        // Stetho.initializeWithDefaults(this)
54 55 56 57 58 59
    }

    override fun onTerminate() {
        super.onTerminate()
        stopKovenant()
    }
Christophe Henry's avatar
Christophe Henry committed
60 61

    companion object {
Christophe Henry's avatar
Christophe Henry committed
62
        private val applicationPromise = deferred<FreshRSSApplication, Throwable>()
Christophe Henry's avatar
Christophe Henry committed
63 64
        val application: FreshRSSApplication get() = applicationPromise.promise.get()
        val database get() = application.database
Christophe Henry's avatar
Christophe Henry committed
65
        val context: Context get() = application.applicationContext
Christophe Henry's avatar
Christophe Henry committed
66
        val notificationManager: NotificationManagerCompat
67
            get() = NotificationManagerCompat.from(application)
68
        val stateSharedPreferences: SharedPreferences
Christophe Henry's avatar
Christophe Henry committed
69
            get() = context.getSharedPreferences("STATE", Context.MODE_PRIVATE)
70

Christophe Henry's avatar
Christophe Henry committed
71
        fun getStringR(id: Int, vararg formatArgs: Any = arrayOf()) = if (formatArgs.isEmpty())
72 73
            application.resources.getString(id) else
            application.resources.getString(id, *formatArgs)
74 75
    }

Christophe Henry's avatar
Christophe Henry committed
76
    inner class RefresherServiceConnection : ServiceConnection {
77
        private val handler = Handler()
78
        private val token = object {}
79 80 81

        override fun onServiceDisconnected(name: ComponentName?) {
            handler.removeCallbacksAndMessages(token)
82
            _refresherService.value = null
83 84 85
        }

        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
86 87 88 89
            (service as RefresherBinder).service.let {
                _refresherService.value = it
                postDelayedRefesh()
            }
90 91 92 93
        }

        private fun postDelayedRefesh() {
            handler.postDelayed(this@FreshRSSApplication.refreshDelay * 60 * 1000, token) {
94
                this@FreshRSSApplication.refresherService.value.whenNotNull {
Christophe Henry's avatar
Christophe Henry committed
95
                    it.refresh(false)
96 97 98 99
                    postDelayedRefesh()
                }
            }
        }
Christophe Henry's avatar
Christophe Henry committed
100
    }
Christophe Henry's avatar
Christophe Henry committed
101
}