Skip to content

Luca-HyeongRok/RunningTracker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

29 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Running Tracker ๐Ÿƒโ€โ™‚๏ธ

Running Tracker๋Š” ์‚ฌ์šฉ์ž์˜ ๋Ÿฌ๋‹ ํ™œ๋™์„ ๊ธฐ๋กํ•˜๊ณ  ์‹œ๊ฐ์ ์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”
์•ˆ๋“œ๋กœ์ด๋“œ ๋Ÿฌ๋‹ ํŠธ๋ž˜์ปค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค.
Kotlin๊ณผ Jetpack Compose๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ MVVM ์•„ํ‚คํ…์ฒ˜๋ฅผ ์ ์šฉํ•ด ๊ฐœ๋ฐœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋Ÿฌ๋‹ ์ค‘ ๊ฒฝ๊ณผ ์‹œ๊ฐ„๊ณผ ์ด๋™ ๊ฒฝ๋กœ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ,
๋‹จ์ˆœํ•˜๊ณ  ์ง๊ด€์ ์ธ UI๋ฅผ ๋ชฉํ‘œ๋กœ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


โœจ ์ฃผ์š” ๊ธฐ๋Šฅ (Key Features)

  • ๋Ÿฌ๋‹ ํƒ€์ด๋จธ

    • ViewModel์—์„œ ์ง์ ‘ ๊ด€๋ฆฌ๋˜๋Š” ์ฝ”๋ฃจํ‹ด ๊ธฐ๋ฐ˜ ํƒ€์ด๋จธ
    • Start / Pause / Stop ๋™์ž‘ ๋ถ„๋ฆฌ
    • Pause ํ›„ Start ์‹œ ์‹œ๊ฐ„ ์œ ์ง€, Stop ์‹œ์—๋งŒ ์ดˆ๊ธฐํ™”
  • ์‹ค์‹œ๊ฐ„ ์œ„์น˜ ๊ฒฝ๋กœ ํ‘œ์‹œ

    • Google Maps Compose๋ฅผ ํ™œ์šฉํ•œ ๋Ÿฌ๋‹ ๊ฒฝ๋กœ ์‹œ๊ฐํ™”
    • ๋Ÿฌ๋‹ ์ค‘ ์ด๋™ํ•œ ๊ฒฝ๋กœ๋ฅผ Polyline์œผ๋กœ ์ง€๋„์— ํ‘œ์‹œ
  • ์ƒํƒœ ๊ธฐ๋ฐ˜ UI

    • UI๋Š” ViewModel์˜ StateFlow๋งŒ ๊ตฌ๋…
    • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ UI ๋กœ์ง์„ ๋ช…ํ™•ํžˆ ๋ถ„๋ฆฌ
  • ์˜์กด์„ฑ ์ฃผ์ž…

    • Koin์„ ํ™œ์šฉํ•œ ViewModel ๋ฐ ์œ„์น˜ ํด๋ผ์ด์–ธํŠธ ์ฃผ์ž…
    • ํ…Œ์ŠคํŠธ ๋ฐ ํ™•์žฅ์— ์šฉ์ดํ•œ ๊ตฌ์กฐ

๐Ÿ›  ๊ธฐ์ˆ  ์Šคํƒ (Tech Stack)

  • Language: Kotlin
  • UI: Jetpack Compose (Material3)
  • Architecture: MVVM
  • State Management: StateFlow
  • Asynchronous: Kotlin Coroutines
  • Dependency Injection: Koin
  • Maps: Google Maps Compose
  • Location: FusedLocationProviderClient

๐Ÿš€ ์„ค์น˜ ๋ฐ ์‹คํ–‰ (Getting Started)

1) ์‚ฌ์ „ ์ค€๋น„

  • Android Studio (์ตœ์‹  ์•ˆ์ • ๋ฒ„์ „ ๊ถŒ์žฅ)
  • JDK 17 (Android Studio ๋‚ด์žฅ JDK ์‚ฌ์šฉ ๊ฐ€๋Šฅ)
  • Google Maps API Key

2) ํ”„๋กœ์ ํŠธ ํด๋ก 

git clone <repo-url>
cd RunningTracker

3) Google Maps API ํ‚ค ์„ค์ •

app/src/main/res/values/google_maps_key.xml ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  ์•„๋ž˜ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”.

<resources>
    <string name="google_maps_key" translatable="false">YOUR_API_KEY</string>
</resources>

