Skip to content

Android Setup

Barbelic Android 앱은 iOS 앱과 같은 구조의 Capacitor 셸이다. WebView는 번들 대신 원격 정규 origin https://www.barbelic.com을 열고, Kakao·Google·Apple 로그인은 iOS와 동일한 native bridge v1 계약으로 처리한다. 네이티브 셸은 Kotlin(android/app/src/main/java/com/dekerd/barbelic/)이다.

준비 및 실행

  • Android Studio(2025.2.1 이상)와 SDK Platform 36, Build-Tools 36, Platform-Tools. 헤드리스로는 cmdline-toolssdkmanager "platforms;android-36" "build-tools;36.0.0" "platform-tools".
  • JDK 21 (Android Studio 번들 JBR 또는 Microsoft OpenJDK 21). JAVA_HOME을 맞춘다.
  • android/local.propertiessdk.dir=<SDK 경로> (슬래시 경로, git 제외).
  • 실기기는 USB 디버깅을 허용하고 adb devices에 보여야 한다.
bash
npm ci
npm run build
npm run android:sync
npm run android:build        # android/app/build/outputs/apk/debug/app-debug.apk
adb install -r android/app/build/outputs/apk/debug/app-debug.apk

npm run android:open은 Android Studio에서 android/를 연다. android:synccapacitor.settings.gradle·app/capacitor.build.gradle· app/src/main/assets/{public,capacitor.config.json}을 다시 만든다(모두 git 제외). dist-vite/가 비어 있으면 cap sync가 실패하므로 npm run build가 먼저다 — 실제 화면은 원격 origin에서 오고 번들 자산은 자리만 채운다.

Build configuration

android/app/build.gradle이 iOS xcconfig와 같은 세 값을 BuildConfig로 주입한다.

  • BARBELIC_SERVER_ORIGIN: WebView가 여는 정규 origin https://www.barbelic.com
  • BARBELIC_SUPABASE_AUTH_ORIGIN: authorize URL을 허용할 정확한 Supabase origin
  • BARBELIC_CALLBACK_SCHEME: custom URL scheme barbelic (AndroidManifest.xmlbarbelic://auth/callback intent-filter에도 같은 값이 들어간다)

MainActivityCapConfig.Builder.setServerUrl로 원격 origin을 지정한다 — iOS MainViewController.instanceDescriptor()와 같은 역할이다. Supabase Dashboard의 Redirect URLs에 등록된 barbelic://auth/callback**은 iOS와 공유한다.

식별자: applicationId·namespace com.dekerd.barbelic, 표시명 Barbelic, 런처 아이콘은 iOS AppIcon 비트맵을 정사각 축소한 mipmap-*/ic_launcher.png와 검정 바탕 adaptive icon(mipmap-anydpi-v26/ic_launcher.xml)이다.

iOS와 다른 점

  • 외부 인증 창: ASWebAuthenticationSession 대신 Chrome Custom Tabs. Google은 임베디드 WebView OAuth를 차단하므로 브라우저 탭이 필수다.
  • Apple 로그인: Android에는 시스템 시트가 없어 Supabase authorize 웹 플로우 (Services ID com.dekerd.barbelic.web)로 처리한다. 웹 측 코드는 같다.
  • 보안 저장소: Keychain 대신 Android Keystore(AES-GCM) 키로 암호화한 값을 앱 전용 SharedPreferences에 둔다. allowBackup=false.
  • 웹→네이티브 전송: window.barbelicNative.postMessage(JSON.stringify(...)) (androidx.webkit WebMessageListener, 허용 origin은 서버 origin 하나). 웹 barbelicNav.notifyNative가 WebKit 핸들러가 없을 때 이 경로를 쓴다.
  • 세션 이미지 저장(sessionDownloadImage)은 첫 출시 범위에서 제외한다(오너 D5). 네이티브는 메시지를 받으면 안내 토스트만 띄운다.
  • 시스템바: 테마 windowBackground·status/navigation bar 색이 검정이고 Capacitor SystemBars 플러그인 style: dark(밝은 아이콘). WebView 140+에서는 inset을 CSS env(safe-area-inset-*)로 통과시키고(viewport-fit=cover), 그 이전 WebView는 Capacitor가 WebView에 패딩을 준다 — 어느 쪽이든 바 영역은 검정이다.
  • 시스템 뒤로가기: 웹 barbelicNav가 레이어마다 history.pushState({ lg })를 쌓으므로 history.state.lgroot가 아니면 history.back()(웹 popstate가 레이어를 닫음), 루트면 moveTaskToBack — 다른 문서로 되돌아가지 않는다. 키보드가 떠 있으면 IME가 먼저 뒤로가기를 소비한다.
  • 키보드: windowSoftInputMode="adjustResize" + Capacitor IME inset 처리로 WebView가 줄어든다(innerHeight 감소). iOS처럼 덮지 않는다.

실기기 확인

  • 앱 아이콘·스플래시(검정 바탕)가 뜨고 WebView가 https://www.barbelic.com/을 여는가
  • chrome://inspect(debug 빌드)에서 window.barbelicNativewindow.__barbelicNativeCapabilities가 보이는가
  • 로그인 화면 세 버튼이 Custom Tabs를 열고, 취소 시 pending 상태가 풀리는가
  • 성공 callback이 barbelic://auth/callback으로 앱에 돌아와 홈이 다시 뜨는가
  • 앱을 완전히 종료 후 다시 열어도 로그인이 복원되는가
  • 시스템 뒤로가기가 웹 레이어(메뉴·세션·운동)를 닫고, 루트에서는 앱을 내리는가
  • 운동 진행 중 화면이 꺼지지 않는가(workoutActive)
  • 키보드가 입력란을 가리지 않는가(adjustResize + edge-to-edge)

Windows에서 Gradle 빌드·에뮬레이터·실기기 설치가 모두 가능하다(iOS와 달리 Mac 불필요). 서명·번들·Play 등록은 android-release.md를 따른다.