코딩하기 좋은날
롤(Riot) API를 활용한 롤 알림 안드로이드 앱 제작 - 1 (Kotlin) 본문
평소 롤을 즐겨하는 유저로써 롤 API를 활용한 무언가를 만들어 보자라고 생각을 하였습니다.
그중 내가 등록한 사람이 게임을 시작했을 때 ! 알림을 알려주는게 있으면 편하겠구나 라는 생각이 들어 만들기 시작하였습니다.
간략하게 제작 순서를 설명하고 시작하겠습니다.
1. Riot API Key 발급받기
API를 이용하려면 당연히 Key를 발급받아야 합니다.
https://developer.riotgames.com/
아래 사이트로 간다음 자신의 롤아이디로 로그인하면 DEVELOPMENT API KEY 이 키는 24시간마다 만기가 되므로 갱신을 시켜줘야 하고
20 requests every 1 seconds(s)
100 requests every 2 minutes(s)
의 제한이 따릅니다. 그 이상을 이용하기 위해선 상품 등록을 하고 라이엇 측에서 허용을 해줘야 하는 것 같습니다.
2. 사용할 API 확인
많은 종류의 API가 있는데 여기서 필요한 API를 찾았습니다. 가장 먼저 SUMMONER-V4를 이용하면 소환사의 이름으로 라이엇측에서 지정한 ID를 얻어낼 수 있습니다. 이후 SPECTATOR-V4 라는 관전정보 API가 있는데 이 ID를 이용하면 현재 진행중인 게임 정보에 대해 알 수 있습니다.
그리고 이건 추후에 넣은 기능이지만 앱을 실행시 등록된 유저의 소환사 아이콘, 레벨 티어 승/패 정보를 보여주도록 구현을 하였기 때문에 이러한 정보가 포함된 LEAGUE-V4도 이용을 하였습니다. 설명이 아주 자세하게 되어있으므로 필요한 것을 찾아서 쓰면 됩니다!
3. API 호출
자 이제 안드로이드 스튜디오로 넘어가겠습니다. 우선은 API 호출을 하기 위하여 여러 라이브러리가 있지만 가장 많이 사용하고 또 성능도 좋다고 알고 있는 Retrofit2 를 이용 하겠습니다.
하나의 인터페이스와(서버 역할을 할) 하나의 Client를 Object로 생성해서 사용하면 되겠습니다. GET 방식을 이용하여 호출하였고 API호출시 반환받는 타입을 잘 확인해야 합니다. League정보 같은경우 Set으로 반환이 되서 모르고 있다가 꽤나 헤맸던 기억이 납니다. 각 형식에 맞게 Query나 Path를 통해 필요한 부분을 채워 주시면 됩니다. 뭐 대략 아래와 같습니다.
Retrofit2를 Coroutine을 활용하여 사용을 하였습니다.
interface SummonerAPI {
@GET("summoner/v4/summoners/by-name/{summonerName}")
suspend fun getsummoner(
@Path("summonerName") summonerName : String,
@Query("api_key") api_key : String
): Response<Summoner>
@GET("spectator/v4/active-games/by-summoner/{encryptedSummonerId}")
suspend fun getspectator(
@Path("encryptedSummonerId") encryptedSummonerId : String?,
@Query("api_key") api_key : String
): Response<Spectator>
@GET("league/v4/entries/by-summoner/{encryptedSummonerId}")
suspend fun getLeague(
@Path("encryptedSummonerId") encryptedSummonerId : String?,
@Query("api_key") api_key: String
): Response<Set<LeagueEntryDTO>>
}
object RetrofitClient {
private var instance : Retrofit? = null
fun getServer(): SummonerAPI = instance!!.create(
SummonerAPI::class.java)
fun getInstnace() : Retrofit {
if(instance == null){
instance = Retrofit.Builder()
.baseUrl("https://kr.api.riotgames.com/lol/")
.addConverterFactory(GsonConverterFactory.create())
.build()
}
return instance!!
}
}
이제 API 호출을 통해 값이 잘 넘어오는 것을 확인하였습니다.
4. 어떻게 알림을 보낼 것인가?
그렇다면 어떻게 알림을 보낼 것인가? 에 대한 고민을 시작 했습니다.
1. 다모아서 서버에서 따로 처리한뒤 FCM(firebase Cloud message)을 이용하여 알림을 Push한다.
2. 그냥 각각의 앱에서 처리한다.
위의 2가지 사항에 대해 고민을 하였지만 1번은 자체 서버를 구축해야 하므로 간단히 테스트만 해보고 클라이언트 자체에서도 처리해보고 싶었기 때문에 2번의 방법으로 하기로 하였습니다.
1번의 방법은 따로 주기적인 작업을 돌리지는 않았고 로컬에서 디바이스의 Token 값을 이용하여 FCM 을 송신하고 수신받는 정도만 테스트 해보았습니다. 주기적인 작업을 돌리기 위해서는 서버 호스팅을 하여야 하는데 그러기엔 귀찮아서.. 안했습니다.
우선 이앱이 만들어진 목적은 언제든 게임이 시작한다면 유저에게 알림을 줄 수 있어야 합니다. 따라서 특정 사이트를 굳이 검색해보지 않아도 우리는 그사람이 현재 게임을 하고 있음을 알 수 있는 편리함을 가집니다.
이러한 동작을 하기 위해서는 앱이 켜져있든 꺼져있든 상관없이 주기적으로 API를 호출해야 합니다. 따라서 기본적으로 백그라운드에서 작업을 하는 Service를 이용하기로 하였고 죽지 않는 서비스 Immortal Service를 구현하여 사용하기로 생각을 하였습니다.
https://forest71.tistory.com/185
이러한 Immortal Service에 대해서는 위의 블로그에서 정말 많은 도움을 받았습니다. Immortal Service를 구현하는데 있어 꽤 많은 Issue들이 존재하는데 그러한 부분들을 시원하게 긁어 주셨습니다.
기본적인 원리는 서비스의 OnDestroy 나 OnTaskRemoved가 호출되면 알람을 실행 시킵니다. 이때 우리의 알람은 앱에 있는 AlarmReceiver를 깨울 수 있는 BroadCast를 가집니다. 알람이 실행되면 우리의 앱의 AlarmReceiver는 이를 수신하고 서비스는 다시 시작하게 됩니다. 이는 휴대폰의 재부팅시에도 유효해야 하므로 RebootReciever 또한 동일한 동작을 하게 처리해 주면 됩니다. 관찰결과 OS에서 주기적으로 서비스를 Destroy시킵니다. 위 블로그에서는 절전 모드와 관련이 있다고 글이 적혀있습니다. 이러한 부분은 따로 적용을 해보진 않았습니다.
여기서 또하나의 Issue가 생기는데 안드로이드 oreo(8, API 26) 이상에서는 백그라운드에서 서비스를 실행하는 것을 금지합니다. 따라서 startForegroundService 라는 메서드를 이용하여 이를 해결 할 수 있는데 문제는 이는 하나의 notification창을 띄우게 되는 문제가 발생합니다.
위의 블로그를 참조하면 startForegroundService를 이용하여 호출된 서비스에서 자신을 종료하고 그안에서 기존에 사용하던 서비스를 실행 시켜주는 방법으로 이러한 문제를 해결하고 있습니다.
자 따라서 API 호출 -> 게임중임 -> 알림 발송을 서비스에서 지속적으로 수행을 하게 됩니다.
기본적으로 이러한 호출은 300초 마다 진행되게 하였고 테스트를 해보니 알림이 잘 도착하였습니다.
약간의 감시용(?)의 역할이 있는것 같지만 뭐 그렇습니다. -> 이러한 서비스 이용에 대한 ISSUE가 있어 3편에서 사용법의 수정이 있습니다.
아래는 Destiny(스트리머이신)님의 아이디를 등록하자 (지금 게임 중이셨습니다) 알림이 오는 것을 볼 수 있습니다!
1편은 여기까지 작성하겠습니다. 2편에서는 소환사를 등록해야 하기 때문에 데이터 저장에 관련 된 부분과 추가적으로 앱을 실행시킬 때 소환사의 정보를 뿌리는 것들에 대해서 설명을 하고 전체 코드는 2편에서 제 깃허브 주소를 참고해 주시면 될 것 같습니다.
'Android' 카테고리의 다른 글
안드로이드 SharedPreferences 사용 예제(Kotlin) (0) | 2020.08.03 |
---|---|
롤(Riot) API를 활용한 롤 알림 안드로이드 앱 제작 - 2 (Kotlin) (0) | 2020.07.19 |
Android Notification (kotlin) (0) | 2020.07.12 |
Android Service ( Start / Intent / bound) 란? - 2 (0) | 2020.06.19 |
Android Service ( Start / Intent / bound) 란? - 1 (0) | 2020.06.15 |