Notification channel v3: HIGH + 60ms tick, lockscreen public (silent channel delayed the heads-up pill)

This commit is contained in:
avi 2026-09-17 20:51:19 -05:00
commit c942865879

View file

@ -34,9 +34,10 @@ import com.shonar.R
object RecordingNotificationHelper { object RecordingNotificationHelper {
// v2: fresh id — sidesteps any stuck/user-locked importance lingering on // v2: fresh id — sidesteps any stuck/user-locked importance lingering on
// the old id. Created HIGH on every service start (see ensureChannel). // the old id. Created HIGH on every service start (see ensureChannel).
const val CHANNEL_ID = "shonar_recording_ongoing_v2" const val CHANNEL_ID = "shonar_recording_ongoing_v3"
private const val LEGACY_CHANNEL_ID = "shonar_recording" private const val LEGACY_CHANNEL_ID = "shonar_recording"
private const val LEGACY_CHANNEL_ID_V1 = "shonar_recording_ongoing" private const val LEGACY_CHANNEL_ID_V1 = "shonar_recording_ongoing"
private const val LEGACY_CHANNEL_ID_V2 = "shonar_recording_ongoing_v2"
const val NOTIFICATION_ID = 1001 const val NOTIFICATION_ID = 1001
@Volatile @Volatile
@ -51,20 +52,29 @@ object RecordingNotificationHelper {
val mgr = ctx.getSystemService(NotificationManager::class.java) val mgr = ctx.getSystemService(NotificationManager::class.java)
runCatching { mgr.deleteNotificationChannel(LEGACY_CHANNEL_ID) } runCatching { mgr.deleteNotificationChannel(LEGACY_CHANNEL_ID) }
runCatching { mgr.deleteNotificationChannel(LEGACY_CHANNEL_ID_V1) } runCatching { mgr.deleteNotificationChannel(LEGACY_CHANNEL_ID_V1) }
val existing = runCatching { mgr.getNotificationChannel(CHANNEL_ID) }.getOrNull() runCatching { mgr.deleteNotificationChannel(LEGACY_CHANNEL_ID_V2) }
if (existing == null) { // A fully SILENT high-importance channel is classified "minimally
mgr.createNotificationChannel( // impactful" by Android 14+ SystemUI, whose heads-up popup then waits
NotificationChannel( // on an interaction-decay timer — the popup pill showed ~10s after the
CHANNEL_ID, // tap while recording itself started in 0.2s (verified 2026-09-17 via
ctx.getString(R.string.notif_channel_recording), // StackScroll timestamps). One short 60ms tick makes the notification
NotificationManager.IMPORTANCE_HIGH, // unambiguously alerting: the pill pops with the tap. Sound stays off;
).apply { // a beep at record start would be worse than the tick.
description = ctx.getString(R.string.notif_channel_recording_desc) // Note: createNotificationChannel over an existing id refreshes
setSound(null, null) // vibration/sound (app-controlled), only importance stays user-locked.
enableVibration(false) mgr.createNotificationChannel(
}, NotificationChannel(
) CHANNEL_ID,
} ctx.getString(R.string.notif_channel_recording),
NotificationManager.IMPORTANCE_HIGH,
).apply {
description = ctx.getString(R.string.notif_channel_recording_desc)
setSound(null, null)
vibrationPattern = longArrayOf(0, 60)
enableVibration(true)
lockscreenVisibility = Notification.VISIBILITY_PUBLIC
},
)
channelReady = true channelReady = true
} }