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
|
@Composable
|
||||||
|
|||||||
@@ -71,6 +71,20 @@ object GreenZoneConstants {
|
|||||||
@Volatile var placementGuideMode: PlacementGuideMode = PlacementGuideMode.SIMPLE
|
@Volatile var placementGuideMode: PlacementGuideMode = PlacementGuideMode.SIMPLE
|
||||||
@Volatile var alignmentAlgo: AlignmentAlgo = AlignmentAlgo.V1 // default V1 (일반 사용자). V2 (Method D) 는 clinical alignment session 전용.
|
@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 모드에서 조정 가능. */
|
/** Posture pitch 임계값 (deg). |pitch| > 이 값 → LYING, ≤ 이 값 → NON_LYING. dev 모드에서 조정 가능. */
|
||||||
@Volatile var pitchLyingThreshold: Float = 25f
|
@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))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
|
HorizontalDivider(modifier = Modifier.padding(vertical = dividerPadding))
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|||||||
Reference in New Issue
Block a user