안드로이드/개발관련(Kotlin)

안드로이드 AlarmManager로 정해진 시간에 작업 수행(Kotlin)

닉네임못짓는사람 2023. 2. 27. 20:05
반응형

이번 글에서는 AlarmManager를 사용해서 우리가 원하는 시간에 작업을 수행하는 방법에 대해 알아보자.

자세한 AlarmManager에 대한 설명은 생략하고, 사용하는 방법에 대해서만 알아볼것이다.

 

바로 코드로 확인해보자.

    fun addAlarm(){
        var alarmManager = this.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        var intent = Intent(this, Alarm::class.java)
        var pIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT)

        val cal = Calendar.getInstance()
        cal.set(Calendar.YEAR, 2021)
        cal.set(Calendar.MONTH, 4)
        cal.set(Calendar.DAY_OF_MONTH, 14)
        cal.set(Calendar.HOUR_OF_DAY, 1)
        cal.set(Calendar.MINUTE, 30)
        cal.set(Calendar.SECOND, 0)

        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal.timeInMillis, pIntent)
    }

가장 먼저 해주어야 할 것은 AlarmManager객체를 선언해주는 것이다.

그 다음으로 Intnet를 선언해주어야 하는데, AlarmManager를 받을 Receiver를 지정해주면 된다.

또한 Intent에 action을 지정하면 지정한 action에 맞춰서 걸러받을 수도 있다.

 

intent를 선언했으면 PendingIntent를 선언해주는데, 실제로 Receiver에 Intent를 보내주는건 이놈이 한다.

pIntnet의 argument는 순서대로 context, requestNumber, Intent, FLAG이다.

여기서 두 번째의 requestNumber로 알람들을 구분하여 등록, 해제할 수 있다.

 

이렇게 Intent들을 선언해주었으면, 다음으로 알람을 언제 보낼것인지 시간을 설정해줄 차례다.

시간은 Calendar객체를 사용하며, 년, 월, 일, 시, 분, 초, ms(micro second)등을 지정할 수 있다.

이때 주의해야 할 점은 MONTH의 경우 0부터 시작한다는 점인데, 즉 0 = 1월, 1 = 2월이 된다.

또한 일을 설정할 때 HOUR_OF_DAY는 24시간을 기준으로하며, DAY는 12시간씩 PM, AM으로 나뉜다.

 

이렇게 시간 설정까지 다 해주었다면 alarmManager.set을 사용해 설정을 해주면 보내는 쪽은 끝이난다.

이때 alarmManager.set은 버전별로, 목적별로 set, setExact, setInexactRepeating,

setExactAndAllowWhileIdle등이 있는데 이부분은 잘 구별해서 사용하길 바란다.

 

다음으로 이 Intent를 받아서 처리하는 부분이다.

class Alarm: BroadcastReceiver(){
    override fun onReceive(context: Context?, intent: Intent?) {
        if(intent != null){
            Log.e("알람", System.currentTimeMillis().toString())
        }
    }
}

Intent를 받으려면 BroadcastReceiver를 상속받는 클래스를 작성해주어야 한다.

이 클래스가 Intent를 받으면 onReceive함수가 실행되니 이곳에 자신이 수행할 작업을 작성해주면 된다.

 

이렇게 하기만하면 끝이 아니고 Manifest에 이 Reciever를 등록해주어야 한다.

<receiver android:name=".Alarm"/>

리시버는 Manifest에 application이하에 작성해주면 된다.

필자의 경우는 receiver를 LocalBroadcastReceiver로 등록해서 사용해보려고 했는데, 이렇게 하면 작동을 안한다.

혹시 쓸 때에는 이 부분도 참고하면 좋을 것 같다.

 

마지막으로, AlarmManager를 해제하는 법에 대해 적어보겠다.

    fun delAlarm(){
        var intent = Intent(this, Alarm::class.java)
        var pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0)
        alarmManager.cancel(pendingIntent)
    }

이 부분도 매우 간단하다.

위에서처럼 Intent, PendingIntent를 선언해주고 alarmManager.cancel로 PendingIntent를 넣어주기만 하면 되는데,

이때 PendingIntent의 Request넘버를 등록할 때와 동일하게 해주어야 한다.

 

alarmManager를 반복적으로 사용하고 싶은 사람들은 setInexactRepeating를 사용하면 된다고 한다.

근데 필자는 이 방법을 사용하니 여러 개의 알람을 등록했을 때, 모두 한번에 보내지는걸 확인했다.

그래서 필자는 이 방법은 사용을 안하고 setExactAndAllowWhileIdle를 사용한 뒤,

알람쪽 BroadcastReceiver에서 Intnet를 받으면, 다시 Broadcast를 보내서 등록 함수를 재실행 하는 방법으로 사용했다.

반응형