From 6dfe5e6281e26e48a4d8a59f92a504b55e509991 Mon Sep 17 00:00:00 2001 From: jjangddu Date: Tue, 11 Aug 2026 16:08:25 +0900 Subject: [PATCH] =?UTF-8?q?fix(ble):=20disconnect()=20=EC=8B=9C=20isConnec?= =?UTF-8?q?ted.value=20=EC=A6=89=EC=8B=9C=20false=20=EB=B0=98=EC=98=81=20(?= =?UTF-8?q?=ED=99=88=20"=EC=97=B0=EA=B2=B0=EB=90=A8"=20stuck)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 증상 (사용자 관찰 2026-08-11): · 설정 → Disconnect 눌러 연결 해제 후 goHome() → 홈 화면에 여전히 "● 연결됨" chip 표시. 실제 BLE 는 끊긴 상태. 원인: · BleManager.disconnect() 가 gatt.disconnect() 만 호출 · isConnected.value 는 시스템 콜백 (onConnectionStateChange STATE_DISCONNECTED) 이 도착해야 false 로 갱신됨. 콜백은 비동기 (수 초 지연 가능). · 그 사이 goHome() 실행 → HomeView 는 getter (isDemoMode || bleManager.isConnected.value) 로 값 읽음 · 아직 true → "연결됨" 잘못 표시. · PiezoMonitoringView:2385 의 `appState.isDeviceConnected = false` 는 setter 가 no-op (2026-08-03 fix 이후 getter-only) 라 무효. 수정: · disconnect() 첫머리에서 isConnected.value = false 즉시 세팅 (UI 층 즉시 반영). · 실제 GATT teardown 은 콜백에서 정상 진행 (idempotent). 재연결 시엔 그때 콜백으로 다시 true 되므로 로직 훼손 없음. · disconnectAndUnbond() 는 이미 postDelayed 안에서 false 세팅 하고 있으나 이건 사용자 요청 시엔 300ms 정도 지연이 커도 UI 오동작 없음 (즉시 goHome 없음). 빌드: BUILD SUCCESSFUL 20s. installDemoDebug 완료. --- app/src/main/java/com/medithings/vesiscan/ble/BleManager.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/com/medithings/vesiscan/ble/BleManager.kt b/app/src/main/java/com/medithings/vesiscan/ble/BleManager.kt index d6b72ac..ac93476 100644 --- a/app/src/main/java/com/medithings/vesiscan/ble/BleManager.kt +++ b/app/src/main/java/com/medithings/vesiscan/ble/BleManager.kt @@ -564,6 +564,12 @@ class BleManager private constructor(private val context: Context) { stopWatchdog() connectionTimer?.let { handler.removeCallbacks(it) } connectionTimer = null + // 2026-08-11: 즉시 UI 반영 (홈 화면 "연결됨" stuck 방지). + // gatt.disconnect() 는 비동기 · onConnectionStateChange 콜백이 몇 초 뒤 도착. + // 그 사이 사용자가 goHome() 하면 isConnected.value 가 true 로 남아 UI 오동작. + // Fix: 사용자 명시적 disconnect 요청이므로 UI state 즉시 false 반영. + // 실제 GATT teardown 은 콜백에서 정상 진행 (idempotent). + isConnected.value = false bluetoothGatt?.disconnect() com.medithings.vesiscan.services.BleForegroundService.stop(context) }