์ถœ์‹œ ๊ธฐ์ค€ ๊ถŒ์žฅ ์„ค์ •:

  • ๋””๋ฒ„๊ทธ/๋ฆด๋ฆฌ์Šค API ํ‚ค๋ฅผ ๋ถ„๋ฆฌํ•ด์„œ ์‚ฌ์šฉ
  • Google Cloud Console์—์„œ Maps SDK for Android ํ™œ์„ฑํ™”
  • API ํ‚ค ์ œํ•œ(Application restrictions) ์„ค์ •:
    • Android apps
    • ํŒจํ‚ค์ง€๋ช…: com.example.runningtracker
    • SHA-1 ์ธ์ฆ์„œ ์ง€๋ฌธ: ๋””๋ฒ„๊ทธ/๋ฆด๋ฆฌ์Šค ๊ฐ๊ฐ ๋“ฑ๋ก
  • API restrictions์—์„œ Maps ๊ด€๋ จ API๋งŒ ํ—ˆ์šฉ

์ฐธ๊ณ :

  • google_maps_key.xml์€ .gitignore์— ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์ €์žฅ์†Œ์— ์ปค๋ฐ‹๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋ฆด๋ฆฌ์Šค ๋นŒ๋“œ ์ „ ์‹ค์ œ ๋ฆด๋ฆฌ์Šค keystore ๊ธฐ์ค€ SHA-1๋กœ ๋™์ž‘ ํ™•์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

4) ์•ฑ ์‹คํ–‰

  • Android Studio์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์—ฐ ๋’ค ์—๋ฎฌ๋ ˆ์ดํ„ฐ ๋˜๋Š” ์‹ค์ œ ๊ธฐ๊ธฐ์—์„œ ์‹คํ–‰
  • ๋˜๋Š” ํ„ฐ๋ฏธ๋„์—์„œ ๋””๋ฒ„๊ทธ ๋นŒ๋“œ:
./gradlew assembleDebug

Windows:

gradlew.bat assembleDebug

๐Ÿ” ๊ถŒํ•œ ๋ฐ ๊ฐœ์ธ์ •๋ณด ์ฒ˜๋ฆฌ (์ถœ์‹œ ๊ธฐ์ค€)

๊ถŒํ•œ ์‚ฌ์šฉ ๋ชฉ์ 

  • ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION: ๋Ÿฌ๋‹ ์ค‘ ์œ„์น˜ ์ถ”์  ๋ฐ ๊ฒฝ๋กœ ํ‘œ์‹œ
  • FOREGROUND_SERVICE, FOREGROUND_SERVICE_LOCATION: ๋Ÿฌ๋‹ ์ค‘ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์œ„์น˜ ์ถ”์  ์œ ์ง€
  • POST_NOTIFICATIONS (Android 13+): ํฌ๊ทธ๋ผ์šด๋“œ ์„œ๋น„์Šค ์•Œ๋ฆผ ํ‘œ์‹œ

์ˆ˜์ง‘/์ €์žฅ ๋ฐ์ดํ„ฐ (ํ˜„์žฌ ๊ตฌํ˜„ ๊ธฐ์ค€)

  • ๋Ÿฌ๋‹ ๊ธฐ๋ก: ์‹œ์ž‘ ์‹œ๊ฐ, ์ด ์šด๋™ ์‹œ๊ฐ„, ํ‰๊ท  ์†๋„, ์ด๋™ ๊ฑฐ๋ฆฌ
  • ์œ„์น˜ ๋ฐ์ดํ„ฐ: ๋Ÿฌ๋‹ ๊ฒฝ๋กœ ํ‘œ์‹œ๋ฅผ ์œ„ํ•ด ์‹ค์‹œ๊ฐ„ ์‚ฌ์šฉ
  • ์ €์žฅ ์œ„์น˜: ๊ธฐ๊ธฐ ๋‚ด๋ถ€ Room DB (running_database)

์™ธ๋ถ€ ์ „์†ก ๋ฐ ์ œ3์ž ์ œ๊ณต (ํ˜„์žฌ ๊ตฌํ˜„ ๊ธฐ์ค€)

  • ๋ณ„๋„ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋กœ ๋Ÿฌ๋‹ ๊ธฐ๋ก์„ ์ „์†กํ•˜์ง€ ์•Š์Œ
  • Google Maps SDK ์‚ฌ์šฉ์œผ๋กœ ์ง€๋„ ํ‘œ์‹œ ๊ด€๋ จ ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ

์‚ฌ์šฉ์ž ์•ˆ๋‚ด

  • ์œ„์น˜ ๊ถŒํ•œ์ด ์—†์œผ๋ฉด ์œ„์น˜ ๊ธฐ๋ฐ˜ ๊ธฐ๋Šฅ์ด ๋™์ž‘ํ•˜์ง€ ์•Š์Œ
  • ๊ถŒํ•œ์€ ๊ธฐ๊ธฐ ์„ค์ •์—์„œ ์–ธ์ œ๋“  ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ

