[๋ฐฉ๊ด‘๊ณก๊ณก] ์นด์นด์˜ค Map ํ˜„์žฌ ์œ„์น˜ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ ๋”œ๋ ˆ์ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

2024. 10. 27. 12:05ยท๐Ÿงก Projects/๐Ÿงก Projects: App
728x90

1๏ธโƒฃ  ๋ฌธ์ œ ์ƒํ™ฉ

์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ์—์„œ ์‚ฌ์šฉ์ž์˜ ํ˜„์žฌ ์œ„์น˜๋ฅผ ์ง€๋„์— ํ‘œ์‹œํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋˜ ์ค‘, ๋งค๋ฒˆ ์œ„์น˜๋ฅผ ์ƒˆ๋กœ ๋ถˆ๋Ÿฌ์˜ค๊ฒŒ ๋จ.

ํŠนํžˆ, ์•ฑ์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•  ๋•Œ๋งˆ๋‹ค ์œ„์น˜๋ฅผ ์ƒˆ๋กœ ๊ฐ€์ ธ์˜ค๋Š” ๊ณผ์ •์—์„œ ๋”œ๋ ˆ์ด๊ฐ€ ๋ฐœ์ƒ

 

2๏ธโƒฃ ๋ฌธ์ œ ์›์ธ

์•ฑ์ด ์‹œ์ž‘๋  ๋•Œ๋งˆ๋‹ค ์œ„์น˜๋ฅผ ๋งค๋ฒˆ ์ƒˆ๋กœ ๊ฐ€์ ธ์˜ค๋Š” fusedLocationClient.getCurrentLocation() ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ.

 

  • GPS ์‹ ํ˜ธ๊ฐ€ ์•ฝํ•˜๊ฑฐ๋‚˜ ๋„คํŠธ์›Œํฌ ์ƒํƒœ๊ฐ€ ๋ถˆ์•ˆ์ •ํ•œ ๊ฒฝ์šฐ
  • ์œ„์น˜ ์ •๋ณด๊ฐ€ ์ž์ฃผ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ์ƒํ™ฉ์—์„œ๋Š” ๋ถˆํ•„์š”ํ•œ ์ž์› ์†Œ๋ชจ๊ฐ€ ๋ฐœ์ƒ

 

๋”ฐ๋ผ์„œ, ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์œ„์น˜ ์ •๋ณด๋ฅผ ์บ์‹ฑํ•˜์—ฌ ์ €์žฅํ•˜๊ณ , ํ•„์š”ํ•  ๋•Œ๋งŒ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ฐฉ์‹์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

 

3๏ธโƒฃ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

  1. SharedPreferences๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ
  2. ๋งˆ์ง€๋ง‰์œผ๋กœ ๊ฐ€์ ธ์˜จ ์œ„์น˜๋ฅผ ์ €์žฅํ•˜๊ณ 
  3. ์•ฑ์ด ์‹œ์ž‘๋  ๋•Œ ์ด๋ฅผ ๋ถˆ๋Ÿฌ์™€ ์ดˆ๊ธฐ ์œ„์น˜๋กœ ์„ค์ •
  4. ์บ์‹ฑ๋œ ์œ„์น˜์™€ ํ˜„์žฌ ์œ„์น˜๋ฅผ ๋น„๊ตํ•˜์—ฌ ๋‹ค๋ฅธ ๊ฒฝ์šฐ์—๋งŒ ์ง€๋„ ์ค‘์‹ฌ ์—…๋ฐ์ดํŠธ, SharedPreferences ๊ฐฑ์‹ 

์ด๋ฅผ ํ†ตํ•ด ์•ฑ ์‹œ์ž‘ ์‹œ ๋น ๋ฅด๊ฒŒ ์ง€๋„์— ์œ„์น˜๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํ•„์š”ํ•  ๋•Œ๋งŒ ์ƒˆ๋กœ์šด ์œ„์น˜ ์ •๋ณด๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

 

1. SharedPreferences ์ดˆ๊ธฐํ™”

