등산왕 – 안드로이드 앱 프로젝트

2 minute read

배경

약 4개월 동안 네이버 커넥트재단에서 진행하는 부스트캠프 웹·모바일 6기 멤버십 과정을 마무리했다. 멤버십 과정의 마지막 6주동안 진행한 프로젝트 등산왕에 대한 정리를 하려고 한다.

앱 소개

깃헙 레포지토리

등산왕은 등산 기록 관리 앱이다. 앱에는 크게 세 가지 기능이 있다.

등산 기록

record

내가 개발을 맡은 실시간 등산 기록을 하는 기능이다. BottomNavigationView의 첫번째 항목이며, 앱의 메인 기능이다. 등산 기록 버튼을 누르면 주변 산이 표시되고, 산을 선택 시 등산 기록이 시작된다. 기록되는 정보는 등산 경로, 시간, 거리, 그리고 걸음 수이며, 이는 포그라운드 서비스에 기록된다. 사용자가 앱을 종료하더라도 독립적으로 서비스가 실행되고 있기 때문에 기록이 중지되지 않는다. 또한 알림으로 실시간 등산 정보를 표시하고 있다.

위치 좌표

location

위치 좌표를 받아오는 것은 구글의 Fused Location Provider를 사용했다. Fused Location Provider를 사용하면 단말기의 위치 정보를 내부적으로 여러 센서(GPS, Wifi, 통신망) 등을 복합적으로 사용해 적절한 위치를 반환받을 수 있다. 포그라운드 서비스에서 이 API를 사용해 받은 위치를 메모리에 계속 저장하고 있다가, 등산 종료 버튼을 누를 시 내부 DB에 저장하게 된다.

실시간 위치 정보 표시

처음 기획에서는 등산 기록 중에는 단말기의 좌표만 받고 등산 시간과 거리만 화면에 표시했다. 그러나 실시간으로 등산 경로를 볼 수 있으면 좋을 것 같다는 피드백을 받고 네이버 지도 API를 사용해 지도 기능을 추가했다. 위치 좌표는 이미 Fused Location Provider로 받고 있었으니 네이버 지도 API 내의 위치 서비스를 이용할 필요는 없었다. Dynamic map의 PathOverlay를 사용해 위치 좌표들을 이어줌으로써 실시간 등산 경로를 표시할 수 있었다.

locationCallback = object : LocationCallback() {
    override fun onLocationResult(locationResult: LocationResult) {
        super.onLocationResult(locationResult)
        // 걸음수가 늘어난 경우에만 new location이라고 취급
        if (tempStep < curStep) {
            onNewLocation(locationResult.lastLocation)
            repository.locations.add(LatLngAlt.fromLocation(locationResult.lastLocation))
            repository.locationLiveData.postValue(repository.locations)
        }
        tempStep = curStep
    }
}

단말기를 가만히 놔두어도 Fused Location Provider의 한계로 반환되는 위치 값이 계속 달라지는 문제가 있었다. 이를 해결하기 위해 기록하고 있는 걸음 센서를 사용해, ‘걷지 않을 때 위치가 달라지는 것은 예외로 처리’하는 방법을 통해 위치가 달라졌을 때 걸음 수가 증가하지 않았을 경우 그 위치를 버리는 방식으로 해결했다.

등산 기록 확인

room

Room DB에 저장된 등산 기록을 확인하는 기능이다. RecyclerView를 사용했으며, 썸네일 이미지는 vworld의 API에 등산 경로를 polyline으로 찍어서 사용했다. 상세 화면의 지도는 메인 지도와 마찬가지로 네이버 지도를 사용했다.

업적

achievements

특정 조건을 만족하는 경우 업적이 자동으로 달성되며(등산 종료 버튼 누를 시 검사를 하고 있다), 업적이 달성되면 알림으로 표시한다. 달성한 업적은 카카오링크 API를 사용해 카카오톡으로 공유할 수 있다. 업적 시스템을 통해 등산에 대한 흥미를 일으켜 재미있게 등산을 할 수 있지 않을까 하는 마음으로 기획했다.

산 정보 제공

처음에는 산림청에서 제공하는 전국 산 정보 API를 그대로 쓰려고 했지만, 누락된 정보도 많고 쓸모 없는 정보가 너무 많았다. 또한 지역명이 통일돼있지 않아서 어떤 산은 경남, 어떤 산은 경상남도에 있다고 표시됐다. 모든 산 정보를 내려받으니 용량이 약 3메가바이트밖에 되지 않아, 이를 적절히 전처리를 한 후 내부 DB에 저장하고 사용하는 방식을 채택했다. 내부 DB는 Room을 사용했고, createFromAsset()을 사용해 처음부터 DB가 구축된 상태로 앱을 시작했다.

picture 19 picture 20 picture 21
     

지역 별 지도를 클릭해 해당 지역의 산을 볼 수도 있고, 스피너로 시/군을 선택하거나 이름으로 검색이 가능하다. 산 상세 정보는 산림청에서 제공하는 정보를 사용했고, 날씨 정보는 산림청 제공 정보를 역지오코딩한 좌표를 OpenWeather API에 전달해 일주일 간의 해당 산의 날씨 정보를 얻어왔다.

소감

제대로 된 팀 프로젝트를 졸업하고나서야 경험한 것 같다. Git을 사용해 코드를 공유하고 관리했으며 적절한 기능 별 분업을 해 순조롭개 개발이 진행됐다. 점점 개발을 진행할 수록 상용 앱에 가까운 퀄리티로 발전하는 앱을 보며 보람찬 기분을 많이 느꼈다. 후에 취업에 성공했을 때 회사 업무에 도움이 많이 되는 프로젝트였으면 좋겠다. 이제 안드로이드 앱 개발을 해봤으니 조그마한 개인 프로젝트도 진행해보고 싶은 생각이 든다.

Comments