forked from github/wulkanowy-mirror
Fix timetable widget automatic day switching (#267)
This commit is contained in:
parent
4f0021919c
commit
722f8d691a
@ -1,5 +1,6 @@
|
||||
package io.github.wulkanowy.di
|
||||
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.Context
|
||||
import com.firebase.jobdispatcher.FirebaseJobDispatcher
|
||||
import com.firebase.jobdispatcher.GooglePlayDriver
|
||||
@ -37,6 +38,10 @@ internal class AppModule {
|
||||
@Provides
|
||||
fun provideFirebaseAnalyticsHelper(context: Context) = FirebaseAnalyticsHelper(FirebaseAnalytics.getInstance(context))
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideAppWidgetManager(context: Context) = AppWidgetManager.getInstance(context)
|
||||
|
||||
@Singleton
|
||||
@Named("isDebug")
|
||||
@Provides
|
||||
|
@ -64,7 +64,7 @@ class TimetableWidgetFactory(
|
||||
}
|
||||
|
||||
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 {
|
||||
lessons[position].let {
|
||||
|
@ -3,9 +3,11 @@ package io.github.wulkanowy.ui.widgets.timetable
|
||||
import android.app.PendingIntent
|
||||
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_DELETED
|
||||
import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID
|
||||
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS
|
||||
import android.appwidget.AppWidgetProvider
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
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.weekDayName
|
||||
import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.LocalDate.now
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimetableWidgetProvider : AppWidgetProvider() {
|
||||
class TimetableWidgetProvider : BroadcastReceiver() {
|
||||
|
||||
@Inject
|
||||
lateinit var appWidgetManager: AppWidgetManager
|
||||
|
||||
@Inject
|
||||
lateinit var sharedPref: SharedPrefHelper
|
||||
@ -42,89 +48,79 @@ class TimetableWidgetProvider : AppWidgetProvider() {
|
||||
const val BUTTON_PREV = "buttonPrev"
|
||||
|
||||
const val BUTTON_RESET = "buttonReset"
|
||||
|
||||
fun createWidgetKey(appWidgetId: Int) = "timetable_widget_$appWidgetId"
|
||||
}
|
||||
|
||||
override fun onUpdate(context: Context?, appWidgetManager: AppWidgetManager?, appWidgetIds: IntArray?) {
|
||||
appWidgetIds?.forEach {
|
||||
val widgetKey = "timetable_widget_$it"
|
||||
checkSavedWidgetDate(widgetKey)
|
||||
|
||||
val savedDate = LocalDate.ofEpochDay(sharedPref.getLong(widgetKey, 0))
|
||||
context?.run {
|
||||
RemoteViews(packageName, R.layout.widget_timetable).apply {
|
||||
setTextViewText(R.id.timetableWidgetDay, savedDate.weekDayName.capitalize())
|
||||
setTextViewText(R.id.timetableWidgetDate, savedDate.toFormattedString())
|
||||
setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty)
|
||||
setRemoteAdapter(R.id.timetableWidgetList, Intent(context, TimetableWidgetService::class.java)
|
||||
.apply { action = widgetKey })
|
||||
setOnClickPendingIntent(R.id.timetableWidgetNext, createNavIntent(context, it, it, appWidgetIds, BUTTON_NEXT))
|
||||
setOnClickPendingIntent(R.id.timetableWidgetPrev, createNavIntent(context, -it, it, appWidgetIds, BUTTON_PREV))
|
||||
createNavIntent(context, Int.MAX_VALUE, it, appWidgetIds, BUTTON_RESET).let { intent ->
|
||||
setOnClickPendingIntent(R.id.timetableWidgetDate, intent)
|
||||
setOnClickPendingIntent(R.id.timetableWidgetDay, intent)
|
||||
}
|
||||
setPendingIntentTemplate(R.id.timetableWidgetList,
|
||||
PendingIntent.getActivity(context, 1, MainActivity.getStartIntent(context).apply {
|
||||
putExtra(EXTRA_START_MENU_INDEX, 3)
|
||||
}, FLAG_UPDATE_CURRENT))
|
||||
|
||||
}.also { view ->
|
||||
appWidgetManager?.apply {
|
||||
notifyAppWidgetViewDataChanged(it, R.id.timetableWidgetList)
|
||||
updateAppWidget(it, view)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
when (intent.action) {
|
||||
ACTION_APPWIDGET_UPDATE -> onUpdate(context, intent)
|
||||
ACTION_APPWIDGET_DELETED -> onDelete(intent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onUpdate(context: Context, intent: Intent) {
|
||||
if (intent.getStringExtra(EXTRA_BUTTON_TYPE) === null) {
|
||||
intent.getIntArrayExtra(EXTRA_APPWIDGET_IDS).forEach { appWidgetId ->
|
||||
updateWidget(context, appWidgetId, now().nextOrSameSchoolDay)
|
||||
}
|
||||
} 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)
|
||||
setTextViewText(R.id.timetableWidgetDay, date.weekDayName.capitalize())
|
||||
setTextViewText(R.id.timetableWidgetDate, date.toFormattedString())
|
||||
setRemoteAdapter(R.id.timetableWidgetList, Intent(context, TimetableWidgetService::class.java)
|
||||
.apply { action = createWidgetKey(appWidgetId) })
|
||||
setOnClickPendingIntent(R.id.timetableWidgetNext, createNavIntent(context, appWidgetId, appWidgetId, BUTTON_NEXT))
|
||||
setOnClickPendingIntent(R.id.timetableWidgetPrev, createNavIntent(context, -appWidgetId, appWidgetId, BUTTON_PREV))
|
||||
createNavIntent(context, Int.MAX_VALUE, appWidgetId, BUTTON_RESET).also {
|
||||
setOnClickPendingIntent(R.id.timetableWidgetDate, it)
|
||||
setOnClickPendingIntent(R.id.timetableWidgetDay, it)
|
||||
}
|
||||
setPendingIntentTemplate(R.id.timetableWidgetList,
|
||||
PendingIntent.getActivity(context, 1, MainActivity.getStartIntent(context).apply {
|
||||
putExtra(EXTRA_START_MENU_INDEX, 3)
|
||||
}, FLAG_UPDATE_CURRENT))
|
||||
}.also {
|
||||
sharedPref.putLong(createWidgetKey(appWidgetId), date.toEpochDay(), true)
|
||||
appWidgetManager.apply {
|
||||
notifyAppWidgetViewDataChanged(appWidgetId, R.id.timetableWidgetList)
|
||||
updateAppWidget(appWidgetId, it)
|
||||
}
|
||||
}
|
||||
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 {
|
||||
private fun createNavIntent(context: Context, code: Int, appWidgetId: Int, buttonType: String): PendingIntent {
|
||||
return PendingIntent.getBroadcast(context, code,
|
||||
Intent(context, TimetableWidgetProvider::class.java).apply {
|
||||
action = ACTION_APPWIDGET_UPDATE
|
||||
putExtra(EXTRA_APPWIDGET_IDS, widgetIds)
|
||||
putExtra(EXTRA_BUTTON_TYPE, buttonType)
|
||||
putExtra(EXTRA_TOGGLED_WIDGET_ID, widgetId)
|
||||
putExtra(EXTRA_TOGGLED_WIDGET_ID, appWidgetId)
|
||||
}, FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
|
||||
private fun checkSavedWidgetDate(widgetKey: String) {
|
||||
sharedPref.run {
|
||||
if (getLong(widgetKey, -1) == -1L) {
|
||||
putLong(widgetKey, LocalDate.now().nextOrSameSchoolDay.toEpochDay(), true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user