val sharedPreferences = getSharedPreferences("LocationCache", MODE_PRIVATE)
  • ์›๋ฆฌ: 
    • SharedPreferences๋Š” ๊ฐ„๋‹จํ•œ ํ‚ค-๊ฐ’ ์Œ์„ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
    • ์—ฌ๊ธฐ์„œ๋Š” "LocationCache"๋ผ๋Š” ์ด๋ฆ„์˜ SharedPreferences ๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜์—ฌ ์œ„์น˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
    • MODE_PRIVATE๋Š” ์ด ๋ฐ์ดํ„ฐ๊ฐ€ ์•ฑ ๋‚ด์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

 

2. ์ด์ „์— ์ €์žฅ๋œ ์œ„์น˜ ๊ฐ€์ ธ์˜ค๊ธฐ

val cachedLatitude = sharedPreferences.getString("latitude", null)?.toDoubleOrNull()
val cachedLongitude = sharedPreferences.getString("longitude", null)?.toDoubleOrNull()
  • ์›๋ฆฌ:
    • ์ด์ „์— ์ €์žฅ๋œ ์œ„๋„์™€ ๊ฒฝ๋„ ๊ฐ’์„ SharedPreferences์—์„œ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.
    • ์ €์žฅ๋œ ๊ฐ’์ด ์—†์„ ๊ฒฝ์šฐ null์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • ๋ฌธ์ž์—ด๋กœ ์ €์žฅ๋œ ๊ฐ’์„ Double๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

 

3. ์บ์‹ฑ๋œ ์œ„์น˜๋กœ ์ง€๋„ ์„ค์ •

if (cachedLatitude != null && cachedLongitude != null) {
    val cachedPosition = LatLng.from(cachedLatitude, cachedLongitude)
    kakaoMap.moveCamera(CameraUpdateFactory.newCenterPosition(cachedPosition, 16))
    addMarkerToMap(cachedPosition, null)
}

 

  • ์›๋ฆฌ:
    • ์ €์žฅ๋œ ์œ„์น˜๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ,
      • ์ด๋ฅผ LatLng ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ง€๋„ ์ค‘์‹ฌ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
      •  moveCamera ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ง€๋„์˜ ์ค‘์‹ฌ์„ ์บ์‹ฑ๋œ ์œ„์น˜๋กœ ์ด๋™์‹œํ‚ค๊ณ , 
      • addMarkerToMap ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ์œ„์น˜์— ๋งˆ์ปค๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

 

4. ์œ„์น˜ ๊ถŒํ•œ ํ™•์ธ

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
    // ์œ„์น˜ ์—…๋ฐ์ดํŠธ ์ฃผ๊ธฐ๋ฅผ ์กฐ์ ˆํ•˜์—ฌ ํ•„์š”ํ•  ๋•Œ๋งŒ ์œ„์น˜๋ฅผ ๊ฐ€์ ธ์˜ด
}
  • ์›๋ฆฌ:
    • ์‚ฌ์šฉ์ž๊ฐ€ ์œ„์น˜ ๊ถŒํ•œ์„ ํ—ˆ์šฉํ–ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. 
    • ACCESS_FINE_LOCATION ๊ถŒํ•œ์ด ํ—ˆ์šฉ๋œ ๊ฒฝ์šฐ์—๋งŒ ์œ„์น˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
    • ์ด๋Š” ์‚ฌ์šฉ์ž ํ”„๋ผ์ด๋ฒ„์‹œ๋ฅผ ๋ณดํ˜ธํ•˜๊ณ , ์•ฑ์ด ๋ถˆํ•„์š”ํ•œ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

 

5-1. ํ˜„์žฌ ์œ„์น˜ ์š”์ฒญ

