ble: 일반 사용자는 KnownDeviceStore 저장 0개 + 펌웨어 미수신 경고
다중 기기 페어링 저장은 Clinical 흐름 전용. 일반 사용자는 매 세션 fresh scan + pair — 저장 기능 자체 미노출. - BleManager.connect 성공 시: ClinicalSessionStore.inClinicalFlow 체크 → false 면 KnownDeviceStore.add() skip - DeviceScanView: 같은 조건으로 Saved Devices 섹션 노출 X. knownDevices = emptyList() → 기존 단일 디바이스 리스트 UX + FirmwareWarningBanner 케이스 추가: 연결 후 8초간 mid? 응답 미수신 → 빨강 경고 "펌웨어 응답 없음 — 펌웨어 호환 문제 가능" 사용자가 정확한 원인 파악 가능 (구버전 != 응답 자체 안 옴).
This commit is contained in:
@@ -869,11 +869,15 @@ class BleManager private constructor(private val context: Context) {
|
||||
cancelReconnectTimer()
|
||||
debugLogger.connected(connectedDeviceName.value, gatt.device.address)
|
||||
|
||||
try {
|
||||
com.example.medilightv2android.services.KnownDeviceStore.add(
|
||||
context, gatt.device.address, connectedDeviceName.value
|
||||
)
|
||||
} catch (_: Exception) {}
|
||||
// Clinical 흐름에서만 KnownDeviceStore 영속화. 일반 사용자는
|
||||
// 매 세션 fresh scan + pair — 저장 0개.
|
||||
if (com.example.medilightv2android.services.ClinicalSessionStore.inClinicalFlow) {
|
||||
try {
|
||||
com.example.medilightv2android.services.KnownDeviceStore.add(
|
||||
context, gatt.device.address, connectedDeviceName.value
|
||||
)
|
||||
} catch (_: Exception) {}
|
||||
}
|
||||
|
||||
// MTU 247 요청 (reb: 208B 패킷 드롭 방지)
|
||||
// onMtuChanged 콜백에서 discoverServices 호출
|
||||
|
||||
+39
-15
@@ -13,7 +13,11 @@ import androidx.compose.material.icons.filled.Warning
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
@@ -22,38 +26,58 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.example.medilightv2android.ble.BleManager
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
/**
|
||||
* 펌웨어 구버전 경고 배너 — PlacementGuide / PiezoMonitoring 상단에 노출.
|
||||
* isFirmwareOutdated 가 true 일 때만 렌더. 사용자가 측정 안 됨 원인을 즉시 파악하도록.
|
||||
* 펌웨어 상태 배너 — PlacementGuide / PiezoMonitoring 상단에 노출.
|
||||
*
|
||||
* 표시 케이스:
|
||||
* (1) 펌웨어 구버전 (build < MIN_FIRMWARE_BUILD) — 주황 경고
|
||||
* (2) 연결 후 8초 넘게 mid? 응답 미수신 — 빨강 경고 (펌웨어가 mid 미지원)
|
||||
* (3) 정상 또는 미연결 — 안 보임
|
||||
*/
|
||||
@Composable
|
||||
fun FirmwareWarningBanner(bleManager: BleManager, modifier: Modifier = Modifier) {
|
||||
val fw by bleManager.firmwareVersion
|
||||
if (!bleManager.isFirmwareOutdated) return
|
||||
val isConnected by bleManager.isConnected
|
||||
|
||||
// (2) 연결됐는데 일정 시간 동안 펌웨어 미수신 추적
|
||||
var timedOut by remember { mutableStateOf(false) }
|
||||
LaunchedEffect(isConnected, fw) {
|
||||
timedOut = false
|
||||
if (isConnected && fw.isEmpty()) {
|
||||
delay(8_000)
|
||||
if (bleManager.isConnected.value && bleManager.firmwareVersion.value.isEmpty()) {
|
||||
timedOut = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val outdated = bleManager.isFirmwareOutdated
|
||||
if (!outdated && !timedOut) return
|
||||
|
||||
val bgColor = if (outdated) Color(0xFFFF9500) else Color(0xFFD32F2F)
|
||||
val title = if (outdated) "펌웨어 업데이트 필요" else "펌웨어 응답 없음"
|
||||
val subtitle = if (outdated) {
|
||||
"현재: $fw · 필요: VBTFW${"%04d".format(BleManager.MIN_FIRMWARE_BUILD)} 이상. 측정이 정상 동작하지 않을 수 있습니다."
|
||||
} else {
|
||||
"연결됐으나 mid? 응답 미수신. 펌웨어 호환 문제 가능 — 측정 안 될 수 있음."
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 6.dp)
|
||||
.clip(RoundedCornerShape(10.dp))
|
||||
.background(Color(0xFFFF9500))
|
||||
.background(bgColor)
|
||||
.padding(horizontal = 12.dp, vertical = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(Icons.Default.Warning, "Warning", tint = Color.White)
|
||||
Spacer(modifier = Modifier.width(10.dp))
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
"펌웨어 업데이트 필요",
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = Color.White
|
||||
)
|
||||
Text(
|
||||
"현재: $fw · 필요: VBTFW${"%04d".format(BleManager.MIN_FIRMWARE_BUILD)} 이상. 측정이 정상 동작하지 않을 수 있습니다.",
|
||||
fontSize = 11.sp,
|
||||
color = Color.White.copy(alpha = 0.9f)
|
||||
)
|
||||
Text(title, fontSize = 13.sp, fontWeight = FontWeight.Bold, color = Color.White)
|
||||
Text(subtitle, fontSize = 11.sp, color = Color.White.copy(alpha = 0.9f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -52,7 +52,11 @@ fun DeviceScanView(appState: AppState) {
|
||||
var connectingDeviceAddress by remember { mutableStateOf<String?>(null) }
|
||||
var permissionsGranted by remember { mutableStateOf(false) }
|
||||
|
||||
var knownDevices by remember { mutableStateOf(KnownDeviceStore.getAll(context)) }
|
||||
// Clinical 흐름에서만 다중 기기 저장/표시 — 일반 사용자는 fresh scan & pair.
|
||||
val isClinicalFlow = com.example.medilightv2android.services.ClinicalSessionStore.inClinicalFlow
|
||||
var knownDevices by remember {
|
||||
mutableStateOf(if (isClinicalFlow) KnownDeviceStore.getAll(context) else emptyList())
|
||||
}
|
||||
var pendingDelete by remember { mutableStateOf<KnownDevice?>(null) }
|
||||
val knownAddresses = knownDevices.map { it.address }.toSet()
|
||||
val newDevices = bleManager.discoveredDevices
|
||||
|
||||
Reference in New Issue
Block a user