-
[Android/Java] 알림, 특정주기 알림, 반복 알람 만들기Android 2020. 10. 4. 02:59
알림 참고
developer.android.com/guide/topics/ui/notifiers/notifications?hl=ko
반복 알람 예약 참고
developer.android.com/training/scheduling/alarms
알림 알람 차이를 이렇게 이해하고 글을 썼다
알림 : 알리는 행위 자체
알람 : 설정된 알림
안드로이드 알림 개요
스마트폰 알림 요소
- 상대표시줄 알림
- 알림창의 알림
- 잠금화면 알림(Android 5.0, API 레벨 21부터)
- 헤드업 알림(Android 5.0, API 레벨 21부터)
- 앱 아이콘 뱃지 알림(Android 8.0, API 레벨26 부터)
알림에 사용자가 적절히 반응할 수 있는 액티브 요소를 넣는것이 좋다
알림 호환성에 대한 내용은 참고링크 맨 밑에서 확인가능
알림 만들기
NotificationCompat 클래스를 사용하면 알아서 API를 호환해준다
알람 설정
NotificationCompat.Builder 객체를 사용해 알림 콘텐츠와 채널을 설정해야한다.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) #작은 아이콘 .setContentTitle(textTitle) #제목 .setContentText(textContent) #본문 .setPriority(NotificationCompat.PRIORITY_DEFAULT); #알림 우선순위 설정생성자의 경우 채널ID 제공
채널이란 Android 8.0(API 레벨26) 이상에서 호환성 유지를 위해 필요. 이전 버전에서는 상관X
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(NOTIFICATION_ID, builder.build())ID가 같으면 같은 알람으로 인식해서 알람창에 여러개 안뜨고 하나로 덮어짐
반복 알람 예약 AlarmManager
앱이 사용되지 않을때도 시간기반 알림 실행하기
AlarmManager 클래스 기반
알람 특징
- 지정된 시간 또는 정해진 간격으로 인텐트 실행
- Broadcast receiver와 함께 알람을 사용하여 서비스를 시작하고 다른작업을 실행
- 앱 외부에서 작동하므로, 알림을 사용하면 앱이 실행중이 아니거나 기기가 대기중일때도 이벤트나 작업 트리거가능
반복 알람 특성
- 알람 유형 (밑에 설명)
- 트리거 시간. 지정된 시간이 과거이면 알람은 즉시 트리거됨
- 알람 간격. ex)하루에 한번, 매 시간, 5분 마다
- 알람이 트리거 되면 실행되는 대기 중인 인텐트. 동일한 인텐트를 사용하는 새 알람을 설정하면 원래 알람을 대체함
반복 알람 설정
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); PendingIntent pendingIntent = PendingIntent.getService(context, requestId, intent, PendingIntent.FLAG_NO_CREATE); if (pendingIntent != null && alarmManager != null) { alarmManager.cancel(pendingIntent); }PendingIntent를 취소하려면 FLAG_NO_CREATE를 PendingIntent.getService()에 전달하여 인텐트의 인스턴스(있는 경우)를 가져온 다음 그 인텐트를 AlarmManger.cancel()에 전달
PendingIntent가 FLAG_ONE_SHOT으로 생성된 경우 취소할 수 없음
알람 유형
크게 2가지 기준으로 나뉨
1. 기기 부팅 후 실제 경과시간
2. 실시간 시계(RTC)
둘다 화면이 꺼져 있을때 기기에서 CPU 절전 모드르 해제하는 wakeup 버전을 제공
※ wakeup 버전의 알람 유형을 사용하지 않으면 기기가 다음에켜질때 모든 반복 알람이 실행됨
특정 간격(ex 30분마다) 알람을 실행한다면, 실제 경과시간 유형
하루 중 특정 시간에 실행되면 시간 기반의 실시간 시계 유형
- 유형 목록
- ELAPSSED_REALTIME : 기기 부팅 후 경과한 시간을 기반으로 대기 인텐트 실행. 기기 절전모드 해제X
경과시간은 기기가 대기상태였던 시간을 포함함
- ELAPSED_REATIME_WAKEUP : 기기 부팅 후 지정된 시간이 경과하면 기기 절전을 해제하고 대기중인 인텐트 실행
- RTC : 지정된 시간에 대기중인 인텐트 실행. 기기의 절전모드는 해제X
- RTC_WAKEUP : 지정된 시간에 기기의 절전 모드를 해제하여 대기 중인 인텐트 실행
- 실제 경과시간 알람 예시
- 알람 설정한 후 30분 마다 기기 절전모드를 해제하여 알람 실행
// Hopefully your alarm will have a lower frequency than this! alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR, AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);- 1분 후 기기의 절전모드를 해제하여 일회성 알람을 실행
private AlarmManager alarmMgr; private PendingIntent alarmIntent; ... alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, AlarmReceiver.class); alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0); alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60 * 1000, alarmIntent);- 실시간 시계 알람 예시
- 오후 2시에 기기절전 모드를 해제하여 알람 실행, 하루 한번 동일한 시간에 반복
// Set the alarm to start at approximately 2:00 p.m. Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.HOUR_OF_DAY, 14); // With setInexactRepeating(), you have to use one of the AlarmManager interval // constants--in this case, AlarmManager.INTERVAL_DAY. alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);- 정확히 오전 8시30분에 기기 절전모드 해제하여 알람 실행, 그 후 20분 마다 반복
private AlarmManager alarmMgr; private PendingIntent alarmIntent; ... alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, AlarmReceiver.class); alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0); // Set the alarm to start at 8:30 a.m. Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.HOUR_OF_DAY, 8); calendar.set(Calendar.MINUTE, 30); // setRepeating() lets you specify a precise custom interval--in this case, // 20 minutes. alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 20, alarmIntent);- 알람 취소
알람 관리자의 cancel()을 호출하여 취소할 PendingIntent를 전달
// If the alarm has been set, cancel it. if (alarmMgr!= null) { alarmMgr.cancel(alarmIntent); }
기기가 다시 시작되어도 알람 실행하기
기기를 종료하면 설정된 모든 알람이 취소됨. 그러므로 기기가 재부팅 될 때
자동으로 반복 알람이 다시 시작하도록 기능추가
1. 안드로이드 매니페스트에 RECEIVE_BOOT_COMPLETED 권한 설정
AndroidManifest.xml 파일에 다음 항목 추가
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>이 권한을 사용하면 시스템 부팅이 끝난 후 해당 앱은 브로드캐스팅되는 ACTION_BOOT_COMPLETED를 받음
그 후 브로드캐스트 수신기 설정하면됨
2. BroadcastReceiver를 구현하여 브로드캐스트 받기
public class SampleBootReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { // Set the alarm here. } } }3. AndroidManifest.xml 에서 ACTION_BOOT_COMPLETED 작업을 필터링 하는 인텐트 필터 및 Broadcast 수신기 추가
<receiver android:name=".SampleBootReceiver" android:enabled="false"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"></action> </intent-filter> </receiver>android:enabled=false 이므로 특정 명시적 인텐트만 받는다. ( 인텐트 및 브로드캐스트 참고)
이렇게 하면 부팅 수신기가 불필요하게 호출되는 것을 방지
- 수신기 사용 예시(사용자가 알람을 설정한 경우)
ComponentName receiver = new ComponentName(context, SampleBootReceiver.class); PackageManager pm = context.getPackageManager(); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);사용자가 기기를 재부팅해도 수신기는 사용할 수 있는 상태다.
수신기를 프로그래매틱 방식으로 사용하면 재부팅해도 manifest 설정에 의해 재정의된다.
수신기는 앱이 중지할때까지 사용할 수 있는 상태로 남아있는다.
다음과 같이 수신기를 중지할 수 있다.(ex 사용자가 알람을 취소한 경우)
ComponentName receiver = new ComponentName(context, SampleBootReceiver.class); PackageManager pm = context.getPackageManager(); pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);- 잠자기 및 앱 대기 상태에서도 알람 실행하기
Android 6.0(API 레벨 23) 에서 도입됨
해당 상태에서 알람을 실행하려면
setAndAllowWhileIdel() 또는 setExactAndAllowWhileIdle() 사용
- 알람 권장사항
- 필요 이상으로 트리거 시간을 정밀 설정하지 말것
SetRepeating() 대신 setInexacRepeating() 사용
'Android' 카테고리의 다른 글
안드로이드 10 (Q) head up notification 띄우기 (0) 2020.11.03 Android WebView mixed content 허용하기( 안드로이드 웹뷰 엑박 문제) (0) 2020.10.25 콘텐츠 제공자 Content providers (0) 2019.07.09 브로드캐스트 수신자 Broadcast Receiver (0) 2019.07.09 서비스 Service (0) 2019.07.03