fusedLocationClient.getCurrentLocation(Priority.PRIORITY_BALANCED_POWER_ACCURACY, null)
    .addOnSuccessListener { location ->
        // ์œ„์น˜๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๊ฐ€์ ธ์™”์„ ๋•Œ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ
    }
    .addOnFailureListener {
        // ์œ„์น˜๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ ์‹คํŒจํ–ˆ์„ ๋•Œ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ
    }
  • ์›๋ฆฌ:
    • fusedLocationClient.getCurrentLocation() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜„์žฌ ์œ„์น˜๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. 
    • PRIORITY_BALANCED_POWER_ACCURACY๋Š” ๋ฐฐํ„ฐ๋ฆฌ ์†Œ๋ชจ๋ฅผ ๊ณ ๋ คํ•˜์—ฌ ์ ์ ˆํ•œ ์ •ํ™•๋„๋กœ ์œ„์น˜๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
      • ์„ฑ๊ณต ์‹œ: ์œ„์น˜๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๊ฐ€์ ธ์˜ค๋ฉด addOnSuccessListener๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค
      • ์‹คํŒจ ์‹œ: ์œ„์น˜๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ ์‹คํŒจํ•˜๋ฉด addOnFailureListener๊ฐ€ ์‹คํ–‰๋˜์–ด ์‚ฌ์šฉ์ž์—๊ฒŒ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

 

5-2. ์œ„์น˜ ๊ฐ์ฒด ์ฒ˜๋ฆฌ

location?.let {
    val currentPosition = LatLng.from(it.latitude, it.longitude)
    // ์ดํ›„ ์ฝ”๋“œ์—์„œ currentPosition์„ ์‚ฌ์šฉ
}
  • ์›๋ฆฌ:
    • ์œ„์น˜ ๊ฐ์ฒด๊ฐ€ null์ด ์•„๋‹Œ ๊ฒฝ์šฐ์—๋งŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. 
    • let ๋ธ”๋ก์„ ์‚ฌ์šฉํ•˜์—ฌ location ๊ฐ์ฒด์˜ ์œ„๋„์™€ ๊ฒฝ๋„๋ฅผ LatLng ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
    • ์ด ๊ฐ์ฒด๋Š” ์ง€๋„ ์ค‘์‹ฌ์„ ์„ค์ •ํ•˜๊ฑฐ๋‚˜ ๋งˆ์ปค๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

5.3 ์œ„์น˜ ๋ณ€๊ฒฝ ์—ฌ๋ถ€ ํŒ๋‹จ

val isLocationChanged = cachedPosition?.let { cachedPos ->
    val cachedLocation = Location("").apply {
        latitude = cachedPos.latitude
        longitude = cachedPos.longitude
    }
    val currentLocation = Location("").apply {
        latitude = it.latitude
        longitude = it.longitude
    }
    cachedLocation.distanceTo(currentLocation) > 10 // 10 meters threshold
} ?: true
  • ์›๋ฆฌ:
    • ์บ์‹ฑ๋œ ์œ„์น˜์™€ ํ˜„์žฌ ์œ„์น˜ ๋น„๊ต: Location ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ์œ„์น˜ ๊ฐ„์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
    • ๊ฑฐ๋ฆฌ ๊ธฐ์ค€: distanceTo() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ์œ„์น˜ ๊ฐ„์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ , ์ด ๊ฐ’์ด 10๋ฏธํ„ฐ๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ์—๋งŒ ์œ„์น˜๊ฐ€ ๋ณ€๊ฒฝ๋œ ๊ฒƒ์œผ๋กœ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค.
    • ๊ธฐ๋ณธ๊ฐ’: ์บ์‹ฑ๋œ ์œ„์น˜๊ฐ€ ์—†์„ ๊ฒฝ์šฐ(cachedPosition์ด null์ธ ๊ฒฝ์šฐ), ์œ„์น˜๊ฐ€ ๋ณ€๊ฒฝ๋œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•˜์—ฌ true๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

 

5.4 ์œ„์น˜ ๋ณ€๊ฒฝ ์‹œ ์ง€๋„ ์—…๋ฐ์ดํŠธ

