AlarmManager

sumi Yoo·2022년 11월 28일
0

백그라운드 처리

정확한 시점에 실행해야 하는 작업에는 AlarmManager를 사용할 수 있다.
App이 실행 중이 아닐 때라도 정해진 시간에 이벤트를 받아 어떤 작업을 처리할 수 있다.

AlarmReceiver

지정된 시간이 되었을 때 동작할 기능을 Receiver의 onReceive()에 정의한다.
이벤트는 인텐트 형태이다.

class AlarmReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
    	...
    }
}

Manifest

생성한 리시버는 Manifest.xml에 등록해야 한다. API 레벨 31부터는 정확한 시간에 알람을 울리기 위해 manifest.xml에 SCHEDULE_EXACT_ALARM 퍼미션을 선언해줘야 한다.

알람 등록

설정한 알람 시간, 요청 코드, 알람 내용(동작시킬 인텐트)을 인자로 넣어준다.

alarmManager.setExactAndAllowWhileIdle(
            AlarmManager.RTC_WAKEUP,
            cal.timeInMillis - ONE_HOUR_IN_MILLIS,
            getPendingIntent(promise, requestCode)
        )

setExactAndAllowWhileIdle: setExact()과 동일하지만 절전모드에서도 동작하는 API입니다.

알람 취소

알람을 취소하기 위해서 AlarmManager.cancel()에 펜딩 인텐트를 전달한다. 이 때 알람 요청코드는 알람을 생성했을 때 사용했던 요청 코드와 동일해야 한다.

alarmManager.cancel(pendingIntent)

부팅 후에도 알람 유지하기

AlarmManager를 통해 등록된 알람들은 기기가 꺼지거나 재부팅되면 모두 지워진다.
재부팅 시 알람이 울리도록 하기 위해선 Manifest.xml 퍼미션을 추가해야 한다.

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

브로드 캐스트의 수행 시간이 10초를 넘기게 되면 anr이 발생하게 된다.
따라서 서비스를 따로 호출해서 그 서비스에서 firestore에 저장되어 있는 내 약속 정보들을 모두 가져와 알람 매니저에 등록 해주었다.

if (intent.action.equals("android.intent.action.BOOT_COMPLETED")) {
            context.startService(Intent(context, BootService::class.java))
        }

BootService

@AndroidEntryPoint
class BootService : LifecycleService() {

    @Inject
    lateinit var promiseRepository: PromiseRepository

    @Inject
    lateinit var userRepository: UserRepository

    @Inject
    lateinit var alarmDirector: AlarmDirector


    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        lifecycleScope.launch {
            alarmDirector.removeLocalAllAlarm()
            userRepository.getMyInfo().first().onSuccess { myInfo ->
                promiseRepository.getPromiseList(myInfo).first().forEach { promise ->
                    alarmDirector.registerAlarm(promise)
                }
            }
            stopSelf()
        }
        return super.onStartCommand(intent, flags, startId)
    }

}

BootService도 메니페스트 파일에 선언해줘야 한다.

https://danggai.github.io/android/Android%EC%97%90%EC%84%9C-WorkManager-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0/
https://codechacha.com/ko/android-alarmmanager/
https://velog.io/@jeongminji4490/Android-%EC%95%8C%EB%9E%8C-%EA%B8%B0%EB%8A%A5-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0%EC%83%9D%EC%84%B1%EB%B6%80%ED%84%B0-%EC%9E%AC%EB%B6%80%ED%8C%85%EA%B9%8C%EC%A7%80

0개의 댓글