Fix change of worker specs after app update (#402)

This commit is contained in:
Rafał Borcz 2019-06-06 22:32:43 +02:00 committed by Mikołaj Pich
parent 75122d0dcd
commit 7485cb2a39
13 changed files with 110 additions and 37 deletions

View File

@ -5,13 +5,13 @@ package io.github.wulkanowy.utils
import android.content.Context import android.content.Context
import timber.log.Timber import timber.log.Timber
fun initCrashlytics(context: Context, appInfo: AppInfo) {
// do nothing
}
class CrashlyticsTree : Timber.Tree() { class CrashlyticsTree : Timber.Tree() {
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
// do nothing // do nothing
} }
} }
fun initCrashlytics(context: Context) {
// do nothing
}

View File

@ -80,7 +80,6 @@
android:name="android.appwidget.provider" android:name="android.appwidget.provider"
android:resource="@xml/provider_widget_timetable" /> android:resource="@xml/provider_widget_timetable" />
</receiver> </receiver>
<receiver <receiver
android:name=".ui.modules.luckynumberwidget.LuckyNumberWidgetProvider" android:name=".ui.modules.luckynumberwidget.LuckyNumberWidgetProvider"
android:label="@string/lucky_number_title"> android:label="@string/lucky_number_title">

View File

@ -1,6 +1,8 @@
package io.github.wulkanowy package io.github.wulkanowy
import android.content.Context import android.content.Context
import android.util.Log.INFO
import android.util.Log.VERBOSE
import androidx.multidex.MultiDex import androidx.multidex.MultiDex
import androidx.work.Configuration import androidx.work.Configuration
import androidx.work.WorkManager import androidx.work.WorkManager
@ -9,10 +11,10 @@ import dagger.android.AndroidInjector
import dagger.android.support.DaggerApplication import dagger.android.support.DaggerApplication
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.utils.Log import eu.davidea.flexibleadapter.utils.Log
import io.github.wulkanowy.BuildConfig.DEBUG
import io.github.wulkanowy.di.DaggerAppComponent import io.github.wulkanowy.di.DaggerAppComponent
import io.github.wulkanowy.services.sync.SyncWorkerFactory import io.github.wulkanowy.services.sync.SyncWorkerFactory
import io.github.wulkanowy.utils.ActivityLifecycleLogger import io.github.wulkanowy.utils.ActivityLifecycleLogger
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.CrashlyticsTree import io.github.wulkanowy.utils.CrashlyticsTree
import io.github.wulkanowy.utils.DebugLogTree import io.github.wulkanowy.utils.DebugLogTree
import io.github.wulkanowy.utils.initCrashlytics import io.github.wulkanowy.utils.initCrashlytics
@ -27,6 +29,9 @@ class WulkanowyApp : DaggerApplication() {
@Inject @Inject
lateinit var workerFactory: SyncWorkerFactory lateinit var workerFactory: SyncWorkerFactory
@Inject
lateinit var appInfo: AppInfo
override fun attachBaseContext(base: Context?) { override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base) super.attachBaseContext(base)
MultiDex.install(this) MultiDex.install(this)
@ -35,15 +40,23 @@ class WulkanowyApp : DaggerApplication() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
AndroidThreeTen.init(this) AndroidThreeTen.init(this)
WorkManager.initialize(this, Configuration.Builder().setWorkerFactory(workerFactory).build())
RxJavaPlugins.setErrorHandler(::onError) RxJavaPlugins.setErrorHandler(::onError)
initCrashlytics(applicationContext) initWorkManager()
initLogging() initLogging()
initCrashlytics(this, appInfo)
}
private fun initWorkManager() {
WorkManager.initialize(this,
Configuration.Builder()
.setWorkerFactory(workerFactory)
.setMinimumLoggingLevel(if (appInfo.isDebug) VERBOSE else INFO)
.build())
} }
private fun initLogging() { private fun initLogging() {
if (DEBUG) { if (appInfo.isDebug) {
Timber.plant(DebugLogTree()) Timber.plant(DebugLogTree())
FlexibleAdapter.enableLogs(Log.Level.DEBUG) FlexibleAdapter.enableLogs(Log.Level.DEBUG)
} else { } else {

View File

@ -6,10 +6,9 @@ import dagger.Module
import dagger.Provides import dagger.Provides
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import io.github.wulkanowy.BuildConfig.DEBUG
import io.github.wulkanowy.WulkanowyApp import io.github.wulkanowy.WulkanowyApp
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.SchedulersProvider
import javax.inject.Named
import javax.inject.Singleton import javax.inject.Singleton
@Module @Module
@ -31,7 +30,6 @@ internal class AppModule {
fun provideAppWidgetManager(context: Context): AppWidgetManager = AppWidgetManager.getInstance(context) fun provideAppWidgetManager(context: Context): AppWidgetManager = AppWidgetManager.getInstance(context)
@Singleton @Singleton
@Named("isDebug")
@Provides @Provides
fun provideIsDebug() = DEBUG fun provideAppInfo() = AppInfo()
} }

View File

@ -10,30 +10,46 @@ import androidx.work.NetworkType.CONNECTED
import androidx.work.NetworkType.UNMETERED import androidx.work.NetworkType.UNMETERED
import androidx.work.PeriodicWorkRequest import androidx.work.PeriodicWorkRequest
import androidx.work.WorkManager import androidx.work.WorkManager
import io.github.wulkanowy.data.db.SharedPrefHelper
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
import io.github.wulkanowy.services.sync.channels.DebugChannel import io.github.wulkanowy.services.sync.channels.DebugChannel
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.isHolidays import io.github.wulkanowy.utils.isHolidays
import org.threeten.bp.LocalDate.now import org.threeten.bp.LocalDate.now
import timber.log.Timber import timber.log.Timber
import java.util.concurrent.TimeUnit.MINUTES import java.util.concurrent.TimeUnit.MINUTES
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Named
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class SyncManager @Inject constructor( class SyncManager @Inject constructor(
private val workManager: WorkManager, private val workManager: WorkManager,
private val preferencesRepository: PreferencesRepository, private val preferencesRepository: PreferencesRepository,
sharedPrefHelper: SharedPrefHelper,
newEntriesChannel: NewEntriesChannel, newEntriesChannel: NewEntriesChannel,
debugChannel: DebugChannel, debugChannel: DebugChannel,
@Named("isDebug") isDebug: Boolean appInfo: AppInfo
) { ) {
companion object {
private const val APP_VERSION_CODE_KEY = "app_version_code"
}
init { init {
if (SDK_INT >= O) newEntriesChannel.create()
if (SDK_INT >= O && isDebug) debugChannel.create()
if (now().isHolidays) stopSyncWorker() if (now().isHolidays) stopSyncWorker()
if (SDK_INT > O) {
newEntriesChannel.create()
if (appInfo.isDebug) debugChannel.create()
}
if (sharedPrefHelper.getLong(APP_VERSION_CODE_KEY, -1L) != appInfo.versionCode.toLong()) {
startSyncWorker(true)
sharedPrefHelper.putLong(APP_VERSION_CODE_KEY, appInfo.versionCode.toLong(), true)
}
Timber.i("SyncManager was initialized") Timber.i("SyncManager was initialized")
} }

View File

@ -8,10 +8,10 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import com.mikepenz.aboutlibraries.LibsBuilder import com.mikepenz.aboutlibraries.LibsBuilder
import com.mikepenz.aboutlibraries.LibsFragmentCompat import com.mikepenz.aboutlibraries.LibsFragmentCompat
import io.github.wulkanowy.BuildConfig
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.openInternetBrowser import io.github.wulkanowy.utils.openInternetBrowser
import io.github.wulkanowy.utils.withOnExtraListener import io.github.wulkanowy.utils.withOnExtraListener
import javax.inject.Inject import javax.inject.Inject
@ -24,6 +24,9 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
@Inject @Inject
lateinit var fragmentCompat: LibsFragmentCompat lateinit var fragmentCompat: LibsFragmentCompat
@Inject
lateinit var appInfo: AppInfo
companion object { companion object {
fun newInstance() = AboutFragment() fun newInstance() = AboutFragment()
} }
@ -71,9 +74,9 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
putExtra(Intent.EXTRA_EMAIL, Array(1) { "wulkanowyinc@gmail.com" }) putExtra(Intent.EXTRA_EMAIL, Array(1) { "wulkanowyinc@gmail.com" })
putExtra(Intent.EXTRA_SUBJECT, "Zgłoszenie błędu") putExtra(Intent.EXTRA_SUBJECT, "Zgłoszenie błędu")
putExtra(Intent.EXTRA_TEXT, "Tu umieść treść zgłoszenia\n\n" + "-".repeat(40) + "\n" + """ putExtra(Intent.EXTRA_TEXT, "Tu umieść treść zgłoszenia\n\n" + "-".repeat(40) + "\n" + """
Build: ${BuildConfig.VERSION_CODE} Build: ${appInfo.versionCode}
SDK: ${android.os.Build.VERSION.SDK_INT} SDK: ${appInfo.systemVersion}
Device: ${android.os.Build.MANUFACTURER} ${android.os.Build.MODEL} Device: ${appInfo.systemManufacturer} ${appInfo.systemModel}
""".trimIndent()) """.trimIndent())
} }

View File

@ -10,11 +10,11 @@ import android.view.ViewGroup
import android.view.inputmethod.EditorInfo.IME_ACTION_DONE import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
import android.view.inputmethod.EditorInfo.IME_NULL import android.view.inputmethod.EditorInfo.IME_NULL
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import io.github.wulkanowy.BuildConfig.VERSION_NAME
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.login.LoginActivity import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.hideSoftInput import io.github.wulkanowy.utils.hideSoftInput
import io.github.wulkanowy.utils.openInternetBrowser import io.github.wulkanowy.utils.openInternetBrowser
import io.github.wulkanowy.utils.setOnItemSelectedListener import io.github.wulkanowy.utils.setOnItemSelectedListener
@ -28,6 +28,9 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
@Inject @Inject
lateinit var presenter: LoginFormPresenter lateinit var presenter: LoginFormPresenter
@Inject
lateinit var appInfo: AppInfo
companion object { companion object {
fun newInstance() = LoginFormFragment() fun newInstance() = LoginFormFragment()
} }
@ -128,7 +131,7 @@ class LoginFormFragment : BaseFragment(), LoginFormView {
override fun showVersion() { override fun showVersion() {
loginFormVersion.apply { loginFormVersion.apply {
visibility = VISIBLE visibility = VISIBLE
text = "${getString(R.string.app_name)} $VERSION_NAME" text = "${getString(R.string.app_name)} ${appInfo.versionName}"
} }
} }

View File

@ -3,25 +3,25 @@ package io.github.wulkanowy.ui.modules.login.form
import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.SchedulersProvider
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Named
class LoginFormPresenter @Inject constructor( class LoginFormPresenter @Inject constructor(
schedulers: SchedulersProvider, schedulers: SchedulersProvider,
studentRepository: StudentRepository, studentRepository: StudentRepository,
private val loginErrorHandler: LoginErrorHandler, private val loginErrorHandler: LoginErrorHandler,
private val analytics: FirebaseAnalyticsHelper, private val analytics: FirebaseAnalyticsHelper,
@param:Named("isDebug") private val isDebug: Boolean private val appInfo: AppInfo
) : BasePresenter<LoginFormView>(loginErrorHandler, studentRepository, schedulers) { ) : BasePresenter<LoginFormView>(loginErrorHandler, studentRepository, schedulers) {
override fun onAttachView(view: LoginFormView) { override fun onAttachView(view: LoginFormView) {
super.onAttachView(view) super.onAttachView(view)
view.run { view.run {
initView() initView()
if (isDebug) showVersion() else showPrivacyPolicy() if (appInfo.isDebug) showVersion() else showPrivacyPolicy()
loginErrorHandler.onBadCredentials = { loginErrorHandler.onBadCredentials = {
setErrorPassIncorrect() setErrorPassIncorrect()

View File

@ -5,10 +5,10 @@ import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import com.takisoft.preferencex.PreferenceFragmentCompat import com.takisoft.preferencex.PreferenceFragmentCompat
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import io.github.wulkanowy.BuildConfig.DEBUG
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.ui.base.BaseActivity import io.github.wulkanowy.ui.base.BaseActivity
import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.AppInfo
import javax.inject.Inject import javax.inject.Inject
class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPreferenceChangeListener, class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPreferenceChangeListener,
@ -17,6 +17,9 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP
@Inject @Inject
lateinit var presenter: SettingsPresenter lateinit var presenter: SettingsPresenter
@Inject
lateinit var appInfo: AppInfo
companion object { companion object {
fun newInstance() = SettingsFragment() fun newInstance() = SettingsFragment()
} }
@ -36,7 +39,7 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP
override fun onCreatePreferencesFix(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferencesFix(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.scheme_preferences) addPreferencesFromResource(R.xml.scheme_preferences)
findPreference(getString(R.string.pref_key_notification_debug)).isVisible = DEBUG findPreference(getString(R.string.pref_key_notification_debug)).isVisible = appInfo.isDebug
} }
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {

View File

@ -33,7 +33,7 @@ class SettingsPresenter @Inject constructor(
Timber.i("Change settings $key") Timber.i("Change settings $key")
preferencesRepository.apply { preferencesRepository.apply {
when (key) { when (key) {
serviceEnableKey -> syncManager.run { if (isServiceEnabled) startSyncWorker() else stopSyncWorker() } serviceEnableKey -> with(syncManager) { if (isServiceEnabled) startSyncWorker() else stopSyncWorker() }
servicesIntervalKey, servicesOnlyWifiKey -> syncManager.startSyncWorker(true) servicesIntervalKey, servicesOnlyWifiKey -> syncManager.startSyncWorker(true)
isDebugNotificationEnableKey -> chuckCollector.showNotification(isDebugNotificationEnable) isDebugNotificationEnableKey -> chuckCollector.showNotification(isDebugNotificationEnable)
appThemeKey -> view?.recreateView() appThemeKey -> view?.recreateView()

View File

@ -0,0 +1,28 @@
package io.github.wulkanowy.utils
import android.os.Build.MANUFACTURER
import android.os.Build.MODEL
import android.os.Build.VERSION.SDK_INT
import io.github.wulkanowy.BuildConfig.CRASHLYTICS_ENABLED
import io.github.wulkanowy.BuildConfig.DEBUG
import io.github.wulkanowy.BuildConfig.VERSION_CODE
import io.github.wulkanowy.BuildConfig.VERSION_NAME
import javax.inject.Singleton
@Singleton
open class AppInfo {
open val isCrashlyticsEnabled get() = CRASHLYTICS_ENABLED
open val isDebug get() = DEBUG
open val versionCode get() = VERSION_CODE
open val versionName get() = VERSION_NAME
open val systemVersion get() = SDK_INT
open val systemManufacturer: String get() = MANUFACTURER
open val systemModel: String get() = MODEL
}

View File

@ -4,9 +4,21 @@ import android.content.Context
import com.crashlytics.android.Crashlytics import com.crashlytics.android.Crashlytics
import com.crashlytics.android.core.CrashlyticsCore import com.crashlytics.android.core.CrashlyticsCore
import io.fabric.sdk.android.Fabric import io.fabric.sdk.android.Fabric
import io.github.wulkanowy.BuildConfig
import timber.log.Timber import timber.log.Timber
fun initCrashlytics(context: Context, appInfo: AppInfo) {
Fabric.with(Fabric.Builder(context)
.kits(
Crashlytics.Builder()
.core(CrashlyticsCore.Builder()
.disabled(!appInfo.isCrashlyticsEnabled)
.build())
.build()
)
.debuggable(appInfo.isDebug)
.build())
}
class CrashlyticsTree : Timber.Tree() { class CrashlyticsTree : Timber.Tree() {
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
@ -17,9 +29,3 @@ class CrashlyticsTree : Timber.Tree() {
else Crashlytics.logException(t) else Crashlytics.logException(t)
} }
} }
fun initCrashlytics(context: Context) {
Fabric.with(Fabric.Builder(context).kits(
Crashlytics.Builder().core(CrashlyticsCore.Builder().disabled(!BuildConfig.CRASHLYTICS_ENABLED).build()).build()
).debuggable(BuildConfig.DEBUG).build())
}

View File

@ -4,6 +4,7 @@ import io.github.wulkanowy.TestSchedulersProvider
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.reactivex.Single import io.reactivex.Single
import org.junit.Before import org.junit.Before
@ -33,13 +34,16 @@ class LoginFormPresenterTest {
@Mock @Mock
lateinit var analytics: FirebaseAnalyticsHelper lateinit var analytics: FirebaseAnalyticsHelper
@Mock
lateinit var appInfo: AppInfo
private lateinit var presenter: LoginFormPresenter private lateinit var presenter: LoginFormPresenter
@Before @Before
fun initPresenter() { fun initPresenter() {
MockitoAnnotations.initMocks(this) MockitoAnnotations.initMocks(this)
clearInvocations(repository, loginFormView) clearInvocations(repository, loginFormView)
presenter = LoginFormPresenter(TestSchedulersProvider(), repository, errorHandler, analytics, false) presenter = LoginFormPresenter(TestSchedulersProvider(), repository, errorHandler, analytics, appInfo)
presenter.onAttachView(loginFormView) presenter.onAttachView(loginFormView)
} }