Files
VesiscanClinicalAndroid/app/src/main/java/com/example/medilightv2android/services/NotificationService.kt
T
dw.jang a8532917b4 Initial commit: VesiscanBasic Android app
Port of MedilightV2 iOS app to Android with Kotlin + Jetpack Compose.
Includes BLE connectivity, NIRS/Piezo sensor modes, Rive animations,
interactive measurement history charts, and foldable device support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 17:27:00 +09:00

78 lines
2.8 KiB
Kotlin

package com.example.medilightv2android.services
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.example.medilightv2android.R
import com.example.medilightv2android.models.UrgencyLevel
class NotificationService private constructor(private val context: Context) {
companion object {
@Volatile
private var instance: NotificationService? = null
fun getInstance(context: Context): NotificationService =
instance ?: synchronized(this) {
instance ?: NotificationService(context.applicationContext).also { instance = it }
}
private const val CHANNEL_ID = "bladder_urgency"
private const val CHANNEL_NAME = "Bladder Monitoring"
}
private var lastNotifiedUrgency: String? = null
init {
createNotificationChannel()
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
CHANNEL_NAME,
NotificationManager.IMPORTANCE_HIGH
).apply {
description = "Bladder level urgency notifications"
enableVibration(true)
}
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
fun sendUrgencyNotification(urgency: UrgencyLevel, volume: Int) {
val urgencyKey = urgency.rawStringValue
if (urgencyKey == "safe" || urgencyKey == lastNotifiedUrgency) return
lastNotifiedUrgency = urgencyKey
val (title, body) = when (urgency) {
UrgencyLevel.WARNING -> "Bladder Level Rising" to "Estimated $volume ml. Prepare for catheterization."
UrgencyLevel.URGENT -> "Catheterization Needed" to "Estimated $volume ml. Please catheterize now."
UrgencyLevel.SAFE -> return
}
val priority = if (urgency == UrgencyLevel.URGENT)
NotificationCompat.PRIORITY_MAX else NotificationCompat.PRIORITY_HIGH
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle(title)
.setContentText(body)
.setPriority(priority)
.setAutoCancel(true)
.build()
try {
NotificationManagerCompat.from(context).notify(urgencyKey.hashCode(), notification)
} catch (_: SecurityException) { }
}
fun cancelAll() {
lastNotifiedUrgency = null
NotificationManagerCompat.from(context).cancelAll()
}
}