if (isLocationChanged) {
    // ํ˜„์žฌ ์œ„์น˜๋กœ ์ง€๋„ ์ค‘์‹ฌ ์„ค์ •
    kakaoMap.moveCamera(CameraUpdateFactory.newCenterPosition(currentPosition, 16))
    addMarkerToMap(currentPosition, null)

    // ์ƒˆ๋กœ์šด ์œ„์น˜๋ฅผ ์บ์‹ฑ
    val editor = sharedPreferences.edit()
    editor.putString("latitude", it.latitude.toString())
    editor.putString("longitude", it.longitude.toString())
    editor.apply()
}

 

  • ์›๋ฆฌ:
    • ์ง€๋„ ์—…๋ฐ์ดํŠธ:
      • ์œ„์น˜๊ฐ€ ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ์—๋งŒ moveCamera ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง€๋„์˜ ์ค‘์‹ฌ์„ ์ƒˆ๋กœ์šด ์œ„์น˜๋กœ ์„ค์ •ํ•˜๊ณ , 
      • addMarkerToMap ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ์œ„์น˜์— ๋งˆ์ปค๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
    • ์œ„์น˜ ์ €์žฅ: 
      • SharedPreferences์— ์ƒˆ๋กœ์šด ์œ„์น˜๋ฅผ ์ €์žฅํ•˜์—ฌ ์ดํ›„์— ์•ฑ์ด ๋‹ค์‹œ ์‹œ์ž‘๋  ๋•Œ ์ด ์œ„์น˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. 
      • apply() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

 

4๏ธโƒฃ ๊ทธ ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ

  1. LatLng ๊ฐ์ฒด ์ƒ์„ฑ ์—๋Ÿฌ:
cannot access "init" it is private in LatLng

 

kakao.vector~ importํ•ด๋„ ๊ณ„์† ์—๋Ÿฌ ๋‚จ.

LatLng(a,b) -> LatLng.from(a,b) ๋กœ ํ•ด๊ฒฐ


์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด from() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

 

  1. ์œ„์น˜ ๊ถŒํ•œ ๋ฌธ์ œ: ์œ„์น˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฐ˜๋“œ์‹œ ์œ„์น˜ ๊ถŒํ•œ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ถŒํ•œ์ด ์—†๋Š” ๊ฒฝ์šฐ ์•ฑ์ด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ์œ„์น˜ ์—…๋ฐ์ดํŠธ ์ฃผ๊ธฐ ์„ค์ •: ๋„ˆ๋ฌด ์ž์ฃผ ์œ„์น˜๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋ฉด ๋ฐฐํ„ฐ๋ฆฌ ์†Œ๋ชจ๊ฐ€ ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ ์ ˆํ•œ ์ฃผ๊ธฐ๋กœ ์œ„์น˜๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋„๋ก ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

5๏ธโƒฃ ์ „์ฒด์ฝ”๋“œ

๊ฐœ์„  ์ฝ”๋“œ ์ „

private fun setMapToCurrentLocation() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        fusedLocationClient.getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, null)
            .addOnSuccessListener { location ->
                location?.let {
                    val currentPosition = LatLng(it.latitude, it.longitude)
                    kakaoMap.moveCamera(CameraUpdateFactory.newCenterPosition(currentPosition, 16))
                    addMarkerToMap(currentPosition, null)
                }
            }
    }
}

 

๊ฐœ์„  ์ฝ”๋“œ ํ›„
import android.location.Location

