TimetableWidget.kt 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package com.ethosa.ktc.ui.widgets
  2. import android.annotation.SuppressLint
  3. import android.app.PendingIntent
  4. import android.appwidget.AppWidgetManager
  5. import android.appwidget.AppWidgetProvider
  6. import android.content.ComponentName
  7. import android.content.Context
  8. import android.content.Intent
  9. import android.content.SharedPreferences
  10. import android.os.Build
  11. import android.widget.RemoteViews
  12. import com.ethosa.ktc.R
  13. import com.ethosa.ktc.college.CollegeApi
  14. import com.ethosa.ktc.college.CollegeCallback
  15. import com.ethosa.ktc.college.timetable.Week
  16. import com.ethosa.ktc.ui.activities.MainActivity
  17. import com.google.gson.Gson
  18. import okhttp3.Call
  19. import okhttp3.Response
  20. import java.util.*
  21. /**
  22. * Implementation of App Widget functionality.
  23. */
  24. class TimetableWidget : AppWidgetProvider() {
  25. private val college = CollegeApi()
  26. private var preferences: SharedPreferences? = null
  27. override fun onUpdate(
  28. context: Context,
  29. appWidgetManager: AppWidgetManager,
  30. appWidgetIds: IntArray
  31. ) {
  32. preferences = context.getSharedPreferences("com.ethosa.ktc", Context.MODE_PRIVATE)
  33. // There may be multiple widgets active, so update all of them
  34. for (appWidgetId in appWidgetIds) {
  35. updateAppWidget(context, appWidgetManager, appWidgetId)
  36. }
  37. }
  38. /**
  39. * Update timetable for current widget
  40. */
  41. @SuppressLint("UnspecifiedImmutableFlag")
  42. private fun updateWidgetPendingIntent(
  43. context: Context?,
  44. appWidgetId: Int
  45. ): PendingIntent {
  46. val intent = Intent(context, TimetableWidget::class.java)
  47. val ids = AppWidgetManager.getInstance(context)
  48. .getAppWidgetIds(ComponentName(context!!, TimetableWidget::class.java))
  49. intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
  50. intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
  51. return PendingIntent.getBroadcast(
  52. context,
  53. appWidgetId,
  54. intent,
  55. when {
  56. Build.VERSION.SDK_INT >= 31 -> PendingIntent.FLAG_MUTABLE
  57. else -> PendingIntent.FLAG_UPDATE_CURRENT
  58. })
  59. }
  60. /**
  61. * Open app with pending intent
  62. */
  63. @SuppressLint("UnspecifiedImmutableFlag")
  64. private fun openAppPendingIntent(
  65. context: Context?,
  66. appWidgetId: Int
  67. ): PendingIntent {
  68. val intent = Intent(context, MainActivity::class.java)
  69. return PendingIntent.getActivity(
  70. context,
  71. appWidgetId,
  72. intent,
  73. when {
  74. Build.VERSION.SDK_INT >= 31 -> PendingIntent.FLAG_MUTABLE
  75. else -> PendingIntent.FLAG_UPDATE_CURRENT
  76. })
  77. }
  78. @SuppressLint("RemoteViewLayout")
  79. private fun updateAppWidget(
  80. context: Context,
  81. appWidgetManager: AppWidgetManager,
  82. appWidgetId: Int
  83. ) {
  84. // Construct the RemoteViews object
  85. val views = RemoteViews(context.packageName, R.layout.timetable_widget)
  86. views.setOnClickPendingIntent(
  87. R.id.timetable_widget_reload,
  88. updateWidgetPendingIntent(context, appWidgetId)
  89. )
  90. views.setOnClickPendingIntent(
  91. R.id.timetable_widget_background,
  92. openAppPendingIntent(context, appWidgetId)
  93. )
  94. // Load last group ID
  95. val groupId = preferences?.getInt("group", 0)
  96. val calendar = Calendar.getInstance()
  97. val weekday = calendar.get(Calendar.DAY_OF_WEEK)
  98. college.fetchTimetable(groupId!!, object : CollegeCallback {
  99. @SuppressLint("SetTextI18n")
  100. override fun onResponse(call: Call, response: Response) {
  101. // Parse JSON
  102. val json = response.body?.string()
  103. val timetable = Gson().fromJson(json, Week::class.java)
  104. // Get current day timetable
  105. val day =
  106. when {
  107. weekday > 1 -> timetable.days[weekday-2]
  108. weekday > 0 -> timetable.days[1]
  109. else -> timetable.days[0]
  110. }
  111. // Setup widget
  112. views.setTextViewText(R.id.timetable_widget_title, day.title)
  113. views.removeAllViews(R.id.timetable_widget_lessons)
  114. // Setup views
  115. for (l in day.lessons) {
  116. println(l)
  117. // Load lesson data
  118. val lesson = RemoteViews(context.packageName, R.layout.widget_lesson)
  119. lesson.setTextViewText(R.id.lesson_title, l.title)
  120. lesson.setTextViewText(R.id.lesson_classroom, l.classroom)
  121. lesson.setTextViewText(R.id.lesson_number, l.time[0])
  122. lesson.setTextViewText(R.id.lesson_from, l.time[1])
  123. lesson.setTextViewText(R.id.lesson_to, l.time[2])
  124. lesson.setTextViewText(R.id.lesson_teacher, l.teacher)
  125. views.addView(R.id.timetable_widget_lessons, lesson)
  126. }
  127. // Update widget
  128. appWidgetManager.updateAppWidget(appWidgetId, views)
  129. }
  130. }, null)
  131. appWidgetManager.updateAppWidget(appWidgetId, views)
  132. }
  133. }