1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2025-01-19 00:26:45 -06:00

Fix timetable widget automatic day switching (#267)

This commit is contained in:
Rafał Borcz 2019-03-07 16:38:34 +01:00 committed by Mikołaj Pich
parent 4f0021919c
commit 722f8d691a
3 changed files with 76 additions and 75 deletions

View File

@ -1,5 +1,6 @@
package io.github.wulkanowy.di package io.github.wulkanowy.di
import android.appwidget.AppWidgetManager
import android.content.Context import android.content.Context
import com.firebase.jobdispatcher.FirebaseJobDispatcher import com.firebase.jobdispatcher.FirebaseJobDispatcher
import com.firebase.jobdispatcher.GooglePlayDriver import com.firebase.jobdispatcher.GooglePlayDriver
@ -37,6 +38,10 @@ internal class AppModule {
@Provides @Provides
fun provideFirebaseAnalyticsHelper(context: Context) = FirebaseAnalyticsHelper(FirebaseAnalytics.getInstance(context)) fun provideFirebaseAnalyticsHelper(context: Context) = FirebaseAnalyticsHelper(FirebaseAnalytics.getInstance(context))
@Singleton
@Provides
fun provideAppWidgetManager(context: Context) = AppWidgetManager.getInstance(context)
@Singleton @Singleton
@Named("isDebug") @Named("isDebug")
@Provides @Provides

View File

@ -64,7 +64,7 @@ class TimetableWidgetFactory(
} }
override fun getViewAt(position: Int): RemoteViews? { override fun getViewAt(position: Int): RemoteViews? {
if (position == INVALID_POSITION || lessons.getOrNull(position) == null) return null if (position == INVALID_POSITION || lessons.getOrNull(position) === null) return null
return RemoteViews(context.packageName, R.layout.item_widget_timetable).apply { return RemoteViews(context.packageName, R.layout.item_widget_timetable).apply {
lessons[position].let { lessons[position].let {

View File

@ -3,9 +3,11 @@ package io.github.wulkanowy.ui.widgets.timetable
import android.app.PendingIntent import android.app.PendingIntent
import android.app.PendingIntent.FLAG_UPDATE_CURRENT import android.app.PendingIntent.FLAG_UPDATE_CURRENT
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_DELETED
import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS
import android.appwidget.AppWidgetProvider import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.widget.RemoteViews import android.widget.RemoteViews
@ -22,9 +24,13 @@ import io.github.wulkanowy.utils.previousSchoolDay
import io.github.wulkanowy.utils.toFormattedString import io.github.wulkanowy.utils.toFormattedString
import io.github.wulkanowy.utils.weekDayName import io.github.wulkanowy.utils.weekDayName
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.now
import javax.inject.Inject import javax.inject.Inject
class TimetableWidgetProvider : AppWidgetProvider() { class TimetableWidgetProvider : BroadcastReceiver() {
@Inject
lateinit var appWidgetManager: AppWidgetManager
@Inject @Inject
lateinit var sharedPref: SharedPrefHelper lateinit var sharedPref: SharedPrefHelper
@ -42,89 +48,79 @@ class TimetableWidgetProvider : AppWidgetProvider() {
const val BUTTON_PREV = "buttonPrev" const val BUTTON_PREV = "buttonPrev"
const val BUTTON_RESET = "buttonReset" const val BUTTON_RESET = "buttonReset"
fun createWidgetKey(appWidgetId: Int) = "timetable_widget_$appWidgetId"
} }
override fun onUpdate(context: Context?, appWidgetManager: AppWidgetManager?, appWidgetIds: IntArray?) { override fun onReceive(context: Context, intent: Intent) {
appWidgetIds?.forEach { AndroidInjection.inject(this, context)
val widgetKey = "timetable_widget_$it" when (intent.action) {
checkSavedWidgetDate(widgetKey) ACTION_APPWIDGET_UPDATE -> onUpdate(context, intent)
ACTION_APPWIDGET_DELETED -> onDelete(intent)
}
}
val savedDate = LocalDate.ofEpochDay(sharedPref.getLong(widgetKey, 0)) private fun onUpdate(context: Context, intent: Intent) {
context?.run { if (intent.getStringExtra(EXTRA_BUTTON_TYPE) === null) {
RemoteViews(packageName, R.layout.widget_timetable).apply { intent.getIntArrayExtra(EXTRA_APPWIDGET_IDS).forEach { appWidgetId ->
setTextViewText(R.id.timetableWidgetDay, savedDate.weekDayName.capitalize()) updateWidget(context, appWidgetId, now().nextOrSameSchoolDay)
setTextViewText(R.id.timetableWidgetDate, savedDate.toFormattedString()) }
} else {
val buttonType = intent.getStringExtra(EXTRA_BUTTON_TYPE)
val toggledWidgetId = intent.getIntExtra(EXTRA_TOGGLED_WIDGET_ID, 0)
val savedDate = LocalDate.ofEpochDay(sharedPref.getLong(createWidgetKey(toggledWidgetId), 0))
val date = when (buttonType) {
BUTTON_RESET -> now().nextOrSameSchoolDay
BUTTON_NEXT -> savedDate.nextSchoolDay
BUTTON_PREV -> savedDate.previousSchoolDay
else -> now().nextOrSameSchoolDay
}
if (!buttonType.isNullOrBlank()) analytics.logEvent("changed_timetable_widget_day", "button" to buttonType)
updateWidget(context, toggledWidgetId, date)
}
}
private fun onDelete(intent: Intent) {
intent.getIntExtra(EXTRA_APPWIDGET_ID, 0).let {
if (it != 0) sharedPref.delete(createWidgetKey(it))
}
}
private fun updateWidget(context: Context, appWidgetId: Int, date: LocalDate) {
RemoteViews(context.packageName, R.layout.widget_timetable).apply {
setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty) setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty)
setTextViewText(R.id.timetableWidgetDay, date.weekDayName.capitalize())
setTextViewText(R.id.timetableWidgetDate, date.toFormattedString())
setRemoteAdapter(R.id.timetableWidgetList, Intent(context, TimetableWidgetService::class.java) setRemoteAdapter(R.id.timetableWidgetList, Intent(context, TimetableWidgetService::class.java)
.apply { action = widgetKey }) .apply { action = createWidgetKey(appWidgetId) })
setOnClickPendingIntent(R.id.timetableWidgetNext, createNavIntent(context, it, it, appWidgetIds, BUTTON_NEXT)) setOnClickPendingIntent(R.id.timetableWidgetNext, createNavIntent(context, appWidgetId, appWidgetId, BUTTON_NEXT))
setOnClickPendingIntent(R.id.timetableWidgetPrev, createNavIntent(context, -it, it, appWidgetIds, BUTTON_PREV)) setOnClickPendingIntent(R.id.timetableWidgetPrev, createNavIntent(context, -appWidgetId, appWidgetId, BUTTON_PREV))
createNavIntent(context, Int.MAX_VALUE, it, appWidgetIds, BUTTON_RESET).let { intent -> createNavIntent(context, Int.MAX_VALUE, appWidgetId, BUTTON_RESET).also {
setOnClickPendingIntent(R.id.timetableWidgetDate, intent) setOnClickPendingIntent(R.id.timetableWidgetDate, it)
setOnClickPendingIntent(R.id.timetableWidgetDay, intent) setOnClickPendingIntent(R.id.timetableWidgetDay, it)
} }
setPendingIntentTemplate(R.id.timetableWidgetList, setPendingIntentTemplate(R.id.timetableWidgetList,
PendingIntent.getActivity(context, 1, MainActivity.getStartIntent(context).apply { PendingIntent.getActivity(context, 1, MainActivity.getStartIntent(context).apply {
putExtra(EXTRA_START_MENU_INDEX, 3) putExtra(EXTRA_START_MENU_INDEX, 3)
}, FLAG_UPDATE_CURRENT)) }, FLAG_UPDATE_CURRENT))
}.also {
}.also { view -> sharedPref.putLong(createWidgetKey(appWidgetId), date.toEpochDay(), true)
appWidgetManager?.apply { appWidgetManager.apply {
notifyAppWidgetViewDataChanged(it, R.id.timetableWidgetList) notifyAppWidgetViewDataChanged(appWidgetId, R.id.timetableWidgetList)
updateAppWidget(it, view) updateAppWidget(appWidgetId, it)
}
}
} }
} }
} }
override fun onReceive(context: Context?, intent: Intent?) { private fun createNavIntent(context: Context, code: Int, appWidgetId: Int, buttonType: String): PendingIntent {
AndroidInjection.inject(this, context)
intent?.let {
val widgetKey = "timetable_widget_${it.getIntExtra(EXTRA_TOGGLED_WIDGET_ID, 0)}"
it.getStringExtra(EXTRA_BUTTON_TYPE).let { button ->
when (button) {
BUTTON_NEXT -> {
LocalDate.ofEpochDay(sharedPref.getLong(widgetKey, 0)).nextSchoolDay
.let { date -> sharedPref.putLong(widgetKey, date.toEpochDay(), true) }
}
BUTTON_PREV -> {
LocalDate.ofEpochDay(sharedPref.getLong(widgetKey, 0)).previousSchoolDay
.let { date -> sharedPref.putLong(widgetKey, date.toEpochDay(), true) }
}
BUTTON_RESET -> sharedPref.putLong(widgetKey, LocalDate.now().nextOrSameSchoolDay.toEpochDay(), true)
}
button?.also { btn ->
if (btn.isNotBlank()) {
analytics.logEvent("changed_timetable_widget_day", "button" to button)
}
}
}
}
super.onReceive(context, intent)
}
override fun onDeleted(context: Context?, appWidgetIds: IntArray?) {
appWidgetIds?.forEach {
sharedPref.delete("timetable_widget_$it")
}
}
private fun createNavIntent(context: Context, code: Int, widgetId: Int, widgetIds: IntArray, buttonType: String): PendingIntent {
return PendingIntent.getBroadcast(context, code, return PendingIntent.getBroadcast(context, code,
Intent(context, TimetableWidgetProvider::class.java).apply { Intent(context, TimetableWidgetProvider::class.java).apply {
action = ACTION_APPWIDGET_UPDATE action = ACTION_APPWIDGET_UPDATE
putExtra(EXTRA_APPWIDGET_IDS, widgetIds)
putExtra(EXTRA_BUTTON_TYPE, buttonType) putExtra(EXTRA_BUTTON_TYPE, buttonType)
putExtra(EXTRA_TOGGLED_WIDGET_ID, widgetId) putExtra(EXTRA_TOGGLED_WIDGET_ID, appWidgetId)
}, FLAG_UPDATE_CURRENT) }, FLAG_UPDATE_CURRENT)
} }
}
private fun checkSavedWidgetDate(widgetKey: String) {
sharedPref.run {
if (getLong(widgetKey, -1) == -1L) {
putLong(widgetKey, LocalDate.now().nextOrSameSchoolDay.toEpochDay(), true)
}
}
}
}