private fun setMapToCurrentLocation() {
    val sharedPreferences = getSharedPreferences("LocationCache", MODE_PRIVATE)

    // ์ด์ „์— ์ €์žฅ๋œ ์œ„์น˜ ๊ฐ€์ ธ์˜ค๊ธฐ (์œ„๋„, ๊ฒฝ๋„)
    val cachedLatitude = sharedPreferences.getString("latitude", null)?.toDoubleOrNull()
    val cachedLongitude = sharedPreferences.getString("longitude", null)?.toDoubleOrNull()

    var cachedPosition: LatLng? = null
    if (cachedLatitude != null && cachedLongitude != null) {
        cachedPosition = LatLng.from(cachedLatitude, cachedLongitude)
        kakaoMap.moveCamera(CameraUpdateFactory.newCenterPosition(cachedPosition, 16))
        addMarkerToMap(cachedPosition, null)
    }

    // ์œ„์น˜ ๊ถŒํ•œ์ด ํ—ˆ์šฉ๋˜์—ˆ๋Š”์ง€ ํ™•์ธ
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        fusedLocationClient.getCurrentLocation(Priority.PRIORITY_BALANCED_POWER_ACCURACY, null)
            .addOnSuccessListener { location ->
                location?.let {
                    val currentPosition = LatLng.from(it.latitude, it.longitude)

                    // ์ด์ „ ์œ„์น˜์™€ ํ˜„์žฌ ์œ„์น˜ ๋น„๊ต, ๊ฑฐ๋ฆฌ ์ฐจ๊ฐ€ 10๋ฏธํ„ฐ ์ด์ƒ์ธ ๊ฒฝ์šฐ๋งŒ 
                    //์ดˆ๊ธฐ๊ฐ’์ด null์ธ ๊ฒฝ์šฐ๋Š” ๋ฐ”๋กœ true
                    val isLocationChanged = cachedPosition?.let { cachedPos ->
                        val cachedLocation = Location("").apply {
                            latitude = cachedPos.latitude
                            longitude = cachedPos.longitude
                        }
                        val currentLocation = Location("").apply {
                            latitude = it.latitude
                            longitude = it.longitude
                        }
                        cachedLocation.distanceTo(currentLocation) > 10 // 10 meters threshold
                    } ?: true

                    if (isLocationChanged) {
                        // ํ˜„์žฌ ์œ„์น˜๋กœ ์ง€๋„ ์ค‘์‹ฌ ์„ค์ •
                        kakaoMap.moveCamera(CameraUpdateFactory.newCenterPosition(currentPosition, 16))
                        addMarkerToMap(currentPosition, null)

                        // ์ƒˆ๋กœ์šด ์œ„์น˜๋ฅผ ์บ์‹ฑ
                        val editor = sharedPreferences.edit()
                        editor.putString("latitude", it.latitude.toString())
                        editor.putString("longitude", it.longitude.toString())
                        editor.apply()
                    }
                }
            }
            .addOnFailureListener {
                Toast.makeText(this, "ํ˜„์žฌ ์œ„์น˜๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.", Toast.LENGTH_SHORT).show()
            }
    }
}

 

์—ฌ๊ธฐ์„œ ์ด addMarkToMap์ด 2๋ฒˆ ํ˜ธ์ถœ๋˜๋Š”๋ฐ, 

1๋ฒˆ addMarkToMap์—์„œ ์บ์‹ฑ๋œ ์œ„์น˜๋กœ ๋งˆ์ปค ์ถ”๊ฐ€,

2๋ฒˆ addMarkToMap์œผ๋กœ ์šฐ์น˜ ์ฐจ์ด๊ฐ€ 10์ด์ƒ์ธ ๊ฒฝ์šฐ ์ง€๋„์— ๋‹ค์‹œ ๋งˆํฌ๋ฅผ ์ถ”๊ฐ€(์—…๋ฐ์ดํŠธ), SharedPreferences ๊ฐ’ ๊ฐฑ์‹ 

728x90
'๐Ÿงก Projects/๐Ÿงก Projects: App' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [๋ฐฉ๊ด‘๊ณก๊ณก] ์ง€๋„ ๋ ˆ์ด๋ธ” ํด๋ฆญ์‹œ ์•„์ด์ฝ˜ ๋ณ€๊ฒฝ
  • [๋ฐฉ๊ด‘๊ณก๊ณก] ์•„์ด์ฝ˜ ํด๋ฆญ์‹œ ์ „ํ™”๋ฒˆํ˜ธ, ์ฃผ์†Œ ๋ณต์‚ฌ
  • [์ŠคํŒŒ๋ฅดํƒ€ ์ฝ”๋”ฉํด๋Ÿฝ] [๋กœ์ผ“๋‹จ2๊ธฐ] ์•ฑ๊ฐœ๋ฐœ Pizza Collector ๊ฐœ๋ฐœ ํ›„๊ธฐ2
  • [์ŠคํŒŒ๋ฅดํƒ€ ์ฝ”๋”ฉํด๋Ÿฝ] [๋กœ์ผ“๋‹จ2๊ธฐ] ์•ฑ๊ฐœ๋ฐœ ํ›„๊ธฐ 1
