Added option to force a refresh, added fallBackToDestructiveMigration as possible migration strategy for substitution table

This commit is contained in:
Deniz Düzgören
2019-09-08 21:07:20 +02:00
parent 371221a092
commit 47a4a51b44
11 changed files with 114 additions and 48 deletions
+2 -2
View File
@@ -10,8 +10,8 @@ android {
applicationId "com.denizd.substitutionplan" applicationId "com.denizd.substitutionplan"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 28 targetSdkVersion 28
versionCode 30 versionCode 31
versionName "2.2.7" versionName "2.2.8"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
@@ -112,9 +112,7 @@ internal class Main : AppCompatActivity(R.layout.app_bar_main) {
if (info.manufacturer.contains("Huawei") || if (info.manufacturer.contains("Huawei") ||
info.manufacturer.contains("Honor") || info.manufacturer.contains("Honor") ||
info.manufacturer.contains("Xiaomi")) { info.manufacturer.contains("Xiaomi")) {
val alertDialog = AlertDialog.Builder(context, val alertDialog = AlertDialog.Builder(context, R.style.AlertDialog)
R.style.AlertDialog
)
val dialogView = LayoutInflater.from(context).inflate(R.layout.secret_dialog, null) val dialogView = LayoutInflater.from(context).inflate(R.layout.secret_dialog, null)
val title = dialogView.findViewById<TextView>(R.id.textviewtitle) val title = dialogView.findViewById<TextView>(R.id.textviewtitle)
title.text = getString(R.string.chineseDevicesTitle) title.text = getString(R.string.chineseDevicesTitle)
@@ -34,11 +34,12 @@ import kotlin.collections.ArrayList
* @param isMenu food menu will be downloaded and persisted in the database if true * @param isMenu food menu will be downloaded and persisted in the database if true
* @param isJobService a notification will be prepared and sent if this and isPlan is true * @param isJobService a notification will be prepared and sent if this and isPlan is true
*/ */
internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boolean, context: Context, application: Application, parentView: View?) : AsyncTask<Void, Void, Void>() { internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boolean, context: Context, application: Application, parentView: View?, forced: Boolean) : AsyncTask<Void, Void, Void>() {
private var jobService = isJobService private var jobService = isJobService
private var plan = isPlan private var plan = isPlan
private var menu = isMenu private var menu = isMenu
private var forceRefresh = forced
private var mContext = context private var mContext = context
private var mApplication = application private var mApplication = application
@@ -60,6 +61,10 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole
foodUrl = "https://djd4rkn355.github.io/food_test.html" foodUrl = "https://djd4rkn355.github.io/food_test.html"
} }
if (forceRefresh) {
edit.putString("timeNew", "").putString("timeFoodNew", "").apply()
}
if (menu) { if (menu) {
requestFoodMenuData() requestFoodMenuData()
} }
@@ -69,10 +74,12 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole
if (plan || menu) { if (plan || menu) {
mView?.let { v: View -> mView?.let { v: View ->
val snackText = "${mContext.getText(R.string.lastUpdated)} ${when { var snackText = "${mContext.getText(R.string.lastUpdated)} ${when {
plan -> currentTime
menu -> currentFoodTime menu -> currentFoodTime
else -> currentTime else -> "---"
}}" }}"
snackText = if (forceRefresh) mContext.getString(R.string.forcedRefresh) else snackText
val snackBarView = v.findViewById<View>(R.id.coordination) val snackBarView = v.findViewById<View>(R.id.coordination)
Snackbar.make(snackBarView, snackText, Snackbar.LENGTH_LONG).show() Snackbar.make(snackBarView, snackText, Snackbar.LENGTH_LONG).show()
} }
@@ -28,10 +28,11 @@ internal abstract class SubstDatabase : RoomDatabase() {
if (instance == null) { if (instance == null) {
synchronized (SubstDatabase::class) { synchronized (SubstDatabase::class) {
instance = Room.databaseBuilder(context.applicationContext, instance = Room.databaseBuilder(context.applicationContext,
SubstDatabase::class.java, SubstDatabase::class.java,
"subst_database") "subst_database")
.addMigrations(addTeacherColumn) .addMigrations(addTeacherColumn)
.build() .fallbackToDestructiveMigration()
.build()
} }
} }
return instance return instance
@@ -43,10 +44,10 @@ internal abstract class SubstDatabase : RoomDatabase() {
if (foodInstance == null) { if (foodInstance == null) {
synchronized (SubstDatabase::class) { synchronized (SubstDatabase::class) {
foodInstance = Room.databaseBuilder(context.applicationContext, foodInstance = Room.databaseBuilder(context.applicationContext,
SubstDatabase::class.java, SubstDatabase::class.java,
"food_database") "food_database")
.fallbackToDestructiveMigration() .fallbackToDestructiveMigration()
.build() .build()
} }
} }
return foodInstance return foodInstance
@@ -63,24 +63,26 @@ internal class FoodFragment : Fragment(R.layout.food_layout) {
if (prefs.getBoolean("autoRefresh", false)) { if (prefs.getBoolean("autoRefresh", false)) {
pullToRefresh.isRefreshing = true pullToRefresh.isRefreshing = true
DataFetcher( DataFetcher(
false, isPlan = false,
true, isMenu = true,
false, isJobService = false,
mContext, context = mContext,
activity!!.application, application = activity!!.application,
view.rootView parentView = view.rootView,
forced = false
).execute() ).execute()
} }
pullToRefresh.setOnRefreshListener { pullToRefresh.setOnRefreshListener {
pullToRefresh.isRefreshing = true pullToRefresh.isRefreshing = true
DataFetcher( DataFetcher(
false, isPlan = false,
true, isMenu = true,
false, isJobService = false,
mContext, context = mContext,
activity!!.application, application = activity!!.application,
view.rootView parentView = view.rootView,
forced = false
).execute() ).execute()
} }
} }
@@ -83,7 +83,8 @@ internal open class PlanFragment : Fragment(R.layout.plan) {
isJobService = false, isJobService = false,
context = mContext, context = mContext,
application = activity!!.application, application = activity!!.application,
parentView = view.rootView parentView = view.rootView,
forced = false
).execute() ).execute()
} }
@@ -1,5 +1,6 @@
package com.denizd.substitutionplan.fragments package com.denizd.substitutionplan.fragments
import android.annotation.SuppressLint
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -27,6 +28,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.denizd.substitutionplan.* import com.denizd.substitutionplan.*
import com.denizd.substitutionplan.adapters.ColourAdapter import com.denizd.substitutionplan.adapters.ColourAdapter
import com.denizd.substitutionplan.adapters.RingtoneAdapter import com.denizd.substitutionplan.adapters.RingtoneAdapter
import com.denizd.substitutionplan.data.DataFetcher
import com.denizd.substitutionplan.data.HelperFunctions import com.denizd.substitutionplan.data.HelperFunctions
import com.denizd.substitutionplan.models.Colour import com.denizd.substitutionplan.models.Colour
import com.denizd.substitutionplan.models.Ringtone import com.denizd.substitutionplan.models.Ringtone
@@ -85,6 +87,7 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
val btnVersion = view.findViewById<LinearLayout>(R.id.btnVersion) val btnVersion = view.findViewById<LinearLayout>(R.id.btnVersion)
currentRingtone = view.findViewById(R.id.txtCustomiseRingtone2) currentRingtone = view.findViewById(R.id.txtCustomiseRingtone2)
setRingtoneText() setRingtoneText()
val btnForceRefresh = view.findViewById<LinearLayout>(R.id.btnForceRefresh)
switchDisableGreeting.setOnCheckedChangeListener(this) switchDisableGreeting.setOnCheckedChangeListener(this)
// switchDark.setOnCheckedChangeListener(this) // switchDark.setOnCheckedChangeListener(this)
@@ -101,6 +104,12 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
view.findViewById<LinearLayout>(R.id.btnTerms).setOnClickListener(this) view.findViewById<LinearLayout>(R.id.btnTerms).setOnClickListener(this)
view.findViewById<LinearLayout>(R.id.btnPrivacyP).setOnClickListener(this) view.findViewById<LinearLayout>(R.id.btnPrivacyP).setOnClickListener(this)
btnVersion.setOnClickListener(this) btnVersion.setOnClickListener(this)
btnForceRefresh.setOnClickListener(this)
btnForceRefresh.setOnLongClickListener {
edit.putString("timeNew", "").putString("timeFoodNew", "").apply()
makeToast(mContext.getString(R.string.forcedRefreshTimes))
true
}
val darkModeDropDown = view.findViewById<AutoCompleteTextView>(R.id.darkModeDropDownText) val darkModeDropDown = view.findViewById<AutoCompleteTextView>(R.id.darkModeDropDownText)
val darkModeList = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { val darkModeList = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
@@ -127,6 +136,7 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
0 -> { 0 -> {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
if (Build.VERSION.SDK_INT in 23..28) { if (Build.VERSION.SDK_INT in 23..28) {
@SuppressLint("InlinedApi")
window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
window?.navigationBarColor = ContextCompat.getColor(mContext, R.color.colorBackground) window?.navigationBarColor = ContextCompat.getColor(mContext, R.color.colorBackground)
} }
@@ -150,11 +160,6 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
switchDisableGreeting.isChecked = prefs.getBoolean("greeting", true) switchDisableGreeting.isChecked = prefs.getBoolean("greeting", true)
// switchDark.isChecked = when (prefs.getInt("themeInt", 0)) {
// 1 -> true
// 2 -> true
// else -> false
// }
switchNotifications.isChecked = prefs.getBoolean("notif", false) switchNotifications.isChecked = prefs.getBoolean("notif", false)
switchDefaultPlan.isChecked = prefs.getBoolean("defaultPersonalised", false) switchDefaultPlan.isChecked = prefs.getBoolean("defaultPersonalised", false)
switchAutoRefresh.isChecked = prefs.getBoolean("autoRefresh", false) switchAutoRefresh.isChecked = prefs.getBoolean("autoRefresh", false)
@@ -271,6 +276,17 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
} }
} }
} }
R.id.btnForceRefresh -> {
DataFetcher(
isPlan = true,
isMenu = true,
isJobService = false,
context = mContext,
application = activity!!.application,
parentView = view!!.rootView,
forced = true
).execute()
}
} }
edit.apply() edit.apply()
} }
@@ -311,9 +327,7 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
} }
private fun createColourDialog() { private fun createColourDialog() {
val colourCustomiserBuilder = AlertDialog.Builder(mContext, val colourCustomiserBuilder = AlertDialog.Builder(mContext, R.style.AlertDialog)
R.style.AlertDialog
)
val dialogView = LayoutInflater.from(mContext).inflate(R.layout.recycler_dialog, null) val dialogView = LayoutInflater.from(mContext).inflate(R.layout.recycler_dialog, null)
val titleText = dialogView.findViewById<TextView>(R.id.empty_textviewtitle) val titleText = dialogView.findViewById<TextView>(R.id.empty_textviewtitle)
@@ -358,7 +372,7 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
R.drawable.ic_help, R.drawable.ic_pencil R.drawable.ic_help, R.drawable.ic_pencil
) )
for (i in 0 until coursesNoLang.size) { for (i in coursesNoLang.indices) {
colours.add( colours.add(
Colour( Colour(
courses[i], courses[i],
@@ -462,7 +476,7 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
R.id.sky, R.id.orchid, R.id.lavender, R.id.carnation, R.id.brown2, R.id.pureBlack) R.id.sky, R.id.orchid, R.id.lavender, R.id.carnation, R.id.brown2, R.id.pureBlack)
val colours = HelperFunctions.colourNames val colours = HelperFunctions.colourNames
for (i2 in 0 until buttons.size) { for (i2 in buttons.indices) {
picker.findViewById<MaterialButton>(buttons[i2]).setOnClickListener { picker.findViewById<MaterialButton>(buttons[i2]).setOnClickListener {
// prefs.edit().putInt("bg$titleNoLang", colourIntegers[i2]).apply() // prefs.edit().putInt("bg$titleNoLang", colourIntegers[i2]).apply()
prefs.edit().putString("card$titleNoLang", colours[i2]).apply() prefs.edit().putString("card$titleNoLang", colours[i2]).apply()
@@ -530,10 +544,6 @@ internal class SettingsFragment : Fragment(R.layout.content_settings), View.OnCl
makeToast(getString(R.string.youtubeNotFound)) makeToast(getString(R.string.youtubeNotFound))
} }
} }
"_NOTIFICATION" -> {
edit.putString("timeNew", "").putString("timeFoodNew", "").apply()
makeToast("Notification times cleared")
} // TODO add option to clear database
"_FIRSTTIME" -> { "_FIRSTTIME" -> {
edit.putBoolean("firstTime", true).apply() edit.putBoolean("firstTime", true).apply()
makeToast("First time flag cleared") makeToast("First time flag cleared")
@@ -13,7 +13,8 @@ internal class FBNotificationService : FirebaseMessagingService() {
isJobService = true, isJobService = true,
context = applicationContext, context = applicationContext,
application = application, application = application,
parentView = null parentView = null,
forced = false
).execute() ).execute()
} }
} }
+42 -4
View File
@@ -496,6 +496,44 @@
app:layout_constraintStart_toStartOf="@+id/txtAutoRefresh" app:layout_constraintStart_toStartOf="@+id/txtAutoRefresh"
app:layout_constraintTop_toTopOf="@+id/txtAutoRefresh"/> app:layout_constraintTop_toTopOf="@+id/txtAutoRefresh"/>
<TextView
android:id="@+id/txtForceRefresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/forceRefreshTxt"
android:textColor="@color/colorText"
android:textSize="14sp"
app:layout_constraintStart_toStartOf="@+id/txtAutoRefreshTwo"
app:layout_constraintTop_toBottomOf="@+id/txtAutoRefreshTwo" />
<TextView
android:id="@+id/txtForceRefresh2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/forceRefreshTxt2"
android:textColor="@color/colorHint"
android:textSize="12sp"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toStartOf="@+id/txtForceRefresh"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtForceRefresh" />
<LinearLayout
android:id="@+id/btnForceRefresh"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:clickable="true"
android:focusable="true"
style="@style/SelectableItemBackground"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/txtVisitWeb"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtAutoRefreshTwo" />
<TextView <TextView
android:id="@+id/txtVisitWeb" android:id="@+id/txtVisitWeb"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -504,8 +542,8 @@
android:text="@string/visitWebsite" android:text="@string/visitWebsite"
android:textColor="@color/colorText" android:textColor="@color/colorText"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintStart_toStartOf="@+id/txtAutoRefreshTwo" app:layout_constraintStart_toStartOf="@+id/txtForceRefresh2"
app:layout_constraintTop_toBottomOf="@+id/txtAutoRefreshTwo" /> app:layout_constraintTop_toBottomOf="@+id/txtForceRefresh2" />
<TextView <TextView
android:id="@+id/txtWeb" android:id="@+id/txtWeb"
@@ -514,7 +552,7 @@
android:text="@string/ifYouNeedTo" android:text="@string/ifYouNeedTo"
android:textColor="@color/colorHint" android:textColor="@color/colorHint"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintStart_toStartOf="@+id/txtVisitWeb" app:layout_constraintStart_toStartOf="@+id/txtForceRefresh"
app:layout_constraintTop_toBottomOf="@+id/txtVisitWeb" /> app:layout_constraintTop_toBottomOf="@+id/txtVisitWeb" />
<LinearLayout <LinearLayout
@@ -531,7 +569,7 @@
app:layout_constraintBottom_toTopOf="@+id/txtLicences" app:layout_constraintBottom_toTopOf="@+id/txtLicences"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtAutoRefreshTwo" /> app:layout_constraintTop_toBottomOf="@+id/txtForceRefresh2" />
<TextView <TextView
android:id="@+id/txtLicences" android:id="@+id/txtLicences"
+4
View File
@@ -151,4 +151,8 @@
<item>Hell</item> <item>Hell</item>
<item>Dunkel</item> <item>Dunkel</item>
</string-array> </string-array>
<string name="forcedRefresh">Aktualisierung erfolgreich</string>
<string name="forcedRefreshTimes">Aktualisierungszeiten wurden gelöscht</string>
<string name="forceRefreshTxt">Erzwinge eine Aktualisierung</string>
<string name="forceRefreshTxt2">Nutz dies falls du Plan oder Speisemenü nicht sehen kannst</string>
</resources> </resources>
+4
View File
@@ -165,4 +165,8 @@
<item>Light</item> <item>Light</item>
<item>Dark</item> <item>Dark</item>
</string-array> </string-array>
<string name="forcedRefresh">Forced refresh successful</string>
<string name="forcedRefreshTimes">Cleared refresh times</string>
<string name="forceRefreshTxt">Force a refresh</string>
<string name="forceRefreshTxt2">Use this if you can\'t see the plan or food menu</string>
</resources> </resources>