Toy Project

[Toy Project 4] 위치 알라미 출시!! 그리고 프로젝트 수행 후기

소스코드 요리사 2018. 11. 20. 22:59

Toy Project로 이번에는 위치알람(위치알라미)을 만들어 보았습니다.

PLAY 스토어에도 비슷한 기능의 위치/GPS 알람들이 많습니다.

그런데, 등록한 위치영역 밖에 있을 때 알람을 해주는 기능과 문자로 알림을 주는 기능을 가진 어플은 없었습니다.

사실 저는 이 두가지 기능이 제일 필요했거든요. 

왜냐면 아래 개발 비화를 읽어보시면 알겠지만 아내에게 퇴근했다라는 정보를 줄 수 있어야 했기 때문입니다.


아무튼, 이번 프로젝트를 하게된 동기, 주요 동작 구조 설명, 새롭게 알게 된 점을 공유합니다.

많은 다운로드와 함께 다른 일에 조금이나마 참조되었으면 좋겠습니다.





#1. 개발 비화

저는 보통 퇴근을 일찍하는 날이면 집에 가서 아내가 차려준 맛있는 밥을 먹습니다.

그래서, 퇴근할 때 전화를 해서 운전하고 집으로 가는 동안 아내가 밥을 차려줄 수 있게 알려줍니다.

아내는 그렇게해야 밥을 차려먹고, 치워도 너무 늦지 않는다고 하더군요. 


근데, 퇴근하고 아내에게 전화해주는 것이 너무 번거럽고 간혹 잊는 경우도 있었습니다.

그래서,  "퇴근할 때 자동으로 아내에게 문자를 보내주자!" 

라는 단순한 아이디어에서 시작되어 살을 덧붙여 완성하였습니다.


덕분에 맛난 아내에게 사랑받으며(?) 맛난밥을 얻어 먹고 있습니다.^^


#2. 앱 주요 화면 



#3. 핵심 동작 구조

① 서비스 호출

알리미(PlaceTask)의 실행 TYPE에 따라 HandlerService 서비스가 호출됩니다.

ALERT_EXECUTE_TYPE_NOW : 메인화면에서 Switch 의 ON/OFF 등의 이벤트로 바로 실행됨.

ALERT_EXECUTE_TYPE_SCHEDULE : 안드로이드의 알람메니저에 알람 스케쥴이 등록됨. 따라서 알람에 의해 서비스가 실행됨.


② HandlerServcie 서비스의 동작

넘겨 받은 알리미(PlaceTask)의 ID로 SQLite에 저장된 DB에서 정보를 조회, 알리미(PlaceTask) 객체를 인스턴스화 한 후 

PlaceTaskGPSCheckService 서비스를 호출 하여, 알리미(PlaceTask)를 큐에 추가


③ PlaceTaskGPSCheckService 서비스의 동작

작업 큐에서 알리미(PlaceTask)를 하나씩 꺼내 아래 알림 TYPE별로 동작 조건에 부합하는 지 확인합니다.

부합하면 알림옵션에 따라 Activity 를 통해 자신에게 알려주거나 등록된 수신처로 SMS를 전송합니다.

부합하지 않으면 다시 작업 큐에 넣습니다.


-. 알림 동작 조건

(1) 알리미(PlaceTask)가 알람스케쥴 범위 안 인지 확인. 

   : 알람스케쥴 범위 밖이면 해당알리미(PlaceTask)를 작업큐에 넣지 않고 버림.

     예) ALERT_EXECUTE_TYPE_SCHEDULE 의 알리미(PlaceTask)의 현재시간이 종료시간에 도달했을 경우


(2) 현재 GPS의 위치가 알리미(PlaceTask)의 500m 안인지 밖인지 확인.

   : 알림 TYPE이 ALERT_TYPE_IN_REGION 일 경우 500m 안 일경우 (2) 조건 만족

   : 알림 TYPE이 ALERT_TYPE_OUT_REGION 일 경우 500m 밖 일경우 (2) 조건 만족


④ 알리미(PlaceTask)의 옵션에 따라 알림을 전달합니다.

   : 나에게 알림(진동으로 알림) 체크 시 Activity를 통해 자신에게 알려줌.

   : 저장된 연락처 및 문자전달 내용이 있을 경우 저장된 수신처로 SMS를 전송합니다.


   

#4. 해당 프로젝트를 하며 알게 된 것들

(1) 구글 맵, GPS 사용방법

(2) fragment 사용 방법, 생명주기

(3) 서비스, Local 바인드

(4) Broadcast와 Receiver

(5) Broadcast Receiver 에서 bind 된 service 를 사용할 수 없다.

  : Broadcast Receiver 는 실행시간이 10초 안에 끝나야 함. bind 가 되면 bind된 service가 10초안에 끝난다는 보장이 없기 때문에 사용 할 수 없다.

(6) AlarmManager 에 사용되는 PendingIntent 에는 PutExtra 를 이용해서 Serializable 형을 넘길 수 없다.

    사용할 경우 계속 null 이 리턴됨.  int 형은 가능함. 

    그래서, AlarmManager에 알람을 등록할 때 알라미(PlaceTask)의 ID를 PendingIntent로 넘기고, HandlerService에서 ID를 받아 SQLite에서 조회해서 사용하는 것으로 개발을 했다.

(7) 오레오 버전부터 Manifest에 명시적으로 Receiver를 등록하고, Broadcast를 보내면 Broadcast를 전달받지 못함.

    명시적이 아닌 소스코드로 구현하면 전달받아짐.

(8) 오레오 버전부터 Notification 발생 시 채널을 이용해야함.

(9) APK 릴리즈 후 구글맵이 뜨지 않는 경우가 발생할 수 있는데, 이 때는 릴리즈용 키의 Hash를 구글API센터에 등록하면 된다.

    구글 Publish 에 등록된 키를 사용한다면 거기에 나와 있는 Hash를 구글 API센터에 등록하면 된다.



#5. Reference

(1) fragment 관련 

https://developer.android.com/guide/components/fragments?hl=ko

http://recipes4dev.tistory.com/58


(2) 구글맵 관련

https://github.com/googlesamples/android-play-location

https://webnautes.tistory.com/1011

https://webnautes.tistory.com/1165


(3) 서비스 관련

https://developer.android.com/guide/components/services?hl=ko

https://developer.android.com/guide/components/bound-services?hl=ko



#6. PLAY 스토어 다운로드 주소 

: https://play.google.com/store/apps/details?id=com.toyproject.honeyimleaving