eyes from es
eyes from es
  • eyes from es
    eyes from es
    eyes from es
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ
      • โค๏ธ ๊ฟ€ํŒ ๋ชจ์Œ
        • โค๏ธ ๊ฐ“์ƒ ๊ฟ€ํŒ
        • โค๏ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ
      • ๐Ÿงก Projects
        • ๐Ÿงก Projects: Web
        • ๐ŸŽคPreterview
        • ๐Ÿงก Projects: App
        • ๐Ÿงก๋Œ€์™ธํ™œ๋™
        • ๐Ÿงก OSCCA ์˜คํ”ˆ์†Œ์Šค ์ปจํŠธ๋ฆฌ๋ทฐ์…˜ ์•„์นด๋ฐ๋ฏธ
      • ๐Ÿ’› Frontend
        • ๐Ÿ’› Frontend : React
        • ๐Ÿ’› Frontend : JavaScript
        • ๐Ÿ’› Frontend : TypeScript
      • ๐Ÿ’š Backend
      • ๐Ÿ’™ OS: ์šด์˜์ฒด์ œ
        • ๐Ÿ’™ Linux
      • ๐Ÿ’œ ์ฝ”๋”ฉํ…Œ์ŠคํŠธ
        • ๐Ÿ’œ ์ž๋ฃŒ๊ตฌ์กฐ
        • ๐Ÿ’œ ์•Œ๊ณ ๋ฆฌ์ฆ˜
        • ๐Ÿ’œ ๋ฐฑ์ค€
        • ๐Ÿ’œSWEA
        • ๐Ÿ’œํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค
      • ๐Ÿ”ด Study
        • ๐Ÿ”ด๋ฉด์ ‘ ์Šคํ„ฐ๋””
        • ๐Ÿ”ด ๊ธฐ์—…๋ถ„์„
        • ๐Ÿ”ด ์—๋Ÿฌ๋…ธํŠธ(Error Note)๐Ÿงฑ
        • ๐Ÿ”ด ITNews(Coding)
        • ๐Ÿ”ด ITNews(Tech)
      • ๐ŸŸ  ์ธ์ƒ ๊ณ„ํš
        • ๐ŸŸ  ์˜ฌํ•ด ๋ชฉํ‘œ
      • ๐ŸŸก TIL
        • ๐ŸŸก TIL ์ผ๊ธฐ
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ํƒœ๊ทธ
    • ๋ฐฉ๋ช…๋ก
  • ๋งํฌ

  • ๊ณต์ง€์‚ฌํ•ญ

  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    css
    ๋‰ด์Šค์Šคํฌ๋žฉ
    ์›น๊ฐœ๋ฐœ
    ์ฝ”๋“œ๋ฆฌ๋ทฐ
    ์ŠคํŒŒ๋ฅดํƒ€์ฝ”๋”ฉํด๋Ÿฝ
    ์ฝ”๋“œ์Šคํ„ฐ๋””
    ๋ฐฑ์ค€
    ๊ฐœ๋ฐœ
    ์Šค๋งˆํŠธ์‹ฑ์Šค
    ๊ฐœ๋ฐœ๊ณต๋ถ€
    ๋™ํ–ฅ๋ถ„์„
    ๋‰ด์Šค๋ฃธ
    ์•Œ๊ณ ๋ฆฌ์ฆ˜
    ๋„ค์นด๋ผ์ฟ ๋ฐฐ
    ๊ธฐ์—…๋ถ„์„
    ์ž๋ฃŒ๊ตฌ์กฐ
    ๋ถ„์„๋ ˆํฌํŠธ
    ์ฝ”๋”ฉํ…Œ์ŠคํŠธ
    ์Šคํ„ฐ๋””
    Ai
    ๋ฌธ์ œํ’€์ด
    ์ตœ๊ทผ์ด์Šˆ
    ์‚ผ์„ฑ์ „์ž
    ๋ฐฉํ•™์Šคํ„ฐ๋””
    ์ฝ”ํ…Œ
    SW์ด์Šˆ
    IT์ด์Šˆ
    html
    ์ฝ”๋”ฉ
    C
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.5
eyes from es
[๋ฐฉ๊ด‘๊ณก๊ณก] ์นด์นด์˜ค Map ํ˜„์žฌ ์œ„์น˜ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ ๋”œ๋ ˆ์ด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”