본문 바로가기
Project

[모바일/AndroidStudio]🌴도시열섬 어플리케이션 프로젝트

by SolaKim 2023. 12. 26.

2023학년도 2학기 "모바일프로그래밍"이라는 수업을 수강하였습니다.

Android Studio를 배우는 수업이었습니다. 마지막 기말고사 대체로 프로젝트를 제작했습니다.

여러가지 주제들이 있었지만 교수님께서 추천해주시는 주제가 "도시열섬"이어서, 교수님의 추천주제로 정해서 만들어보기로 했습니다.

팀원은 총 나까지 포함해서 5명이 있었고, 모두 모바일 프로그래밍은 처음 해보는 상태였습니다. 

 

일단 "도시열섬"을 가지고 어플리케이션을 만든다면 어떤 기능이 들어가면 좋을지에 대해서 회의를 해보았습니다.

  • 도시열섬 지역을 알 수 있도록 도시열섬지도를 만들자! 
  • 사람들이 개개인적으로 도시열섬 피해를 최소화할 수 있는 장치를 만들자
    • 커뮤니티? 사람들이 서로 열섬 피해 상황을 공유하거나 녹지공간을 공유할 수 있는 커뮤니티 기능이 있으면 좋겠다!
    • 공유우산은 어떨까? 기사를 보니 양산(혹은 어두운색의 우산)을 쓰는것만으로 체감 온도가 내려간다고 했었는데..
    • 서울시에 무더위쉼터가 많이 있던데, 기존 지도(네이버지도, 카카오지도)에는 표시되지 않으니 무더위쉼터를 표시한 지도가 있었으면 좋겠다.
    • 열섬 피해를 막기위해선 뜨겁게 열이 오른 아스팔트 도로를 식혀주는것이 필요하니, 살수차를 각 구별로 사람들끼리 투표할 수 있도록 살수차 투표 기능도 넣어보자.

 

이렇게 해서 나온 5개의 주제를 가지고 각각 한 파트씩 맡아서 진행하기로 했습니다.

저는 무더위 쉼터 지도를 구현하는 역할을 맡았습니다!


프로젝트 코드는 오픈소스형태로 공개해놨습니다. => ☘️오픈소스주소☘️
위 주소의 readme를 보면 프로젝트를 전반적으로 파악할 수 있다. 이 블로그 게시글에서는 내가 맡은 부분만을 집중적으로 서술해보려고 합니다.

  1. google maps API 받아오기
    1. Google cloud console 에서 프로젝트 및 API키를 생성. 이후 AndroidManifest.xml에 권한과 메타데이터를 추가.
  2. 서울 열린 데이터 광장에서 '무더위 쉼터' openAPI 받아오기
    1. 서울 열린 데이터 광장 API키 생성하기
  3. 무더위 쉼터 데이터 전처리하기
  4. 전처리 된 데이터를 구글 맵에 마크형태로 표시하기
  5. 검색기능 추가

[무더위 쉼터 구현 코드]

-       HeatShelterAPI.java

서울 열린 데이터 광장 에서 무더위 쉼터의 정보가 담겨있는 openAPI를 사용하여 데이터를 가지고 오고 전처리(parse) 하여 map을 띄우는 액티비티에 intent형태로 넘겨주었습니다. HeatShelterAPI 클래스는 AppCompatActivity를 상속받는 안드로이드 액티비티입니다.

  • onCreate 메서드에서 액티비티 초기화 및 레이아웃 설정이 이루어집니다. onCreate 메서드에서는 또한 데이터를 백그라운드 스레드에서 가져오고, 가져온 데이터를 파싱하여 지도에 표시하는 작업이 이루어진다.
  • data 메서드에서는 서울 열도심 쉼터 데이터를 가져오기 위해 OpenAPI를 사용합니다. HttpURLConnection을 사용하여 API에 요청을 보내고, 응답을 받아오는데 사용된다.
  • parseXML 메서드에서는 받아온 XML 데이터를 파싱하여 필요한 정보를 추출합니다. 각 쉼터의 이름, 주소, 면적, 이용 가능 인원, 선풍기 보유 대수, 에어컨 보유 대수, 좌표 등의 정보를 추출합니다.
  • 추출한 정보를 기반으로 MarkerInfo 객체를 생성하고, 해당 좌표를 coordinates 리스트에 추가합니다. Coordinates 리스트에는 좌표와 그 좌표점에 해당하는 정보들을 담아야했기 때문에 MarkerInfo라는 객체 클래스를 따로 설정해주고 그 객체를 해시맵 형태로 가공하여 선언했습니다.
private HashMap<Marker, MarkerInfo> markerInfoHashMap;
  • 이후 HeatShelterMapFragment 액티비티로 이동하여 지도에 좌표와 관련 정보를 표시합니다.
  • 애플리케이션 화면 전환을 위해 BottomNavigationView를 사용하고, 각 메뉴 아이템을 선택할 때마다 해당하는 프래그먼트가 화면에 표시됩니다.
  • 데이터를 가져오는 네트워크 작업은 메인 스레드가 아닌 별도의 스레드에서 처리합니다. 이를 통해 앱이 무응답 상태가 되지 않게 됩니다.
  • HeatShelterMapFragment 액티비티로 좌표와 관련 정보를 전달하기 위해 인텐트를 사용합니다.

 


[무더위 쉼터 구현 코드]

-       HeatShelterMapFragment.java

