Skip to content

Commit b249afd

Browse files
committed
fix: connection status notification
1 parent 4d33b68 commit b249afd

2 files changed

Lines changed: 64 additions & 5 deletions

File tree

app/src/main/java/com/sameerasw/airsync/service/AirSyncService.kt

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,26 @@ class AirSyncService : Service() {
5050
// Network state tracking
5151
private var networkCallback: ConnectivityManager.NetworkCallback? = null
5252

53+
private val connectionStatusListener: (Boolean) -> Unit = { _ ->
54+
scope.launch {
55+
updateNotification()
56+
}
57+
}
58+
5359
override fun onCreate() {
5460
super.onCreate()
5561
Log.d(TAG, "AirSyncService created")
5662
createNotificationChannel()
5763
MacDeviceStatusManager.startMonitoring(this)
5864
registerNetworkCallback()
65+
WebSocketUtil.registerConnectionStatusListener(connectionStatusListener)
66+
67+
// Monitor connection status, auto-reconnect, and battery status to update notification live
68+
scope.launch {
69+
MacDeviceStatusManager.macDeviceStatus.collect {
70+
updateNotification()
71+
}
72+
}
5973
}
6074

6175
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
@@ -240,6 +254,15 @@ class AirSyncService : Service() {
240254
}
241255
}
242256

257+
private fun updateNotification() {
258+
try {
259+
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
260+
notificationManager.notify(NOTIFICATION_ID, buildNotification())
261+
} catch (e: Exception) {
262+
Log.e(TAG, "Error updating foreground notification", e)
263+
}
264+
}
265+
243266
private fun buildNotification(): Notification {
244267
val intent = Intent(this, MainActivity::class.java)
245268
val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)
@@ -258,18 +281,49 @@ class AirSyncService : Service() {
258281
.setCategory(NotificationCompat.CATEGORY_SERVICE)
259282
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
260283

261-
if (isScanning && connectedDeviceName == null) {
284+
val isConnected = WebSocketUtil.isConnected()
285+
val isAuto = WebSocketUtil.isAutoReconnecting()
286+
val isConnecting = WebSocketUtil.isConnecting()
287+
288+
val dataStoreManager = DataStoreManager.getInstance(applicationContext)
289+
val lastDevice = runBlocking { dataStoreManager.getLastConnectedDevice().first() }
290+
val macStatus = MacDeviceStatusManager.macDeviceStatus.value
291+
292+
if (isConnected && lastDevice != null) {
293+
val name = lastDevice.name
262294
builder.setContentTitle(getString(R.string.app_name))
263-
builder.setContentText(getString(R.string.no_device_connected))
264-
} else {
265-
val name = connectedDeviceName ?: "Mac"
295+
296+
val batteryText = macStatus?.let { status ->
297+
val level = status.battery.level
298+
if (level >= 0) {
299+
val pct = level.coerceIn(0, 100)
300+
if (status.battery.isCharging) " ($pct% Charging)" else " ($pct%)"
301+
} else ""
302+
} ?: ""
303+
304+
builder.setContentText(getString(R.string.connected_to_device, name) + batteryText)
305+
builder.addAction(
306+
R.drawable.rounded_link_off_24,
307+
getString(R.string.disconnect),
308+
disconnectPendingIntent
309+
)
310+
} else if (com.sameerasw.airsync.data.ble.BleGattServer.isAnyAuthenticated() && lastDevice != null) {
266311
builder.setContentTitle(getString(R.string.app_name))
267-
builder.setContentText(getString(R.string.connected_to_device, name))
312+
builder.setContentText("Connected to ${lastDevice.name} via Bluetooth")
268313
builder.addAction(
269314
R.drawable.rounded_link_off_24,
270315
getString(R.string.disconnect),
271316
disconnectPendingIntent
272317
)
318+
} else if (isAuto) {
319+
builder.setContentTitle("Reconnecting...")
320+
builder.setContentText(if (isConnecting) "Trying to connect to Mac..." else "Waiting to retry connection...")
321+
} else if (isConnecting) {
322+
builder.setContentTitle("Connecting...")
323+
builder.setContentText("Connecting to last device...")
324+
} else {
325+
builder.setContentTitle(getString(R.string.app_name))
326+
builder.setContentText(getString(R.string.no_device_connected))
273327
}
274328

275329
return builder.build()
@@ -279,6 +333,7 @@ class AirSyncService : Service() {
279333

280334
override fun onDestroy() {
281335
Log.d(TAG, "AirSyncService destroyed")
336+
WebSocketUtil.unregisterConnectionStatusListener(connectionStatusListener)
282337

283338
networkCallback?.let {
284339
try {

app/src/main/java/com/sameerasw/airsync/utils/WebSocketUtil.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ object WebSocketUtil {
4141
private fun updateConnectedStatus(status: Boolean) {
4242
isConnected.set(status)
4343
_connectionStateFlow.value = status
44+
notifyConnectionStatusListeners(status)
4445
}
4546

4647
// Transport state: true after OkHttp onOpen, false after closing/failure/disconnect
@@ -147,6 +148,7 @@ object WebSocketUtil {
147148

148149
isConnecting.set(true)
149150
handshakeCompleted.set(false)
151+
notifyConnectionStatusListeners(false)
150152

151153
// Reset manual disconnect flag on manual attempt
152154
if (manualAttempt) {
@@ -820,6 +822,7 @@ object WebSocketUtil {
820822
autoReconnectJob = null
821823
autoReconnectAttempts = 0
822824
autoReconnectStartTime = 0L
825+
notifyConnectionStatusListeners(false)
823826
}
824827

825828
fun isAutoReconnecting(): Boolean = autoReconnectActive.get()
@@ -868,6 +871,7 @@ object WebSocketUtil {
868871
if (autoReconnectActive.get()) return // already running
869872
autoReconnectActive.set(true)
870873
autoReconnectStartTime = System.currentTimeMillis()
874+
notifyConnectionStatusListeners(false)
871875
Log.d(TAG, "Starting Smart Auto-Reconnect strategy")
872876

873877
autoReconnectJob?.cancel()

0 commit comments

Comments
 (0)