APP-FE

시각장애인 실내 내비게이션 사용자 앱 (Android)

한이음 2026 · 6팀


개요

BLE 비콘을 체크포인트로 삼아 실내 경로를 음성으로 안내하는 앱입니다. 앱은 RSSI 수집·전송과 음성 입출력만 담당하고, 위치 판정과 경로 탐색은 서버가 수행합니다 (얇은 클라이언트).

항목 값
언어 Kotlin (재사용 파일 4개만 Java, 혼용)
minSdk / targetSdk 26 / 36
UI XML View 시스템 (Compose 미사용)
접근성 TalkBack 전제. 자체 제스처 문법 없음
입력 Android SpeechRecognizer + TalkBack 터치
출력 TTS + 진동

Compose를 쓰지 않는 이유: TalkBack 포커스를 requestFocus() + sendAccessibilityEvent()로 강제 이동해야 하는데, View 시스템이 훨씬 직관적입니다.

상태 구조

앱은 화면이 아니라 상태로 설계합니다. 사용자가 화면을 보지 않으므로, "지금 어떤 상태이고 그것을 어떻게 알리나"가 본체입니다.

READY ──더블탭──▶ LISTENING ──매칭성공──▶ ROUTING ──▶ NAVIGATING ──도착──▶ ARRIVED
  ▲                    │                                  │              │
  └────────────────────┴──────────────────────────────────┴──────────────┘
                          (취소 · 중지 · 종료는 모두 READY로)

1차 개발 범위는 위 5개 상태입니다. DEVIATED · SIGNAL_LOST · LOCATION_UNKNOWN · DISAMBIGUATE · CONFIRM은 2차입니다.

모듈 구조

app/src/main/java/org/mcsmtp/wayfinder/
├── MainActivity.kt                단일 Activity + Fragment 전환
├── state/       NavState.kt · NavStateMachine.kt
├── ui/          Home · Destination · Navigation · Arrival Fragment (.kt)
├── ble/         BleScanner.java(복사) · ScanService.kt(Foreground)
├── speech/      SttManager.kt · SpeechOutput.kt
├── net/         ApiClient.kt · WebSocketManager.java(복사) · model/
├── mock/        MockApi.kt (assets JSON)
└── util/        Haptics.kt · ShakeDetector.kt

.kt와 .java를 한 모듈에 섞어 둡니다. Kotlin에서 Java 클래스를 그대로 호출할 수 있으므로 복사한 4개는 변환하지 않습니다.

재사용 파일

Android_app 리포(실측앱)에서 검증된 코드를 복사해 씁니다.

  • [ ] ble/BleScanner.java — BLE 스캔
  • [ ] WebSocketManager.java — OkHttp WebSocket
  • [ ] data/BeaconDevice.java — 비콘 모델
  • [ ] data/RssiPoint.java — RSSI 시계열

.java 확장자 그대로 둡니다. Kotlin으로 변환하지 마세요 — 이미 검증된 코드이고, 변환 과정에서 버그가 들어갈 수 있습니다.

RssiFilterPipeline.java는 복사하지 않습니다. 필터링은 서버가 수행합니다.

사용 API

우선순위 Method 경로
필수 GET /api/floors/{floorId}/destinations
필수 POST /api/route
필수 WS /ws/navigation
2차 POST /api/locate · /api/route/reroute
여유 GET /api/config

API 확정 전까지는 assets/mock/의 JSON으로 개발합니다. BASE_URL은 빌드 설정으로 분리합니다.

구현 시 주의

# 항목 처리
1 화면 전환 후 포커스 유실 requestFocus() + sendAccessibilityEvent(TYPE_VIEW_FOCUSED)
2 안내 중 화면 꺼짐 FLAG_KEEP_SCREEN_ON
3 STT가 자기 TTS를 인식 마이크 열기 전 TTS 완전 종료 대기
4 백그라운드 BLE 스캔 중단 Foreground Service 필수
5 권한 거부 시 먹통 위치 · 마이크 · 블루투스. 거부 시 음성으로 안내

앱 TTS와 TalkBack이 동시에 발화하면 둘 다 들리지 않습니다. 일반 안내는 announceForAccessibility()로 TalkBack 큐에 위임하고, 자체 TTS(QUEUE_FLUSH)는 계단·이탈·횡단 같은 안전 안내에만 사용합니다.

관련 문서

  • 노션 「사용자 앱 기획」 — 상태 구조 · 입출력 규칙 · 화면 명세 · 기술 구조
  • Dev/info/사용자앱-API-설계.md