Add app/src/main/java/space/bloggin/mercies
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
package space.bloggin.mercies
|
||||
|
||||
import android.Manifest
|
||||
import android.app.AlarmManager
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.appwidget.AppWidgetProvider
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.widget.RemoteViews
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import java.time.LocalDate
|
||||
import java.util.Calendar
|
||||
|
||||
object Daily {
|
||||
private const val CH = "mercies"
|
||||
|
||||
fun open(ctx: Context, tab: String, code: Int): PendingIntent {
|
||||
val i = Intent(ctx, MainActivity::class.java).apply {
|
||||
action = "space.bloggin.mercies.OPEN_$tab"; putExtra("tab", tab)
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
}
|
||||
return PendingIntent.getActivity(ctx, code, i, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
|
||||
}
|
||||
|
||||
private fun alarm(ctx: Context, which: String, on: Boolean, h: Int, m: Int, code: Int) {
|
||||
val am = ctx.getSystemService(AlarmManager::class.java)
|
||||
val pi = PendingIntent.getBroadcast(ctx, code, Intent(ctx, DailyReceiver::class.java).putExtra("which", which),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
|
||||
am.cancel(pi)
|
||||
if (!on) return
|
||||
val cal = Calendar.getInstance().apply {
|
||||
set(Calendar.HOUR_OF_DAY, h); set(Calendar.MINUTE, m); set(Calendar.SECOND, 0)
|
||||
if (timeInMillis <= System.currentTimeMillis()) add(Calendar.DAY_OF_YEAR, 1)
|
||||
}
|
||||
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.timeInMillis, AlarmManager.INTERVAL_DAY, pi)
|
||||
}
|
||||
|
||||
fun schedule(ctx: Context) {
|
||||
val p = Prefs.get(ctx)
|
||||
alarm(ctx, "eve", p.eve, p.eveH, p.eveM, 11)
|
||||
alarm(ctx, "morn", true, if (p.morn) p.mornH else 0, if (p.morn) p.mornM else 3, 12) // also refreshes the widget each day
|
||||
}
|
||||
|
||||
fun notify(ctx: Context, which: String) {
|
||||
if (Build.VERSION.SDK_INT >= 33 && ContextCompat.checkSelfPermission(ctx, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) return
|
||||
val nm = ctx.getSystemService(NotificationManager::class.java)
|
||||
nm.createNotificationChannel(NotificationChannel(CH, "Gentle reminders", NotificationManager.IMPORTANCE_DEFAULT))
|
||||
val n = if (which == "eve") {
|
||||
val alreadyToday = Store.get(ctx).notesOn(LocalDate.now()).isNotEmpty()
|
||||
if (alreadyToday) return
|
||||
NotificationCompat.Builder(ctx, CH).setSmallIcon(R.drawable.ic_notify)
|
||||
.setContentTitle("The jar is open")
|
||||
.setContentText(Prompts.forDate(LocalDate.now()))
|
||||
.setContentIntent(open(ctx, "jar", 21)).setAutoCancel(true).build()
|
||||
} else {
|
||||
val k = Store.get(ctx).kindToday()
|
||||
NotificationCompat.Builder(ctx, CH).setSmallIcon(R.drawable.ic_notify)
|
||||
.setContentTitle("Today's kindness")
|
||||
.setContentText(Kindness.all[k.idx])
|
||||
.setStyle(NotificationCompat.BigTextStyle().bigText(Kindness.all[k.idx]))
|
||||
.setContentIntent(open(ctx, "kind", 22)).setAutoCancel(true).build()
|
||||
}
|
||||
nm.notify(if (which == "eve") 1 else 2, n)
|
||||
}
|
||||
}
|
||||
|
||||
class DailyReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(ctx: Context, intent: Intent) {
|
||||
val which = intent.getStringExtra("which") ?: return
|
||||
MercyWidget.refresh(ctx)
|
||||
val p = Prefs.get(ctx)
|
||||
if ((which == "eve" && p.eve) || (which == "morn" && p.morn)) Daily.notify(ctx, which)
|
||||
}
|
||||
}
|
||||
|
||||
class BootReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(ctx: Context, intent: Intent) { Daily.schedule(ctx); MercyWidget.refresh(ctx) }
|
||||
}
|
||||
|
||||
class MercyWidget : AppWidgetProvider() {
|
||||
override fun onUpdate(ctx: Context, mgr: AppWidgetManager, ids: IntArray) = update(ctx, mgr, ids)
|
||||
|
||||
companion object {
|
||||
fun update(ctx: Context, mgr: AppWidgetManager, ids: IntArray) {
|
||||
val store = Store.get(ctx)
|
||||
val k = store.kindToday()
|
||||
val count = store.noteCount()
|
||||
for (id in ids) {
|
||||
val rv = RemoteViews(ctx.packageName, R.layout.widget_mercy)
|
||||
rv.setTextViewText(R.id.w_text, Kindness.all[k.idx])
|
||||
rv.setTextViewText(R.id.w_foot, (if (k.status == 1) "Done ❀ " else "") + if (count == 1) "1 mercy in the jar" else "$count mercies in the jar")
|
||||
rv.setOnClickPendingIntent(R.id.w_root, Daily.open(ctx, "kind", 23))
|
||||
mgr.updateAppWidget(id, rv)
|
||||
}
|
||||
}
|
||||
fun refresh(ctx: Context) = try {
|
||||
val mgr = AppWidgetManager.getInstance(ctx)
|
||||
update(ctx, mgr, mgr.getAppWidgetIds(ComponentName(ctx, MercyWidget::class.java)))
|
||||
} catch (_: Exception) {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user