[AlarmManager] 알람 매니저 사용법
👩🏻💻 AlarmManager
우선 알람 매니저의 특징을 살펴보자!
- 지정된 시간에 또는 정해진 간격으로 인텐트를 실행한다.
broadcast receiver
와 함께 사용 -> 다른 작업을 실행할 수 있다.- 애플리케이션 외부에서 작동하므로 앱이 실행 중이 아니거나 절전 모드일 떄도 이벤트를 사용하여 작업을 트리거할 수 있다.
- 타이머나 지속적으로 실행되는 서비스에 의존하지 않고 작업할 수 있다.
그렇다면 본격적으로 알람 매니저를 사용하는 방법에 대해 다뤄보고자 한다. 사용법이 비교적 매우 간단하다!
그 과정을 정리해보면 다음과 같다.
- 알람을 받을 broadcast receiver를 정의한다.
- 정의한 broadcast receiver를 등록한다.
- 각 알람에 대한 pendingIntent를 정의한다.
- alarmManager에 해당 pendingIntent를 전달한다.
- broadcast receiver에 의해 알람을 받는다.
- 정의된 후처리를 진행한다.
1. broadcast receiver 정의
class AlarmReceiver : BroadcastReceiver() {
override fun onReceive(p0: Context?, p1: Intent?) {
// broadcast를 받고 진행할 처리 작업 정의
}
}
2. broadcast receiver 등록
broadcast receiver를 등록하는 방법은 크게 두 가지가 있다.
- manifest에 등록하는 방법 (정적 등록)
- activity에 등록하는 방법
각 방법의 차이점은 앱이 실행 중이냐에 따라 달라진다.
- manifest에 등록하는 방법
- 앱이 실행 중이지 않을 때도 broadcast receiver가 동작한다.
- activity에 등록하는 방법
- 등록한 activity의 lifecycle를 따르게 된다.
- 단, 등록한 broadcast를 제거해줘야 메모리 낭비가 되지 않는다.
// manifest를 이용한 등록의 경우
<receiver
android:name=".common_ui.receiver.AlarmReceiver"
android:enabled="true" />
- 여기서
enabled
를 false으로 설정하면 앱 외부 소스의 브로드캐스트를 수신하지 않는다.
3. 알림에 대한 pendingIntent 정의 및 alarmManager에게 전달
fun setPreorderAlarm() {
// 알람 매니저 가져오기
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
// 현재 시간 이후인 지 확인 후 알람 등록
val currentTime = Calendar.getInstance().time.getUTCDateTime()
val alarmTime = Formatter.getDateFromString(preorderDate)
if (alarmTime.after(currentTime)) {
val alarmIntent = Intent(context, AlarmReceiver::class.java)
// intent를 활용해 원하는 값 넘김
alarmIntent.putExtra("preorderDate", preorderDate)
alarmIntent.putExtra("phoneNumber", phoneNumber)
alarmIntent.putExtra("totalOrderCount", totalOrderCount)
// broadcast를 수행할 pendingIntent 선언
val pendingIntent = PendingIntent.getBroadcast(
context,
UUID.randomUUID().variant(), // unique한 아이디 생성
alarmIntent,
PendingIntent.FLAG_IMMUTABLE
)
// alarmManager에 알람 등록
alarmManager.setExact(
AlarmManager.RTC, // 밑 알람 유형 참고
alarmTime.time - TimeUnit.MINUTES.toMillis(10), // 해당 시간 10분 전
pendingIntent
)
}
}
+ 등록된 알람 취소하기
구글링을 해본 결과, alarmManager에 등록된 전체 알람을 가져올 방법은 없다. 따라서
필자의 경우에는 등록한 alarmList를 가지고 있다가 취소하는 데 사용했다.
fun cancelAllAlarm(context: Context) {
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
//필자는 해당 pendingIntent를 따로 변수에 저장해두었다 취소할 때 사용하였다.
pendingIntentList.forEach {
alarmManager.cancel(it)
}
}
👩🏻💻 알람 유형
ELAPSED_REALTIME
- 기기가 부팅된 후 경과한 시간에 대기 중인 인텐트 실행
- 기기의 절전 모드 해제하지 않음
ELAPSED_REALTIME_WAKEUP
- ELAPSED_REALTIME과 동일
- 기기의 절전 모드를 해제하고 대기 중인 인텐트 실행
RTC
- 지정된 시간에 대기 중인 인텐트 실행
- 기기의 절전 모드 해제하지 않음
RTC_WAKEUP
- RTC와 동일
- 기기의 절전 모드를 해제하고 대기 중인 인텐트 실행
👩🏻💻 broadcast receiver 사용 시, 주의할 점
주의할 점은 broadcast receiver를 통해 알람을 받고 UI 작업을 할 수 없다는 것이다. 따라서, dialog를 띄우거나 할 수 없다.. 하지만 pendingIntent를 활용해 activity를 다이얼로그처럼 띄울 수 있다. 이 방법은 추후 별도 게시글을 통해 정리해보겠다.
- broadcast를 사용한다면 다음 게시글을 통해 해당 사용 권장사항을 읽어보는 것이 좋을 것 같다!
댓글남기기