app/src/main/java/dev/equwal/inkupdate/Notify.kt (2642 bytes)
1 // SPDX-License-Identifier: GPL-3.0-or-later 2 // Copyright (c) 2026 equwal 3 package dev.equwal.inkupdate 4 5 import android.app.Notification 6 import android.app.NotificationChannel 7 import android.app.NotificationManager 8 import android.app.PendingIntent 9 import android.content.Context 10 import android.content.Intent 11 import android.net.Uri 12 13 /** 14 * One notification for each app that has an update. 15 * 16 * The id comes from the package name, so a later check replaces the old 17 * notification instead of adding a second one. The caller tells a person about 18 * a version once. Nothing else makes a notification. 19 */ 20 object Notify { 21 22 private const val CHANNEL = "updates" 23 24 /** 25 * Tells the person about one update. 26 * 27 * @return true when the notification went out. It does not go out while 28 * the person keeps notifications off. The caller must then ask 29 * again after the next check, so the update is not lost. 30 */ 31 fun update(context: Context, w: Watched, r: Result.Update): Boolean { 32 val m = context.getSystemService(NotificationManager::class.java) ?: return false 33 if (!m.areNotificationsEnabled()) return false 34 channel(m, context) 35 36 val b = Notification.Builder(context, CHANNEL) 37 .setSmallIcon(R.drawable.ic_notify) 38 .setContentTitle(w.title + " " + r.versionName + " is ready") 39 .setContentText("From " + r.source) 40 .setAutoCancel(true) 41 .setContentIntent(open(context, r.page, w.pkg.hashCode())) 42 43 if (r.apk != null) { 44 b.addAction( 45 Notification.Action.Builder( 46 null as android.graphics.drawable.Icon?, 47 "Download", 48 open(context, r.apk, w.pkg.hashCode() + 1) 49 ).build() 50 ) 51 } 52 m.notify(w.pkg.hashCode(), b.build()) 53 return true 54 } 55 56 private fun channel(m: NotificationManager, context: Context) { 57 m.createNotificationChannel( 58 NotificationChannel( 59 CHANNEL, 60 context.getString(R.string.channel_updates), 61 NotificationManager.IMPORTANCE_DEFAULT 62 ) 63 ) 64 } 65 66 /** Opens a page in whatever app handles it: F-Droid, Play, or a browser. */ 67 private fun open(context: Context, url: String, id: Int): PendingIntent { 68 val i = Intent(Intent.ACTION_VIEW, Uri.parse(url)) 69 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 70 return PendingIntent.getActivity( 71 context, id, i, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE 72 ) 73 } 74 }