์‹ค์ œ ์Šคํ† ์–ด ์ถœ์‹œ ์‹œ์—๋Š” ๋ณ„๋„์˜ Privacy Policy ๋ฌธ์„œ(URL)์™€ Play Console ๋ฐ์ดํ„ฐ ๋ณด์•ˆ ์–‘์‹ ๋‚ด์šฉ์„ ๋ณธ ์„น์…˜๊ณผ ์ผ์น˜์‹œํ‚ค์„ธ์š”.


๐Ÿ“„ Privacy Policy

  • ์ •์ฑ… URL: https://example.com/running-tracker/privacy
  • ์ถœ์‹œ ์ „ ์œ„ URL์„ ์‹ค์ œ ๊ณต๊ฐœ ๋ฌธ์„œ ์ฃผ์†Œ๋กœ ๊ต์ฒดํ•˜์„ธ์š”.
  • ์•ฑ ๋‚ด ์„ค์ • ํ™”๋ฉด/์˜จ๋ณด๋”ฉ, Play Store ๋“ฑ๋ก ์ •๋ณด(๊ฐœ์ธ์ •๋ณด์ฒ˜๋ฆฌ๋ฐฉ์นจ)์™€ ๋™์ผํ•œ URL์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

๐Ÿ“ฆ ์ง€์› ๋ฒ”์œ„ (Compatibility)

  • minSdk: 24 (Android 7.0)
  • targetSdk: 36
  • compileSdk: 36
  • ์–ธ์–ด/๋Ÿฐํƒ€์ž„: Kotlin + JVM 11 ํƒ€๊ฒŸ

์‹คํ–‰ ์š”๊ตฌ์‚ฌํ•ญ:

  • ์œ„์น˜ ์„œ๋น„์Šค(GPS) ์‚ฌ์šฉ ๊ฐ€๋Šฅ ๊ธฐ๊ธฐ
  • ์ง€๋„ ๋กœ๋”ฉ ๋ฐ ์œ„์น˜ ์ฒ˜๋ฆฌ ์‹œ ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ ๊ถŒ์žฅ

๊ฒ€์ฆ ๊ถŒ์žฅ ๋ฒ”์œ„(์ถœ์‹œ ์ „):

  • Android 7/8/10/13 ์ด์ƒ ๋ฒ„์ „๋ณ„ ๊ธฐ๋ณธ ๋™์ž‘ ์ ๊ฒ€
  • ๊ถŒํ•œ ๊ฑฐ๋ถ€/์žฌํ—ˆ์šฉ, ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ „ํ™˜, ๋ฐฐํ„ฐ๋ฆฌ ์ ˆ์ „ ๋ชจ๋“œ ์‹œ๋‚˜๋ฆฌ์˜ค ์ ๊ฒ€

๐Ÿ— ๋ฆด๋ฆฌ์Šค ๋นŒ๋“œ ๊ฐ€์ด๋“œ (Release)

ํ˜„์žฌ ์„ค์ • ๊ธฐ์ค€:

  • release ๋นŒ๋“œ ํƒ€์ž… ์กด์žฌ
  • ์ฝ”๋“œ ์ถ•์†Œ/๋‚œ๋…ํ™”: isMinifyEnabled = false
  • Google Maps API ํ‚ค๋Š” ๋ฆด๋ฆฌ์Šค ํ‚ค(SHA-1) ๊ธฐ์ค€์œผ๋กœ ๋ณ„๋„ ๊ฒ€์ฆ ํ•„์š”

๋นŒ๋“œ ๋ช…๋ น:

./gradlew bundleRelease

Windows:

gradlew.bat bundleRelease

์ถœ๋ ฅ ๊ฒฝ๋กœ:

  • app/build/outputs/bundle/release/

์Šคํ† ์–ด ๋ฐฐํฌ ์ „ ํ•„์ˆ˜ ์ฒดํฌ:

  • ์—…๋กœ๋“œ์šฉ ์„œ๋ช… ํ‚ค(keystore)๋กœ ์„œ๋ช…๋œ AAB ์ƒ์„ฑ
  • versionCode/versionName ์—…๋ฐ์ดํŠธ
  • ๋ฆด๋ฆฌ์Šค ๋นŒ๋“œ์—์„œ ์ง€๋„/์œ„์น˜/์•Œ๋ฆผ ๊ถŒํ•œ ํ๋ฆ„ ์ตœ์ข… ์ ๊ฒ€
  • ProGuard/R8 ์ ์šฉ ๊ณ„ํš์ด ์žˆ๋‹ค๋ฉด ๋‚œ๋…ํ™” ํ›„ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰

๐Ÿงฑ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ (๊ฐ„๋žต)

