feat(dev): 앱 종료 시 자동 페어링 해제 (다중 폰×기기 테스트 workflow 자동화)
배경 (사용자 관찰):
· 폰 A ↔ 기기 A 페어링 후 앱 종료 · 폰 B 로 기기 A 접근 시 실패.
· 폰 B 에서 "저장된 기기" 삭제해도 기기 A 는 폰 A bond 만 신뢰 · 물리 리셋 필요.
· 매번 수동으로 Settings > "페어링 해제" 누르기 번거로움 · 잊기 쉬움.
수정:
1. GreenZoneConstants.autoUnbondOnAppExit: Boolean = false (신규)
dev-mode 용 flag · 앱 종료 시 자동 unbond 여부.
2. MainActivity.onDestroy() 훅
flag ON + 연결된 기기 있으면 → BleManager.disconnectAndUnbond() 자동 실행.
기기측 msr(unbond+reboot) + 폰측 removeBond · fresh state 유지.
3. PiezoMonitoringView Settings (dev-mode 조건부)
"Delete Pairing" 버튼 아래에 토글 카드: "앱 종료 시 자동 페어링 해제"
설명: "[dev] 다중 폰×기기 테스트용 · 종료 시 unbond"
효과:
· 폰 A 앱 종료 → 자동 unbond msr 전송 → 기기 A clean
· 폰 B 접근 시 fresh pairing 즉시 성공
· 매뉴얼 clean 도 여전히 Delete Pairing 버튼으로 즉시 실행 가능 (기존)
주의:
· default OFF (일반 사용자 flow 는 bond 유지가 UX 이점)
· onDestroy 는 앱 강제종료 시 스킵 가능 · 정상 종료 (뒤로가기/스와이프) 는 커버
· try/catch silent · 종료 시점 실패는 UC-05 (필수기능 아님)
빌드: BUILD SUCCESSFUL 1m 15s.
This commit is contained in:
@@ -82,6 +82,28 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 2026-08-12: 테스트 세션 종료 시 자동 페어링 해제 (dev-mode 용).
|
||||
*
|
||||
* `GreenZoneConstants.autoUnbondOnAppExit` ON 이고 · 연결된 기기가 있으면
|
||||
* `disconnectAndUnbond()` 실행 → 기기측 msr(unbond+reboot) + 폰측 removeBond.
|
||||
* 다음 실행 (다른 폰) 에서 fresh pairing 가능하도록 clean state 유지.
|
||||
*
|
||||
* onDestroy 는 앱 강제종료 시 스킵될 수 있으나 · 정상 종료 (뒤로가기 · 홈 스와이프
|
||||
* 후 recent 앱에서 swipe away) 는 커버. dev-mode 테스트 workflow 는 대부분 정상 종료.
|
||||
*/
|
||||
override fun onDestroy() {
|
||||
try {
|
||||
if (com.medithings.vesiscan.managers.GreenZoneConstants.autoUnbondOnAppExit) {
|
||||
val ble = com.medithings.vesiscan.ble.BleManager.getInstance(applicationContext)
|
||||
if (ble.isConnected.value) {
|
||||
ble.disconnectAndUnbond()
|
||||
}
|
||||
}
|
||||
} catch (_: Exception) { /* silent · 종료 시점 · UC-05 */ }
|
||||
super.onDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -71,6 +71,20 @@ object GreenZoneConstants {
|
||||
@Volatile var placementGuideMode: PlacementGuideMode = PlacementGuideMode.SIMPLE
|
||||
@Volatile var alignmentAlgo: AlignmentAlgo = AlignmentAlgo.V1 // default V1 (일반 사용자). V2 (Method D) 는 clinical alignment session 전용.
|
||||
|
||||
/**
|
||||
* 2026-08-12: 테스트 세션 종료 시 자동 페어링 해제 (dev-mode 용).
|
||||
*
|
||||
* ON 시 · MainActivity.onDestroy() 에서 연결된 기기가 있으면 자동으로
|
||||
* disconnectAndUnbond() 호출. 여러 폰 × 여러 기기 테스트 환경에서 매번 수동으로
|
||||
* 페어링 해제할 필요 없이 앱 종료만 하면 기기 clean state 유지.
|
||||
*
|
||||
* 시나리오: 폰 A 로 기기 A 테스트 → 앱 종료 → 자동 unbond msr 전송 →
|
||||
* 기기 A 는 폰 A bond 삭제 → 다음에 폰 B 가 기기 A 와 fresh pairing 성공.
|
||||
*
|
||||
* default OFF (일반 사용자 flow 는 bond 유지가 UX 이점 · 잘못 켜지면 매번 재페어링).
|
||||
*/
|
||||
@Volatile var autoUnbondOnAppExit: Boolean = false
|
||||
|
||||
/** Posture pitch 임계값 (deg). |pitch| > 이 값 → LYING, ≤ 이 값 → NON_LYING. dev 모드에서 조정 가능. */
|
||||
@Volatile var pitchLyingThreshold: Float = 25f
|
||||
|
||||
|
||||
@@ -2403,6 +2403,37 @@ fun PiezoMonitoringView(appState: AppState) {
|
||||
)
|
||||
}
|
||||
|
||||
// 2026-08-12: 다중 폰 × 다중 기기 테스트 workflow 자동화 (dev-mode 전용).
|
||||
// ON 시 · MainActivity.onDestroy() 에서 자동으로 disconnectAndUnbond().
|
||||
// 다음 실행 (다른 폰) 에서 fresh pairing 성공 · 매번 수동 unbond 불필요.
|
||||
if (appState.isDevMode) {
|
||||
Spacer(modifier = Modifier.height(6.dp))
|
||||
var autoUnbond by remember {
|
||||
mutableStateOf(com.medithings.vesiscan.managers.GreenZoneConstants.autoUnbondOnAppExit)
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.background(MlPrimary.copy(alpha = 0.05f), RoundedCornerShape(10.dp))
|
||||
.padding(horizontal = 12.dp, vertical = 6.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text("앱 종료 시 자동 페어링 해제",
|
||||
fontSize = 13.sp, fontWeight = FontWeight.SemiBold)
|
||||
Text("[dev] 다중 폰×기기 테스트용 · 종료 시 unbond",
|
||||
fontSize = 10.sp, color = MlSecondaryText)
|
||||
}
|
||||
Switch(
|
||||
checked = autoUnbond,
|
||||
onCheckedChange = {
|
||||
autoUnbond = it
|
||||
com.medithings.vesiscan.managers.GreenZoneConstants.autoUnbondOnAppExit = it
|
||||
},
|
||||
colors = SwitchDefaults.colors(checkedTrackColor = MlPrimary),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
Reference in New Issue
Block a user