rename example
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
package com.bitcointxoko.gudariwallet.util
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import com.bitcointxoko.gudariwallet.MainActivity
|
||||
import com.bitcointxoko.gudariwallet.R
|
||||
|
||||
object NotificationHelper {
|
||||
|
||||
// ── Intent extra key — read by MainActivity ───────────────────────────────
|
||||
// Public so MainActivity can reference it without a magic string.
|
||||
const val EXTRA_PAYMENT_HASH = "extra_payment_hash"
|
||||
|
||||
// ── Channel setup ─────────────────────────────────────────────────────────
|
||||
|
||||
fun createChannels(context: Context) {
|
||||
val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
|
||||
nm.createNotificationChannel(
|
||||
NotificationChannel(
|
||||
NotificationConstants.CHANNEL_PAYMENTS,
|
||||
"Payments",
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
).apply {
|
||||
description = "Incoming and outgoing Lightning payment alerts"
|
||||
enableVibration(true)
|
||||
enableLights(true)
|
||||
}
|
||||
)
|
||||
|
||||
nm.createNotificationChannel(
|
||||
NotificationChannel(
|
||||
NotificationConstants.CHANNEL_SERVICE_STATUS,
|
||||
"Wallet Monitor",
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
).apply {
|
||||
description = "Background service monitoring for incoming payments"
|
||||
setShowBadge(false)
|
||||
enableVibration(false)
|
||||
setSound(null, null)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// ── User-facing notifications ─────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Posts a high-priority notification for an incoming payment.
|
||||
* Tapping opens MainActivity and navigates directly to the payment detail
|
||||
* screen for [paymentHash].
|
||||
*/
|
||||
fun notifyPaymentReceived(context: Context, amountSats: Long, memo: String?, paymentHash: String) {
|
||||
val title = "Payment received · +$amountSats sats"
|
||||
val text = if (!memo.isNullOrBlank()) memo else "No memo"
|
||||
|
||||
val notification = NotificationCompat.Builder(context, NotificationConstants.CHANNEL_PAYMENTS)
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setContentTitle(title)
|
||||
.setContentText(text)
|
||||
.setAutoCancel(true)
|
||||
.setContentIntent(mainActivityPendingIntent(context, paymentHash))
|
||||
// BigTextStyle shows the full memo when the notification is expanded,
|
||||
// in case it is long enough to be truncated in the compact view.
|
||||
.setStyle(
|
||||
NotificationCompat.BigTextStyle()
|
||||
.bigText(text)
|
||||
.setSummaryText("+$amountSats sats")
|
||||
)
|
||||
.build()
|
||||
|
||||
notify(context, NotificationConstants.NOTIF_ID_PAYMENT_RECEIVED, notification)
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts a default-priority notification for a successfully sent payment.
|
||||
* Tapping opens MainActivity and navigates directly to the payment detail
|
||||
* screen for [paymentHash].
|
||||
*/
|
||||
fun notifyPaymentSent(context: Context, amountSats: Long, paymentHash: String) {
|
||||
val title = "Payment sent"
|
||||
val text = "−$amountSats sats"
|
||||
notify(
|
||||
context,
|
||||
NotificationConstants.NOTIF_ID_PAYMENT_SENT,
|
||||
buildPaymentNotification(context, title, text, paymentHash)
|
||||
)
|
||||
}
|
||||
|
||||
// ── Foreground service notification ───────────────────────────────────────
|
||||
|
||||
fun buildServiceNotification(context: Context): Notification {
|
||||
return NotificationCompat.Builder(context, NotificationConstants.CHANNEL_SERVICE_STATUS)
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setContentTitle("Gudari Wallet")
|
||||
.setContentText("Monitoring for incoming payments")
|
||||
.setOngoing(true)
|
||||
.setSilent(true)
|
||||
.setShowWhen(false)
|
||||
.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)
|
||||
// Service notification taps open the app with no specific destination
|
||||
.setContentIntent(mainActivityPendingIntent(context, paymentHash = null))
|
||||
.build()
|
||||
}
|
||||
|
||||
// ── Dismiss ───────────────────────────────────────────────────────────────
|
||||
|
||||
fun cancel(context: Context, notificationId: Int) {
|
||||
NotificationManagerCompat.from(context).cancel(notificationId)
|
||||
}
|
||||
|
||||
// ── Private helpers ───────────────────────────────────────────────────────
|
||||
|
||||
private fun buildPaymentNotification(
|
||||
context: Context,
|
||||
title: String,
|
||||
text: String,
|
||||
paymentHash: String
|
||||
): Notification {
|
||||
return NotificationCompat.Builder(context, NotificationConstants.CHANNEL_PAYMENTS)
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setContentTitle(title)
|
||||
.setContentText(text)
|
||||
.setAutoCancel(true)
|
||||
.setContentIntent(mainActivityPendingIntent(context, paymentHash))
|
||||
.build()
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a PendingIntent that opens MainActivity.
|
||||
*
|
||||
* If [paymentHash] is non-null, it is attached as [EXTRA_PAYMENT_HASH].
|
||||
* MainActivity reads this in onCreate / onNewIntent and navigates to the
|
||||
* payment detail screen.
|
||||
*
|
||||
* FLAG_UPDATE_CURRENT ensures that if a second notification arrives before
|
||||
* the first is tapped, the hash is updated to the latest payment.
|
||||
* Each notification ID gets its own requestCode so they don't overwrite
|
||||
* each other's extras.
|
||||
*/
|
||||
private fun mainActivityPendingIntent(context: Context, paymentHash: String?): PendingIntent {
|
||||
val intent = Intent(context, MainActivity::class.java).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
if (paymentHash != null) {
|
||||
putExtra(EXTRA_PAYMENT_HASH, paymentHash)
|
||||
}
|
||||
}
|
||||
// Use the hash's hashCode as requestCode so each unique payment gets
|
||||
// its own PendingIntent — prevents one notification's tap from
|
||||
// overwriting another's extras.
|
||||
val requestCode = paymentHash?.hashCode() ?: 0
|
||||
return PendingIntent.getActivity(
|
||||
context,
|
||||
requestCode,
|
||||
intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
}
|
||||
|
||||
private fun notify(context: Context, id: Int, notification: Notification) {
|
||||
runCatching {
|
||||
NotificationManagerCompat.from(context).notify(id, notification)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user