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