일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- zeplin
- 안드로이드 아키텍쳐
- 안드로이드 메모리릭
- #리사이클러뷰 어댑터
- 사용법
- 안드로이드해상도
- #안드로이드
- #리사이클러뷰
- 구글맵안돼요
- 리사이클러뷰 체크박스
- 레트로핏
- #SMS API #안드로이드 SMS #SMS Retriever
- 클린아키텍쳐
- retrofit2
- retrofi
- #android #안드로이드 #glide #gif #이미지다운로드
- 제플린
- #안드로이드 개발자 #안드로이드 신입 #개발자 이직 #안드로이드 면접 #신입 개발자
- retrofit
- 빗버킷 #bitbucket #authorization failed #깃
- 안드로이드 익명클래스
- 키스토어
- #ContentProvider #App DataShare
- 메모리릭
- 안드로이드
- MVVM
Archives
- Today
- Total
땀이 삐질삐질 나는 개발 일기
Android Alarm Manager 반복 설정 시 생길 수 있는 문제 본문
안녕하세요. 삐질삐질 개발하는 개발자 삐질입니다.
이번 글에서는 안드로이드 Alarm Manager를 반복 설정할 때 생길 수 있는 문제를 기록해놓겠습니다.
오레오 이상에서는 Background 작업이 제한되었기 때문에 부득이 하게 주기적인 Alarm을 설정하는 방법으로
우회하고자 했습니다.
알람 매니저를 설정하는 방법은 아래와 같습니다.
public void set15ClockTime(Context context, DateTime dateTime) {
// AlarmOneMinuteBroadcastReceiver 초기화
Intent alarmIntent = new Intent(context, Alarm_Reciver.class);
alarmIntent.putExtra("requestCode", ID_15TIME);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, ID_15TIME, alarmIntent, 0 );
startAlram(context, pendingIntent, dateTime);
}
private void startAlram(Context context, PendingIntent pendingIntent, DateTime time) {
// AlarmManager 호출
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
MakeLog.log("알람 시간 설정", "" + time.toString("yyyy-MM-dd HH:mm:ss"));
MakeLog.log("알람 시간 설정", "" +time.getMillis());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
manager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time.getMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
manager.setExact(AlarmManager.RTC_WAKEUP, time.getMillis(), pendingIntent);
} else {
manager.setRepeating(AlarmManager.RTC_WAKEUP, time.getMillis(),INTERVAL_24, pendingIntent);
}
}
이런식으로 설정해줄 수 있는데요, 각 버전에 따라 알람을 반복시키기 위한 System call API가 다릅니다. 참고해주세요.
제가 이번 글에서 다루고 싶은 부분은 마쉬멜로우 이상의 버전에서 도즈모드를 깨우기 위한 API
-
manager.setExactAndAllowWhileIdle(파라미터 생략)
-
manager.setAlarmClock(파라미터 생략)
가 있습니다.
이 두 API는 스마트폰이 도즈모드 상태일지라도 도즈 모드를 깨워주는 역할을 하는 것은 동일하지만
결정적인 차이가 있습니다.
-
setExactAndAllowWhileIdle -> 내 앱만 도즈모드에서 깨움
-
setAlarmClock -> 모든 앱을 알람에서 꺠움
각 상황에 맞게 적절하게 사용하는 것이 좋겠지만, 저는 개인적으로 2번의 API를 주로 사용합니다.
1번의 API는 도즈모드를 깨워주기는 하지만 , 정확한 시간을 보장하지는 못하는 것 같습니다.
그리고 또한 저는
글의 목적이었던, 주기적으로 무한 반복되는 알람을 구현하고 싶었습니다. 이 로직을 구현하기 위해
-
알람셋
-
브로드 캐스트 리스버 진입 후 현재시간 + Interval Time 알람 셋
-
다시 브로드 캐스트 리시버 진입 후 + Interval Time 알람 셋
계속적으로 반복되게 했습니다.
하지만 결과적으로 계속해서 반복되지 않았습니다.
계속적인 로깅을 함으로써 발견 된 현상으로는
-
알람이 불규칙한 주기로 브로드 캐스트 리시버에 진입하지 않음
-
대표적으로 길어도 3일 ~4일 후 알람이 해제되는 것으로 보임
-
알람을 명시적으로 set해 주어도 바로 다음 알람부터 리시버 진입이 안되는 경우도 있음
이러한 현상을 겪게 되었고, 아직 완전히 해결하지 못했습니다.
이 현상에 따른 추측으로는
-
너무 짧은 시간 동안 많은 일을 하는 스케쥴링(알람)을 부여하기 때문에 OS레벨에서 해제함
-
알람이 울렸을 때 수행하는 로직에서 Exception이 발생해, 크래시로 인하여 알람이 해제됨
-
Doze 모드로 인해 알람이 보장이 안됨.
가장 유력한 부분은 첫 번째 이유입니다. 현재도 계속 해결하기 위해 로깅을 하며 테스트중에 있고
자료를 검색중에 발견한 내용으로는
구글 공식문서에서 “너무 잦은 알람 수행을 권장하지 않는다” 라는 의미의 내용을 보았습니다.
저는 비록 알람매니저를 통해 반복을 수행했지만, 추후 WorkManager로 교체/테스트 해볼 예정입니다.
다만 이전에 WorkManager를 사용했을 때도 완벽하게 주기적으로 작동하는 것이 아니라, 내가 지정한 Interval 안에서
웬만하면 수행이 되지만, 굉장히 불규칙한 주기로 수행되는 부분을 관찰할 적도 있기 때문에, 각별한 주의가 필요합니다.
안드로이드 초보 개발자를 위해 아래와 같은 카카오 오픈톡을 운영 중입니다.
`
'개발 Tip' 카테고리의 다른 글
다중 프로젝트가 의존하는 Module Path를 각 개발 환경에서 자동화 하기 (0) | 2019.11.07 |
---|---|
Glide 4.x 버전 이상에서 Gif 및 이미지 다운받아 파일로 저장 (2) | 2019.10.22 |
RecyclerView Adapter에서 ViewHolder를 Nested Static Class 로 사용하는 이유. (0) | 2019.07.21 |
Retrofit2 기본 사용법 (4) | 2019.07.19 |
FindViewById() 대체제 Databinding (0) | 2019.07.19 |
Comments