app/
โ”œโ”€ presentation/
โ”‚ โ”œโ”€ running/
โ”‚ โ”‚ โ”œโ”€ RunningScreen.kt
โ”‚ โ”‚ โ”œโ”€ RunningViewModel.kt
โ”‚ โ”‚ โ””โ”€ RunningUiState.kt
โ”‚ โ”œโ”€ ButtonControls.kt
โ”‚ โ””โ”€ RunningMap.kt
โ”œโ”€ location/
โ”‚ โ””โ”€ LocationClient.kt
โ”œโ”€ di/
โ”‚ โ””โ”€ appModule.kt
โ””โ”€ util/
โ””โ”€ TimeFormatter.kt

๐Ÿ“ฑ ์‹คํ–‰ ํ™”๋ฉด

๋Ÿฌ๋‹ ํ™”๋ฉด

์ดˆ๊ธฐ ํ™”๋ฉด ๋Ÿฌ๋‹ ์‹œ์ž‘

์ƒํƒœ ๋ณ€ํ™” / ๊ธฐ๋ก

์ผ์‹œ์ •์ง€ ๋Ÿฌ๋‹ ๊ธฐ๋ก

๐Ÿ†• ์—…๋ฐ์ดํŠธ (2026.01.07)

1. ๋Ÿฌ๋‹ ๋กœ์ง ๋ถ„๋ฆฌ (๋ฆฌํŒฉํ† ๋ง)

์„œ๋น„์Šค ์ฝ”๋“œ ๋ณต์žก๋„๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ํ•ต์‹ฌ ๋กœ์ง์„ ์—ญํ•  ๋‹จ์œ„๋กœ ๋ถ„๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

  • RunTimer

    • ์‹œ๊ฐ„ ์ธก์ • ์ „์šฉ ์ปดํฌ๋„ŒํŠธ

    • ์ฝ”๋ฃจํ‹ด ๊ธฐ๋ฐ˜, ์ˆœ์ˆ˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง

  • RunLocationTracker

    • ์œ„์น˜ ์ˆ˜์ง‘ ์ „์šฉ ์ปดํฌ๋„ŒํŠธ

    • LocationClient๋ฅผ ํ†ตํ•ด Flow ๊ธฐ๋ฐ˜ ์œ„์น˜ ์ŠคํŠธ๋ฆผ ์ฒ˜๋ฆฌ

RunningService
โ”œโ”€ RunTimer (์‹œ๊ฐ„ ์ธก์ •)
โ””โ”€ RunLocationTracker (์œ„์น˜ ์ˆ˜์ง‘)
  • ์„œ๋น„์Šค๋Š” ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ์—ญํ• ๋งŒ ๋‹ด๋‹นํ•˜๋„๋ก ์ •๋ฆฌ
  • ํ…Œ์ŠคํŠธ ๋ฐ ์œ ์ง€๋ณด์ˆ˜ ์šฉ์ด์„ฑ ํ–ฅ์ƒ

2. ๋ฐฐํ„ฐ๋ฆฌ ์ƒํƒœ ๊ธฐ๋ฐ˜ ๋Ÿฌ๋‹ ์ œ์–ด

  • BroadcastReceiver ๊ธฐ๋ฐ˜ ๋ฐฐํ„ฐ๋ฆฌ ์ƒํƒœ ๊ฐ์ง€

  • Android ์‹œ์Šคํ…œ ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธ(ACTION_BATTERY_CHANGED) ํ™œ์šฉ

๋™์ž‘ ๊ทœ์น™:

๋Ÿฌ๋‹ ์‹œ์ž‘ ์‹œ

  • ๋ฐฐํ„ฐ๋ฆฌ 30% ์ดํ•˜ โ†’ ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ (์šด๋™์€ ์‹œ์ž‘ ๊ฐ€๋Šฅ)

๋Ÿฌ๋‹ ์ค‘

  • ๋ฐฐํ„ฐ๋ฆฌ 20% ์ดํ•˜ โ†’ ์ž๋™์œผ๋กœ ๋Ÿฌ๋‹ ์ข…๋ฃŒ + ๊ธฐ๋ก ์ €์žฅ

์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ•ด์น˜์ง€ ์•Š์œผ๋ฉด์„œ ์•ˆ์ •์„ฑ ํ™•๋ณด


3. ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ถ”๊ฐ€ (JVM ๋‹จ์œ„ ํ…Œ์ŠคํŠธ)

  • Robolectric + coroutines-test ๊ธฐ๋ฐ˜ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ

  • Android ์˜์กด์„ฑ์ด ์—†๋Š” ํ•ต์‹ฌ ๋กœ์ง ์œ„์ฃผ๋กœ ํ…Œ์ŠคํŠธ

ํ…Œ์ŠคํŠธ ๋Œ€์ƒ: RunTimer

  • start / pause / stop ๋™์ž‘ ๊ฒ€์ฆ

  • ์‹œ๊ฐ„ ์ฆ๊ฐ€ ๋ฐ ์ดˆ๊ธฐํ™” ๋กœ์ง ํ™•์ธ

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages