add background grades updates with notify on changed grades
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
95ce9e14bd
commit
a3102bc3f2
|
@ -11,8 +11,8 @@ android {
|
||||||
applicationId "org.mosad.seil0.projectlaogai"
|
applicationId "org.mosad.seil0.projectlaogai"
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 6000 // 0006000
|
versionCode 6090 // 0006000
|
||||||
versionName "0.6.0"
|
versionName "0.6.1-beta1"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
resValue "string", "build_time", buildTime()
|
resValue "string", "build_time", buildTime()
|
||||||
setProperty("archivesBaseName", "projectlaogai-$versionName")
|
setProperty("archivesBaseName", "projectlaogai-$versionName")
|
||||||
|
@ -31,6 +31,10 @@ android {
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
res.srcDirs =
|
res.srcDirs =
|
||||||
|
@ -63,6 +67,8 @@ dependencies {
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
|
||||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||||
implementation 'androidx.security:security-crypto:1.1.0-alpha02'
|
implementation 'androidx.security:security-crypto:1.1.0-alpha02'
|
||||||
|
implementation 'androidx.work:work-runtime:2.4.0'
|
||||||
|
implementation "androidx.work:work-runtime-ktx:2.4.0"
|
||||||
implementation 'com.google.android.material:material:1.2.0'
|
implementation 'com.google.android.material:material:1.2.0'
|
||||||
implementation 'com.google.code.gson:gson:2.8.6'
|
implementation 'com.google.code.gson:gson:2.8.6'
|
||||||
implementation 'com.afollestad:aesthetic:1.0.0-beta05'
|
implementation 'com.afollestad:aesthetic:1.0.0-beta05'
|
||||||
|
|
|
@ -51,6 +51,7 @@ import org.mosad.seil0.projectlaogai.controller.preferences.Preferences
|
||||||
import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.cColorAccent
|
import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.cColorAccent
|
||||||
import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.cColorPrimary
|
import org.mosad.seil0.projectlaogai.controller.preferences.Preferences.cColorPrimary
|
||||||
import org.mosad.seil0.projectlaogai.fragments.*
|
import org.mosad.seil0.projectlaogai.fragments.*
|
||||||
|
import org.mosad.seil0.projectlaogai.util.NotificationUtils
|
||||||
import kotlin.system.measureTimeMillis
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -179,6 +180,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
|
||||||
Preferences.load(this) // load the settings, must be finished before doing anything else
|
Preferences.load(this) // load the settings, must be finished before doing anything else
|
||||||
CacheController(this) // load the cache
|
CacheController(this) // load the cache
|
||||||
EncryptedPreferences.load(this)
|
EncryptedPreferences.load(this)
|
||||||
|
NotificationUtils(this)
|
||||||
}
|
}
|
||||||
Log.i(className, "startup completed in $startupTime ms")
|
Log.i(className, "startup completed in $startupTime ms")
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,14 +22,21 @@
|
||||||
|
|
||||||
package org.mosad.seil0.projectlaogai.controller
|
package org.mosad.seil0.projectlaogai.controller
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
|
import androidx.work.PeriodicWorkRequestBuilder
|
||||||
|
import androidx.work.WorkManager
|
||||||
|
import org.mosad.seil0.projectlaogai.controller.preferences.Preferences
|
||||||
import org.mosad.seil0.projectlaogai.util.GradeSubject
|
import org.mosad.seil0.projectlaogai.util.GradeSubject
|
||||||
|
import org.mosad.seil0.projectlaogai.worker.GradesUpdateWorker
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class GradesController {
|
class GradesController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* show the difference between 2 grades sets
|
* show the difference between 2 grades sets
|
||||||
*/
|
*/
|
||||||
fun diffGrades(origMap: HashMap<String, ArrayList<GradeSubject>>, diffMap: HashMap<String, ArrayList<GradeSubject>>): ArrayList<GradeSubject> {
|
fun diffGrades(origMap: Map<String, ArrayList<GradeSubject>>, diffMap: Map<String, ArrayList<GradeSubject>>): ArrayList<GradeSubject> {
|
||||||
val diff = ArrayList<GradeSubject>()
|
val diff = ArrayList<GradeSubject>()
|
||||||
|
|
||||||
diffMap.values.forEach { semester ->
|
diffMap.values.forEach { semester ->
|
||||||
|
@ -54,6 +61,39 @@ class GradesController {
|
||||||
return diff
|
return diff
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stop the grades background sync, if the sync interval is greater than 0
|
||||||
|
* start it again with the new interval
|
||||||
|
*/
|
||||||
|
fun updateBackgroundSync(context: Context) {
|
||||||
|
stopBackgroundSync(context)
|
||||||
|
|
||||||
|
// if interval is not 0, start background Sync
|
||||||
|
if (Preferences.gradesSyncInterval > 0)
|
||||||
|
startBackgroundSync(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* start a new periodic worker GradesUpdateWorker
|
||||||
|
*/
|
||||||
|
fun startBackgroundSync(context: Context) {
|
||||||
|
val work = PeriodicWorkRequestBuilder<GradesUpdateWorker>(
|
||||||
|
Preferences.gradesSyncInterval.toLong(),
|
||||||
|
TimeUnit.HOURS
|
||||||
|
).build()
|
||||||
|
|
||||||
|
val workManager = WorkManager.getInstance(context)
|
||||||
|
workManager.enqueueUniquePeriodicWork("GradesUpdateWorker", ExistingPeriodicWorkPolicy.REPLACE, work)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cancel GradesUpdateWorker
|
||||||
|
*/
|
||||||
|
fun stopBackgroundSync(context: Context) {
|
||||||
|
WorkManager.getInstance(context).cancelUniqueWork("GradesUpdateWorker")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -215,8 +215,6 @@ class CacheController(cont: Context) {
|
||||||
|
|
||||||
return GlobalScope.launch(Dispatchers.IO) {
|
return GlobalScope.launch(Dispatchers.IO) {
|
||||||
if (parser.checkQISPOSStatus() == 200) {
|
if (parser.checkQISPOSStatus() == 200) {
|
||||||
if (file.exists()) { file.delete() }
|
|
||||||
|
|
||||||
// save cache file and update time
|
// save cache file and update time
|
||||||
saveEncrypted(context, file, Gson().toJson(parser.parseGrades()))
|
saveEncrypted(context, file, Gson().toJson(parser.parseGrades()))
|
||||||
gradesCacheTime = System.currentTimeMillis() / 1000
|
gradesCacheTime = System.currentTimeMillis() / 1000
|
||||||
|
@ -258,10 +256,15 @@ class CacheController(cont: Context) {
|
||||||
EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
|
EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
|
||||||
).build()
|
).build()
|
||||||
|
|
||||||
|
// only write one file at a time
|
||||||
|
synchronized(this) {
|
||||||
|
if (file.exists()) { file.delete() }
|
||||||
|
|
||||||
encryptedFile.openFileOutput().bufferedWriter().use {
|
encryptedFile.openFileOutput().bufferedWriter().use {
|
||||||
it.write(text)
|
it.write(text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ object Preferences {
|
||||||
var gradesCacheTime: Long = 0
|
var gradesCacheTime: Long = 0
|
||||||
var cColorPrimary: Int = Color.parseColor("#009688")
|
var cColorPrimary: Int = Color.parseColor("#009688")
|
||||||
var cColorAccent: Int = Color.parseColor("#0096ff")
|
var cColorAccent: Int = Color.parseColor("#0096ff")
|
||||||
|
var gradesSyncInterval = 0
|
||||||
var cCourse = Course(
|
var cCourse = Course(
|
||||||
"https://www.hs-offenburg.de/index.php?id=6627&class=class&iddV=DA64F6FE-9DDB-429E-A677-05D0D40CB636&week=0",
|
"https://www.hs-offenburg.de/index.php?id=6627&class=class&iddV=DA64F6FE-9DDB-429E-A677-05D0D40CB636&week=0",
|
||||||
"AI3"
|
"AI3"
|
||||||
|
@ -132,6 +133,22 @@ object Preferences {
|
||||||
cColorAccent = colorAccent
|
cColorAccent = colorAccent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun saveGradesSync(context: Context, interval: Int) {
|
||||||
|
val sharedPref = context.getSharedPreferences(
|
||||||
|
context.getString(R.string.preference_file_key),
|
||||||
|
Context.MODE_PRIVATE
|
||||||
|
)
|
||||||
|
|
||||||
|
with (sharedPref.edit()) {
|
||||||
|
putInt(context.getString(R.string.save_key_gradesSyncInterval),
|
||||||
|
interval
|
||||||
|
)
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
gradesSyncInterval = interval
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* save showBuffet
|
* save showBuffet
|
||||||
*/
|
*/
|
||||||
|
@ -161,18 +178,18 @@ object Preferences {
|
||||||
)
|
)
|
||||||
|
|
||||||
// load the update times (cache)
|
// load the update times (cache)
|
||||||
coursesCacheTime = sharedPref.getLong(context.getString(
|
coursesCacheTime = sharedPref.getLong(
|
||||||
R.string.save_key_coursesCacheTime
|
context.getString(R.string.save_key_coursesCacheTime),0
|
||||||
), 0)
|
)
|
||||||
mensaCacheTime = sharedPref.getLong(context.getString(
|
mensaCacheTime = sharedPref.getLong(
|
||||||
R.string.save_key_mensaCacheTime
|
context.getString(R.string.save_key_mensaCacheTime),0
|
||||||
), 0)
|
)
|
||||||
timetableCacheTime = sharedPref.getLong(context.getString(
|
timetableCacheTime = sharedPref.getLong(
|
||||||
R.string.save_key_timetableCacheTime
|
context.getString(R.string.save_key_timetableCacheTime),0
|
||||||
), 0)
|
)
|
||||||
gradesCacheTime = sharedPref.getLong(context.getString(
|
gradesCacheTime = sharedPref.getLong(
|
||||||
R.string.save_key_gradesCacheTime
|
context.getString(R.string.save_key_gradesCacheTime), 0
|
||||||
), 0)
|
)
|
||||||
|
|
||||||
// load saved course
|
// load saved course
|
||||||
cCourse = Course(
|
cCourse = Course(
|
||||||
|
@ -183,17 +200,22 @@ object Preferences {
|
||||||
)
|
)
|
||||||
|
|
||||||
// load saved colors
|
// load saved colors
|
||||||
cColorPrimary = sharedPref.getInt(context.getString(
|
cColorPrimary = sharedPref.getInt(
|
||||||
R.string.save_key_colorPrimary
|
context.getString(R.string.save_key_colorPrimary), cColorPrimary
|
||||||
), cColorPrimary)
|
)
|
||||||
cColorAccent = sharedPref.getInt(context.getString(
|
cColorAccent = sharedPref.getInt(
|
||||||
R.string.save_key_colorAccent
|
context.getString(R.string.save_key_colorAccent), cColorAccent
|
||||||
), cColorAccent)
|
)
|
||||||
|
|
||||||
|
// load grades sync interval
|
||||||
|
gradesSyncInterval = sharedPref.getInt(
|
||||||
|
context.getString(R.string.save_key_gradesSyncInterval), gradesSyncInterval
|
||||||
|
)
|
||||||
|
|
||||||
// load showBuffet
|
// load showBuffet
|
||||||
cShowBuffet = sharedPref.getBoolean(context.getString(
|
cShowBuffet = sharedPref.getBoolean(
|
||||||
R.string.save_key_showBuffet
|
context.getString(R.string.save_key_showBuffet), true
|
||||||
), true)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -47,6 +47,7 @@ import kotlinx.android.synthetic.main.fragment_settings.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import org.mosad.seil0.projectlaogai.BuildConfig
|
import org.mosad.seil0.projectlaogai.BuildConfig
|
||||||
import org.mosad.seil0.projectlaogai.R
|
import org.mosad.seil0.projectlaogai.R
|
||||||
|
import org.mosad.seil0.projectlaogai.controller.GradesController
|
||||||
import org.mosad.seil0.projectlaogai.controller.cache.CacheController
|
import org.mosad.seil0.projectlaogai.controller.cache.CacheController
|
||||||
import org.mosad.seil0.projectlaogai.controller.cache.CacheController.Companion.coursesList
|
import org.mosad.seil0.projectlaogai.controller.cache.CacheController.Companion.coursesList
|
||||||
import org.mosad.seil0.projectlaogai.controller.preferences.Preferences
|
import org.mosad.seil0.projectlaogai.controller.preferences.Preferences
|
||||||
|
@ -74,6 +75,7 @@ class SettingsFragment : Fragment() {
|
||||||
private lateinit var linLayoutTheme: LinearLayout
|
private lateinit var linLayoutTheme: LinearLayout
|
||||||
private lateinit var linLayoutPrimaryColor: LinearLayout
|
private lateinit var linLayoutPrimaryColor: LinearLayout
|
||||||
private lateinit var linLayoutAccentColor: LinearLayout
|
private lateinit var linLayoutAccentColor: LinearLayout
|
||||||
|
private lateinit var linLayoutGradesSync: LinearLayout
|
||||||
private lateinit var switchBuffet: SwitchCompat
|
private lateinit var switchBuffet: SwitchCompat
|
||||||
private lateinit var txtViewCourse: TextView
|
private lateinit var txtViewCourse: TextView
|
||||||
|
|
||||||
|
@ -97,6 +99,7 @@ class SettingsFragment : Fragment() {
|
||||||
linLayoutTheme = view.findViewById(R.id.linLayout_Theme)
|
linLayoutTheme = view.findViewById(R.id.linLayout_Theme)
|
||||||
linLayoutPrimaryColor = view.findViewById(R.id.linLayout_PrimaryColor)
|
linLayoutPrimaryColor = view.findViewById(R.id.linLayout_PrimaryColor)
|
||||||
linLayoutAccentColor = view.findViewById(R.id.linLayout_AccentColor)
|
linLayoutAccentColor = view.findViewById(R.id.linLayout_AccentColor)
|
||||||
|
linLayoutGradesSync = view.findViewById(R.id.linLayout_GradesSync)
|
||||||
switchBuffet = view.findViewById(R.id.switch_buffet)
|
switchBuffet = view.findViewById(R.id.switch_buffet)
|
||||||
|
|
||||||
// if we call txtView_Course via KAE view binding it'll result in a NPE in the onDismissed call
|
// if we call txtView_Course via KAE view binding it'll result in a NPE in the onDismissed call
|
||||||
|
@ -108,6 +111,11 @@ class SettingsFragment : Fragment() {
|
||||||
txtView_User.text = EncryptedPreferences.email.ifEmpty { resources.getString(R.string.sample_user) }
|
txtView_User.text = EncryptedPreferences.email.ifEmpty { resources.getString(R.string.sample_user) }
|
||||||
txtView_Course.text = cCourse.courseName
|
txtView_Course.text = cCourse.courseName
|
||||||
txtView_AboutDesc.text = resources.getString(R.string.about_version, BuildConfig.VERSION_NAME, getString(R.string.build_time))
|
txtView_AboutDesc.text = resources.getString(R.string.about_version, BuildConfig.VERSION_NAME, getString(R.string.build_time))
|
||||||
|
txtView_GradesSyncDesc.text = if (Preferences.gradesSyncInterval == 0) {
|
||||||
|
resources.getString(R.string.grades_sync_desc_never)
|
||||||
|
} else {
|
||||||
|
resources.getString(R.string.grades_sync_desc, Preferences.gradesSyncInterval)
|
||||||
|
}
|
||||||
switch_buffet.isChecked = cShowBuffet // init switch
|
switch_buffet.isChecked = cShowBuffet // init switch
|
||||||
|
|
||||||
val outValue = TypedValue()
|
val outValue = TypedValue()
|
||||||
|
@ -281,6 +289,38 @@ class SettingsFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
linLayoutGradesSync.setOnClickListener {
|
||||||
|
val items = resources.getStringArray(R.array.syncInterval).toList()
|
||||||
|
val initial = when (Preferences.gradesSyncInterval) {
|
||||||
|
1 -> 1
|
||||||
|
3 -> 2
|
||||||
|
6 -> 3
|
||||||
|
12 -> 4
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialDialog(context!!)
|
||||||
|
.title(R.string.grades_sync)
|
||||||
|
.listItemsSingleChoice(items = items, initialSelection = initial) { _, index, _ ->
|
||||||
|
val interval = when (index) {
|
||||||
|
1 -> 1
|
||||||
|
2 -> 3
|
||||||
|
3 -> 6
|
||||||
|
4 -> 12
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Preferences.saveGradesSync(context!!, interval)
|
||||||
|
GradesController.updateBackgroundSync(context!!)
|
||||||
|
|
||||||
|
txtView_GradesSyncDesc.text = if (Preferences.gradesSyncInterval == 0) {
|
||||||
|
resources.getString(R.string.grades_sync_desc_never)
|
||||||
|
} else {
|
||||||
|
resources.getString(R.string.grades_sync_desc, Preferences.gradesSyncInterval)
|
||||||
|
}
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
|
||||||
switchBuffet.setOnClickListener {
|
switchBuffet.setOnClickListener {
|
||||||
Preferences.saveShowBuffet(context!!, switchBuffet.isChecked)
|
Preferences.saveShowBuffet(context!!, switchBuffet.isChecked)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package org.mosad.seil0.projectlaogai.util
|
||||||
|
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationUtils(val context: Context) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val CHANNEL_ID_GRADES = "channel_grades"
|
||||||
|
|
||||||
|
val id = AtomicInteger(0)
|
||||||
|
|
||||||
|
fun getId() = id.incrementAndGet()
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
createNotificationChannel(CHANNEL_ID_GRADES, "Grades Channel", "A Channel")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(26)
|
||||||
|
private fun createNotificationChannel(channelId: String, name: String, desc: String) {
|
||||||
|
val mChannel = NotificationChannel(channelId, name, NotificationManager.IMPORTANCE_DEFAULT)
|
||||||
|
mChannel.description = desc
|
||||||
|
|
||||||
|
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||||
|
notificationManager.createNotificationChannel(mChannel)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
/**
|
||||||
|
* ProjectLaogai
|
||||||
|
*
|
||||||
|
* Copyright 2019-2020 <seil0@mosad.xyz>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.mosad.seil0.projectlaogai.worker
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import androidx.work.Worker
|
||||||
|
import androidx.work.WorkerParameters
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.mosad.seil0.projectlaogai.R
|
||||||
|
import org.mosad.seil0.projectlaogai.controller.GradesController
|
||||||
|
import org.mosad.seil0.projectlaogai.controller.cache.CacheController
|
||||||
|
import org.mosad.seil0.projectlaogai.controller.preferences.EncryptedPreferences
|
||||||
|
import org.mosad.seil0.projectlaogai.util.NotificationUtils
|
||||||
|
import org.mosad.seil0.projectlaogai.util.NotificationUtils.Companion.CHANNEL_ID_GRADES
|
||||||
|
|
||||||
|
class GradesUpdateWorker(val context: Context, params: WorkerParameters): Worker(context, params) {
|
||||||
|
|
||||||
|
override fun doWork(): Result {
|
||||||
|
|
||||||
|
// check if credentials are present, if not do nothing
|
||||||
|
val credentials = EncryptedPreferences.readCredentials(context)
|
||||||
|
if (credentials.first.isEmpty() || credentials.second.isEmpty()) {
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO show updating notification, for debugging
|
||||||
|
println("doing work ...")
|
||||||
|
val notificationIdDBG = NotificationUtils.getId()
|
||||||
|
val builderDBG = NotificationCompat.Builder(context, CHANNEL_ID_GRADES)
|
||||||
|
.setSmallIcon(R.drawable.ic_grading_black_24dp)
|
||||||
|
.setContentTitle(context.getString(R.string.notification_grades))
|
||||||
|
.setContentText(context.getString(R.string.notification_grades_updating_desc))
|
||||||
|
.setNotificationSilent()
|
||||||
|
NotificationManagerCompat.from(context).apply {
|
||||||
|
notify(notificationIdDBG, builderDBG.build())
|
||||||
|
}
|
||||||
|
|
||||||
|
// get old grades
|
||||||
|
val oldGrades = CacheController(context).readGrades()
|
||||||
|
|
||||||
|
// get update from qispos
|
||||||
|
runBlocking { CacheController.updateGrades(context).join() }
|
||||||
|
val newGrades = CacheController(context).readGrades()
|
||||||
|
|
||||||
|
// check for changes
|
||||||
|
val diff = GradesController().diffGrades(oldGrades, newGrades)
|
||||||
|
|
||||||
|
// show message
|
||||||
|
if (diff.isNotEmpty()) {
|
||||||
|
val text = if (diff.size < 2) {
|
||||||
|
context.getString(R.string.notification_grades_single_desc, diff.first().name)
|
||||||
|
} else {
|
||||||
|
context.getString(R.string.notification_grades_multiple_desc, diff.first().name, (diff.size - 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
val builder = NotificationCompat.Builder(context, CHANNEL_ID_GRADES)
|
||||||
|
.setSmallIcon(R.drawable.ic_grading_black_24dp)
|
||||||
|
.setContentTitle(context.getString(R.string.notification_grades))
|
||||||
|
.setContentText(text)
|
||||||
|
|
||||||
|
// if there are multiple subjects, use BigText
|
||||||
|
if (diff.size > 1)
|
||||||
|
builder.setStyle(NotificationCompat.BigTextStyle().bigText(text))
|
||||||
|
|
||||||
|
NotificationManagerCompat.from(context).apply {
|
||||||
|
notify(NotificationUtils.getId(), builder.build())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO remove debug notification
|
||||||
|
NotificationManagerCompat.from(context).apply {
|
||||||
|
cancel(notificationIdDBG)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -332,6 +332,34 @@
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:background="?android:attr/listDivider" />
|
android:background="?android:attr/listDivider" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linLayout_GradesSync"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_margin="7dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtView_GradesSync"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/grades_sync"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtView_GradesSyncDesc"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/grades_sync_desc" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/divider8"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="?android:attr/listDivider" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.SwitchCompat
|
<androidx.appcompat.widget.SwitchCompat
|
||||||
android:id="@+id/switch_buffet"
|
android:id="@+id/switch_buffet"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -340,6 +368,7 @@
|
||||||
android:text="@string/show_buffet"
|
android:text="@string/show_buffet"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</androidx.cardview.widget.CardView>
|
</androidx.cardview.widget.CardView>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -66,6 +66,9 @@
|
||||||
<string name="primary_color_desc">Zum Ändern tippen, Standard ist Blaugrün.</string>
|
<string name="primary_color_desc">Zum Ändern tippen, Standard ist Blaugrün.</string>
|
||||||
<string name="accent_color">Akzentfarbe</string>
|
<string name="accent_color">Akzentfarbe</string>
|
||||||
<string name="accent_color_desc">Zum Ändern tippen, Standard ist Hellblau.</string>
|
<string name="accent_color_desc">Zum Ändern tippen, Standard ist Hellblau.</string>
|
||||||
|
<string name="grades_sync">Aktualisierungsintervall Noten</string>
|
||||||
|
<string name="grades_sync_desc">%1$d Stunden</string>
|
||||||
|
<string name="grades_sync_desc_never">nie</string>
|
||||||
<string name="show_buffet">Buffet immer anzeigen</string>
|
<string name="show_buffet">Buffet immer anzeigen</string>
|
||||||
|
|
||||||
<!-- dialogs -->
|
<!-- dialogs -->
|
||||||
|
@ -80,6 +83,12 @@
|
||||||
<string name="mensa_current">aktuell: %1$s\n</string>
|
<string name="mensa_current">aktuell: %1$s\n</string>
|
||||||
<string name="mensa_last">letzte Abbuchung: %1$s</string>
|
<string name="mensa_last">letzte Abbuchung: %1$s</string>
|
||||||
|
|
||||||
|
<!-- notifications -->
|
||||||
|
<string name="notification_grades">Noten</string>
|
||||||
|
<string name="notification_grades_single_desc">%1$s wurden hinzugefügt oder aktualisiert</string>
|
||||||
|
<string name="notification_grades_multiple_desc">%1$s und %2$d weiter Vorlesungen wurden hinzugefügt oder aktualisiert</string>
|
||||||
|
<string name="notification_grades_updating_desc">Suche nach neuen Noten …</string>
|
||||||
|
|
||||||
<!-- errors -->
|
<!-- errors -->
|
||||||
<string name="error">Fehler</string>
|
<string name="error">Fehler</string>
|
||||||
<string name="timetable_error">Der Stundenplan konnte nicht geladen werden.</string>
|
<string name="timetable_error">Der Stundenplan konnte nicht geladen werden.</string>
|
||||||
|
@ -101,4 +110,12 @@
|
||||||
<string name="shortcut_grades_long">Noten</string>
|
<string name="shortcut_grades_long">Noten</string>
|
||||||
<string name="shortcut_grades_disabled">Noten deaktiviert</string>
|
<string name="shortcut_grades_disabled">Noten deaktiviert</string>
|
||||||
|
|
||||||
|
<string-array name="syncInterval">
|
||||||
|
<item>Manuell</item>
|
||||||
|
<item>1 Stunde</item>
|
||||||
|
<item>3 Stunden</item>
|
||||||
|
<item>6 Stunden</item>
|
||||||
|
<item>12 Stunden</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -71,6 +71,9 @@
|
||||||
<string name="primary_color_desc">Tap to change, default is teal blue.</string>
|
<string name="primary_color_desc">Tap to change, default is teal blue.</string>
|
||||||
<string name="accent_color">Accent color</string>
|
<string name="accent_color">Accent color</string>
|
||||||
<string name="accent_color_desc">Tap to change, default is light blue.</string>
|
<string name="accent_color_desc">Tap to change, default is light blue.</string>
|
||||||
|
<string name="grades_sync">Update interval grades</string>
|
||||||
|
<string name="grades_sync_desc">%1$d hours</string>
|
||||||
|
<string name="grades_sync_desc_never">never</string>
|
||||||
<string name="show_buffet">Always show buffet</string>
|
<string name="show_buffet">Always show buffet</string>
|
||||||
|
|
||||||
<!-- dialogs -->
|
<!-- dialogs -->
|
||||||
|
@ -85,6 +88,12 @@
|
||||||
<string name="mensa_current">current: %1$s\n</string>
|
<string name="mensa_current">current: %1$s\n</string>
|
||||||
<string name="mensa_last">last: %1$s</string>
|
<string name="mensa_last">last: %1$s</string>
|
||||||
|
|
||||||
|
<!-- notifications -->
|
||||||
|
<string name="notification_grades">Grades</string>
|
||||||
|
<string name="notification_grades_single_desc">%1$s was added or updated</string>
|
||||||
|
<string name="notification_grades_multiple_desc">%1$s and %2$d other subjects have been added or updated</string>
|
||||||
|
<string name="notification_grades_updating_desc">Checking for new grades …</string>
|
||||||
|
|
||||||
<!-- sample strings -->
|
<!-- sample strings -->
|
||||||
<string name="sample_user" translatable="false">spinefield@stud.hs-offenburg.de</string>
|
<string name="sample_user" translatable="false">spinefield@stud.hs-offenburg.de</string>
|
||||||
<string name="sample_course" translatable="false">Everything</string>
|
<string name="sample_course" translatable="false">Everything</string>
|
||||||
|
@ -123,6 +132,7 @@
|
||||||
<string name="save_key_courseTTLink" translatable="false">org.mosad.seil0.projectlaogai.courseTTLink</string>
|
<string name="save_key_courseTTLink" translatable="false">org.mosad.seil0.projectlaogai.courseTTLink</string>
|
||||||
<string name="save_key_colorPrimary" translatable="false">org.mosad.seil0.projectlaogai.colorPrimary</string>
|
<string name="save_key_colorPrimary" translatable="false">org.mosad.seil0.projectlaogai.colorPrimary</string>
|
||||||
<string name="save_key_colorAccent" translatable="false">org.mosad.seil0.projectlaogai.colorAccent</string>
|
<string name="save_key_colorAccent" translatable="false">org.mosad.seil0.projectlaogai.colorAccent</string>
|
||||||
|
<string name="save_key_gradesSyncInterval" translatable="false">org.mosad.seil0.projectlaogai.gradesSyncInterval</string>
|
||||||
<string name="save_key_showBuffet" translatable="false">org.mosad.seil0.projectlaogai.showBuffet</string>
|
<string name="save_key_showBuffet" translatable="false">org.mosad.seil0.projectlaogai.showBuffet</string>
|
||||||
<string name="save_key_coursesCacheTime" translatable="false">org.mosad.seil0.projectlaogai.coursesCacheTime</string>
|
<string name="save_key_coursesCacheTime" translatable="false">org.mosad.seil0.projectlaogai.coursesCacheTime</string>
|
||||||
<string name="save_key_mensaCacheTime" translatable="false">org.mosad.seil0.projectlaogai.mensaCacheTime</string>
|
<string name="save_key_mensaCacheTime" translatable="false">org.mosad.seil0.projectlaogai.mensaCacheTime</string>
|
||||||
|
@ -131,6 +141,13 @@
|
||||||
<string name="save_key_user_email" translatable="false">org.mosad.seil0.projectlaogai.user_email</string>
|
<string name="save_key_user_email" translatable="false">org.mosad.seil0.projectlaogai.user_email</string>
|
||||||
<string name="save_key_user_password" translatable="false">org.mosad.seil0.projectlaogai.user_password</string>
|
<string name="save_key_user_password" translatable="false">org.mosad.seil0.projectlaogai.user_password</string>
|
||||||
|
|
||||||
|
<string-array name="syncInterval">
|
||||||
|
<item>Manually</item>
|
||||||
|
<item>1 Hour</item>
|
||||||
|
<item>3 Hours</item>
|
||||||
|
<item>6 Hours</item>
|
||||||
|
<item>12 Hours</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string-array name="courses">
|
<string-array name="courses">
|
||||||
<item>AI-1</item>
|
<item>AI-1</item>
|
||||||
|
|
Loading…
Reference in New Issue