package com.vgmlr.wedge
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.widget.RemoteViews
import androidx.core.graphics.toColorInt
import androidx.core.net.toUri
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch
import android.app.AlarmManager
class NoteWidgetProvider : AppWidgetProvider() {
private var alarmReceiver: WedgeAlarmReceiver? = null
override fun onEnabled(context: Context) {
super.onEnabled(context)
scheduleNextMinuteCheck(context)
}
override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent)
scheduleNextMinuteCheck(context)
}
private fun scheduleNextMinuteCheck(context: Context) {
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(context, WedgeAlarmReceiver::class.java).apply {
action = "com.vgmlr.wedge.ACTION_CHECK_ALARM"
}
val pendingIntent = PendingIntent.getBroadcast(
context, 2026, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
val triggerAt = System.currentTimeMillis() + 60000L
try {
if (android.os.Build.VERSION.SDK_INT < 31 || alarmManager.canScheduleExactAlarms()) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt, pendingIntent)
} else {
alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt, pendingIntent)
}
} catch (_: SecurityException) {
alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAt, pendingIntent)
}
}
override fun onDisabled(context: Context) {
super.onDisabled(context)
alarmReceiver?.let {
try { context.applicationContext.unregisterReceiver(it) } catch (_: Exception) {}
alarmReceiver = null
}
}
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
val prefs = PreferenceManager(context)
CoroutineScope(Dispatchers.IO).launch {
val bgColor = prefs.widgetBgColor.firstOrNull() ?: "#000000"
for (appWidgetId in appWidgetIds) {
val views = RemoteViews(context.packageName, R.layout.widget_layout)
val serviceIntent = Intent(context, WedgeWidgetService::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
data = this.toUri(Intent.URI_INTENT_SCHEME).toUri()
}
@Suppress("DEPRECATION")
views.setRemoteAdapter(R.id.widget_list, serviceIntent)
val clickIntent = Intent(context, MainActivity::class.java)
val clickPI = PendingIntent.getActivity(
context, 0, clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
)
views.setPendingIntentTemplate(R.id.widget_list, clickPI)
try {
views.setInt(R.id.widget_root, "setBackgroundColor", bgColor.toColorInt())
} catch (_: Exception) {
views.setInt(R.id.widget_root, "setBackgroundColor", "#000000".toColorInt())
}
@Suppress("DEPRECATION")
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_list)
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
}
companion object {
fun triggerUpdate(context: Context) {
val appWidgetManager = AppWidgetManager.getInstance(context)
val componentName = ComponentName(context, NoteWidgetProvider::class.java)
val ids = appWidgetManager.getAppWidgetIds(componentName)
for (id in ids) {
@Suppress("DEPRECATION")
appWidgetManager.notifyAppWidgetViewDataChanged(id, R.id.widget_list)
}
val intent = Intent(context, NoteWidgetProvider::class.java).apply {
action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
}
context.sendBroadcast(intent)
}
}
}