해당 코드는 HeatShelterAPI.java에서 전처리된 무더위쉼터 정보를 받아와서 지도에 마크 표시하는 코드입니다.
현재 위치 기반으로 가장 가까운 무더위 쉼터 5개는 초록색으로 표시되고, 나머지 무더위 쉼터들은 빨강색으로 표시됩니다.
마크를 누르면 해당 무더위 쉼터에 관한 정보가 나옵니다.
검색하고 싶은 구 이름을 검색하면 해당 구의 무더위 쉼터만 지도위에 나타나게 됩니다.

  • onMapReady 메서드에서 Google Map이 사용 가능해질 때 호출되며, 지도의 UI 설정 및 초기 마커 표시 등이 이루어집니다. showOriginalMarkers 메서드에서는 초기에 받아온 좌표와 마커 정보를 기반으로 지도에 마커를 표시합니다.
  • BottomNavigationView를 이용하여 앱 내 다른 화면으로 전환할 수 있도록 구현되어 있습니다. 메뉴 아이템을 선택할 때마다 해당하는 프래그먼트가 화면에 표시됩니다.
  • showSearchDialog 메서드에서는 사용자에게 검색할 구 이름을 입력받는 다이얼로그를 표시하고, 입력된 구 이름을 기반으로 searchByGuName 메서드에서 해당하는 마커만을 지도에 표시합니다.
  • getDistance 메서드에서는 두 지점 간의 거리를 계산합니다. 그리고 onMapReady 메서드에서 현재 위치와 가장 가까운 5군데의 마커를 특정 색상으로 표시합니다. 이때 showNearestMarkers 메서드와 getNearestMarker 메서드가 사용됩니다.
  • 마커를 클릭하면 해당 마커에 대한 정보를 다이얼로그로 표시하고, showMarkerInfoDialog 메서드에서는 해당 정보를 표시하는 다이얼로그를 구현합니다. 이때 정보는 HeatShelterAPI에서 coordinates로 넘겨받은 값을 사용하여 표시합니다.
  • BitmapDescriptorFactory를 사용하여 마커의 아이콘을 설정하고, 리소스의 관리를 효율적으로 처리합니다.
  • 주석으로 표시된 코드들은 실시간 위치를 받아오는 코드들인데, 정상작동 되는것을 확인하였으나 저희 팀 주제가 서울 무더위쉼터 지도여서 시연하는데 현재 전주 위치를 나타내는 것은 부적절하다고 판단하여 주석 표시했습니다!

실제 코드를 실행했을때 나오는 화면 


[팀원들 코드 합치기]

커뮤니티 파트와 소스 코드를 합치는 부분에서 어려움을 겪었습니다...💥💥💥💥

무더위 쉼터 지도 구현을 완성한 이후 커뮤니티로 전체 어플리케이션 틀을 만들던 팀원과 합쳐야했습니다.

팀원은 BottomNavigationView를 이용해서 각 페이지를 fragment 형식으로 맞춰놨지만 저는 intent를 통한 두 액티비티의 정보 교환이 필요했기 때문에 무조건 Activity혹은 FragmentActivity를 사용해야했습니다. 그렇기 때문에 기존 navigator.java 코드를 다음과 같이 수정해주었습니다.

else if (item.getItemId() == R.id.Heat_shelter) {
    Intent intent = new Intent(navigator.this, HeatShelterAPI.class);
    startActivity(intent);
    return true;}

 

⭐️⭐️⭐️
이렇게 하면 네비게이션바에서 무더위 쉼터 클릭시 HeatShelterAPI로 가서 서울시 데이터를 받아오고 전처리한 뒤 HeatShelterMapFragment 코드로 정보가 전달되고 지도에 정보를 표시할 수 있게 됩니다.

또한 두 코드다 액티비티이기 때문에 BottomNavigationView를 코드에 추가해서 해당 액티비티에도 네비게이션바가 정상적으로 뜰 수 있도록 하였습니다.

 


[UI 디자인]

초반엔 디자인이 정말 안드로이드 스튜디오에서 기본적으로 제공하는 디자인을 사용해서 너무 별로였습니다.(구렸습니다ㅜㅜ)

저희는 기나긴 회의 끝에 메인 컬러를 초록색으로 설정하여 모든 메인 컬러들을 설정한 초록색으로 변경했습니다. 또한 버튼들의 구성이나 위치를 신경써서 간편하면서도 세련되어보이게 배치하려고 노력했습니다. 또한 상태바(status bar)를 투명색으로 설정하여 좀 더 가시성이 좋게 설정하였습니다. 전체적인 UI 디자인을 사용자 친화적으로 만들고자 했습니다.

 

다른 앱들과 같이 랜딩페이지(IntroActivity.java)를 만들고자 코드를 추가했습니다.

AndoridManifest.xml 파일에 navigator activity이전에 다음과 같은 코드를 추가했습니다.

<!--        시작로딩-->

<activity android:name=".IntroActivity"

    android:exported="true">

    <intent-filter>

        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />

    </intent-filter>

</activity>

그리고 IntroActivityonCreate 메서드에서 run을 할때 딜레이 3를 주어 로딩페이지처럼 보여질 수 있도록 하였습니다.

handler.postDelayed(new Runnable() {

    @Override

    public void run() {

        Intent intent = new Intent(getApplicationContext(), navigator.class);

        startActivity(intent);

        finish();

    }

},3000);

 


최종적으로 저희 프로젝트는 모바일 프로그래밍 수업에서 총 "10팀중 1등" 이라는 좋은 성적을 거두었습니다!

또한 해당 프로젝트를 가지고 컴퓨터공학과에서 주최하는 작품경진대회에 출전하였고, 은상을 수상하였습니다.

11월부터 12월까지 약 2달간 진행한 프로젝트였는데, 좋은 결과를 받을 수 있어서 너무 영광이었습니다! 

다음 프로젝트도 열심히 해보겠습니다!