알람 예약

알람 (AlarmManager 기반) 클래스)를 사용하면 시간 기반 작업을 할 수 없습니다. 예를 들어, 알람을 사용하여 일기예보를 다운로드하는 것과 같이 하루에 한 번 서비스를 시작하는 장기 실행 작업을 시작할 수 있습니다.

알람에는 다음 특징이 있습니다.

  • 지정된 시간에 또는 정해진 간격으로 인텐트를 실행합니다.

  • Broadcast receiver와 함께 알람을 사용하여 작업 또는 WorkRequests를 예약하여 다른 작업을 실행할 수 있습니다.

  • 애플리케이션 외부에서 작동하므로 알람을 사용하면 앱이 실행 중이 아니거나 기기가 대기 상태인 경우에도 이벤트나 작업을 트리거할 수 있습니다.

  • 앱의 리소스 요구사항을 최소화하는 데 도움이 됩니다. 예약 가능한 항목 타이머나 지속적으로 실행 중인 서비스에 의존하지 않고 작업을 수행할 수 있습니다.

부정확한 알람 설정

앱이 부정확한 알람을 설정하면 시스템은 향후 특정 시점에 알람을 전송합니다. 부정확한 알람은 잠자기와 같은 배터리 절약 제한사항을 준수하면서 알람 전송 시점에 관한 몇 가지 보장을 제공합니다.

개발자는 다음 API 보장을 활용하여 부정확한 알람 전송 시점을 맞춤설정할 수 있습니다.

특정 시간 후에 알람 전송

앱에서 set(), setInexactRepeating() 또는 setAndAllowWhileIdle()를 호출하면 제공된 트리거 시간 전에 알람이 울리지 않습니다.

Android 12(API 수준 31) 이상에서는 절전 모드 또는 잠자기 모드와 같은 배터리 절약 제한이 적용되지 않는 한 시스템이 제공된 트리거 시간으로부터 1시간 이내에 알람을 호출합니다.

특정 기간에 알람 전송

앱에서 setWindow()를 호출하면 제공된 트리거 시간 전에 알람이 울리지 않습니다. 배터리 절약 제한이 적용되지 않는 한, 알람은 지정된 트리거에서 시작하여 지정된 기간 내에 전달됨 있습니다.

앱이 Android 12 이상을 타겟팅하면 시스템이 기간이 지정된 부정확한 알람의 호출을 10분 이상 늦춰야 합니다 따라서 600000 아래의 windowLengthMillis 매개변수 값은 600000로 클립됩니다.

거의 일정한 간격으로 반복 알람을 전송합니다.

앱이 setInexactRepeating()를 호출하면 시스템은 여러 알람을 호출합니다.

  1. 첫 번째 알람은 알림을 받습니다.
  2. 이후 알람은 일반적으로 지정된 기간이 지나면 울립니다. 경과하면 알람을 연속으로 두 번 호출하는 사이의 시간은 다를 수 있습니다.

정확한 알람 설정

시스템은 미래의 정확한 순간에 정확한 알람을 호출합니다.

대부분의 앱은 부정확한 알람을 사용하여 작업과 이벤트를 예약하여 여러 일반적인 사용 사례를 완료할 수 있습니다. 앱의 핵심 기능이 정확한 시간의 알람(예: 알람 시계 앱 또는 캘린더 앱)에 의존하는 경우 정확한 알람을 대신 사용할 수 있습니다.

정확한 알람이 필요하지 않을 수 있는 사용 사례

다음 목록은 정확한 알람이 필요하지 않을 수 있는 일반적인 워크플로를 보여줍니다.

앱의 전체 기간 동안 타이밍 작업 예약
Handler 클래스에는 타이밍 작업을 처리하는 메서드(예: 앱이 실행 중인 동안 n초 동안 다음을 실행합니다. postAtTime()postDelayed(). 이러한 API는 실시간이 아닌 시스템 가동 시간을 사용합니다.
예약된 백그라운드 작업(예: 앱 업데이트 및 로그 업로드)
WorkManager시간에 민감한 주기적 작업을 예약하는 방법을 제공합니다. 반복 간격과 flexInterval (최소 15분)를 제공하여 작업의 세분화된 런타임을 정의합니다
특정 시간 후에 발생해야 하는 사용자 지정 작업(시스템이 유휴 상태이더라도)
부정확한 알람을 사용합니다. 구체적으로 setAndAllowWhileIdle()를 호출합니다.
특정 시간 후에 발생해야 하는 사용자 지정 작업
부정확한 알람을 사용합니다. 구체적으로 set()를 호출합니다.
지정된 기간 내에 발생할 수 있는 사용자 지정 작업
부정확한 알람을 사용합니다. 구체적으로 setWindow()를 호출합니다. 앱이 Android 12 이상을 타겟팅하는 경우 가장 작은 허용되는 기간 길이는 10분입니다.

정확한 알람을 설정하는 방법

앱은 다음 방법 중 하나를 사용하여 정확한 알람을 설정할 수 있습니다. 이러한 메서드 목록의 하단에 가까운 쪽이 더 많이 게재되도록 시간이 중요하지 않지만 더 많은 시스템 리소스가 필요합니다.

setExact()

다른 배터리 절약 조치가 적용되지 않는 한 향후 거의 정확한 시간에 알람을 호출합니다.

앱의 작업이 매우 중요합니다

setExactAndAllowWhileIdle()

배터리를 절약하는 경우에도 향후 거의 정확한 시간에 경보를 울릴 수 있습니다. 경보가 발효됩니다

setAlarmClock()

미래의 정확한 시간에 알람을 호출합니다. 이러한 알람은 사용자에게 매우 잘 표시되므로 시스템은 전송 시간을 조정하지 않습니다. 이 시스템은 이러한 경보를 가장 중요한 경보로 식별하고, 저전력 경보를 경보를 전달하는 데 필요한 경우 경보를 전달할 수 있습니다.

시스템 리소스 소비

시스템이 앱이 설정한 정확한 알람을 트리거하면 기기는 배터리 수명 같은 많은 자원을 소비합니다. 특히 절전 모드입니다. 또한 시스템에서 이러한 요청을 쉽게 일괄 처리할 수 없으며 이를 통해 리소스를 더 효율적으로 사용할 수 있습니다.

오류가 발생할 때마다 부정확한 알람을 만드는 것이 좋습니다. 있습니다. 더 긴 작업을 실행하려면 알람의 BroadcastReceiver에서 WorkManager 또는 JobScheduler를 사용하여 예약합니다. 작업을 수행하는 동안 기기가 잠자기 모드이면 setAndAllowWhileIdle(), 알람에서 작업을 시작할 수 있습니다.

적절한 정확한 알람 권한 선언

앱이 Android 12 이상을 타겟팅하는 경우 "알람 및 리마인더" 액세스할 수 있습니다. 이렇게 하려면 다음 코드 스니펫과 같이 앱의 매니페스트 파일에서 SCHEDULE_EXACT_ALARM 권한을 선언합니다.

<manifest ...>
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
    <application ...>
        ...
    </application>
</manifest>

앱이 Android 13(API 수준 33) 이상을 타겟팅하는 경우 SCHEDULE_EXACT_ALARM 또는 USE_EXACT_ALARM 권한을 선언할 수 있습니다.

<manifest ...>
    <uses-permission android:name="android.permission.USE_EXACT_ALARM"/>
    <application ...>
        ...
    </application>
</manifest>

SCHEDULE_EXACT_ALARMUSE_EXACT_ALARM 권한은 모두 대상은 동일한 권한을 부여받지만 다른 방식으로 부여되며 서로 다른 살펴보겠습니다 앱은 정확한 알람을 사용하고 다음 중 하나를 선언해야 합니다. SCHEDULE_EXACT_ALARM 또는 USE_EXACT_ALARM 권한(사용자 대상 기능이 작동하려면 시간이 정확히 정해진 작업이 필요합니다.

USE_EXACT_ALARM

SCHEDULE_EXACT_ALARM

  • 사용자가 부여함
  • 더 광범위한 사용 사례
  • 앱에서 권한이 취소되지 않았는지 확인해야 합니다.

SCHEDULE_EXACT_ALARM 권한은 Android 13(API 수준 33) 이상을 타겟팅하는 앱의 새로 설치 시 사전 부여되지 않습니다. 사용자가 앱을 이전하는 경우 Android 14를 실행하는 기기로 데이터를 전송하는 데 유용합니다. 새 기기에서 SCHEDULE_EXACT_ALARM 권한이 거부됩니다. 그러나 이 권한은 기존 앱에 이미 있는 경우 Android 14로 기기 업그레이드

참고: OnAlarmListener 객체에는 setExact API에서는 SCHEDULE_EXACT_ALARM 권한이 필요하지 않습니다.

SCHEDULE_EXACT_ALARM 권한 사용

USE_EXACT_ALARM와 달리 SCHEDULE_EXACT_ALARM 권한은 사용자가 부여해야 합니다. 사용자와 시스템 모두 SCHEDULE_EXACT_ALARM 권한

앱에 권한이 부여되었는지 확인하려면 정확한 알람을 설정하기 전에 canScheduleExactAlarms()를 호출합니다. SCHEDULE_EXACT_ALARM 권한이 있는 경우 앱 취소, 앱 중지, 향후 모든 정확한 알람 취소됩니다. 또한 canScheduleExactAlarms()에서 반환된 값은 앱의 전체 수명 주기 동안 유효하게 유지됩니다.

앱에 SCHEDULE_EXACT_ALARMS 권한이 부여되면 시스템에서 ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED 있습니다. 앱은 다음을 실행하는 broadcast receiver를 구현해야 합니다.

  1. 앱에 여전히 특수 앱 액세스 권한이 있는지 확인합니다. canScheduleExactAlarms()를 호출하면 됩니다. 이 검사는 사용자가 앱에 권한을 부여하는 케이스로부터 앱을 보호합니다. 그런 다음 거의 즉시 취소됩니다.
  2. 현재 상태에 따라 앱에 필요한 정확한 알람을 변경합니다. 이 로직은 앱이 ACTION_BOOT_COMPLETED 브로드캐스트를 수신할 때 실행하는 작업과 비슷합니다.

사용자에게 SCHEDULE_EXACT_ALARM 권한을 부여하도록 요청

&#39;알람 및 리마인더 설정 허용&#39; 옵션
그림 1. 사용자가 앱이 정확한 알람을 설정하도록 허용할 수 있는 시스템 설정의 '알람 및 리마인더' 특수 앱 액세스 권한 페이지

필요한 경우 그림 1과 같이 시스템 설정에서 사용자를 알람 및 리마인더 화면으로 보낼 수 있습니다. 그러려면 다음 단계를 완료하세요.

  1. 앱의 UI에서 사용자에게 앱이 정확한 알람을 예약해야 하는 이유를 설명합니다.
  2. ACTION_REQUEST_SCHEDULE_EXACT_ALARM 인텐트 작업이 포함된 인텐트를 호출합니다.

반복 알람 설정

반복 알람을 사용하면 시스템에서 반복 알람을 앱에 알릴 수 있습니다. 있습니다

알람이 제대로 설계되지 않으면 배터리가 소모되고 있습니다 따라서 Android 4.4(API 수준 19) 이상에서는 모든 반복 알람이 부정확한 알람입니다.

반복 알람은 다음과 같은 특성을 갖습니다.

  • 알람 유형입니다. 자세한 내용은 알람 유형 선택을 참조하세요.

  • 트리거 시간. 지정한 트리거 시간이 과거이면 알람이 즉시 트리거됩니다.

  • 알람의 간격. 예를 들어 하루에 한 번, 1시간마다, 5분마다 설정할 수 있습니다.

  • 알람이 트리거되면 실행되는 대기 중인 인텐트. 설정 시 동일한 대기 중 인텐트를 사용하는 두 번째 알람이 원래 알람을 대체합니다.

PendingIntent()를 취소하려면 FLAG_NO_CREATEPendingIntent.getService()에 전달하여 인텐트의 인스턴스(있는 경우)를 가져온 다음 그 인텐트를 AlarmManager.cancel()에 전달합니다.

Kotlin

val alarmManager =
    context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager
val pendingIntent =
    PendingIntent.getService(context, requestId, intent,
                                PendingIntent.FLAG_NO_CREATE)
if (pendingIntent != null && alarmManager != null) {
  alarmManager.cancel(pendingIntent)
}

자바

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);
}

알람 유형 선택

반복 알람을 사용할 때 가장 먼저 고려할 사항 중 하나는 알람 유형입니다.

알람에는 일반적으로 '실제 경과 시간', 두 가지 시계 유형이 있습니다. 및 "실시간 시계" (RTC) 실제 경과 시간은 '시스템 부팅 이후 시간'을 참조로 사용하며 실시간 시계는 UTC(실제 시간) 시간을 사용합니다. 즉, 실제 경과 시간은 시간의 경과를 기준으로 알람을 설정하는 데 적합합니다 (예: 예를 들어 30초마다 실행되는 알람). 지정할 수 있습니다. 실시간 시계 유형은 현재 언어에 따라 달라지는 알람에 더 적합합니다.

두 유형 모두 'wakeup'을 사용합니다. 해당 버전으로 돌아가면 기기의 CPU 절전 모드를 해제하라는 메시지가 표시됩니다. 화면이 꺼집니다. 이렇게 하면 예약된 시간에 알람이 실행됩니다. 앱에 시간 종속 항목이 있는 경우 유용합니다. 예를 들어 특정 작업을 수행하는 시간이 제한된 경우 Wakeup 버전의 알람 유형을 사용하지 않으면 기기가 다음에 켜질 때 모든 반복 알람이 실행됩니다.

특정 간격으로(예: 30분마다) 알람을 실행해야 한다면 실제 경과 시간 유형 중 하나를 사용합니다. 일반적으로 유형이 더 좋습니다.

알람이 하루 중 특정 시간에 울리도록 하려면 다음 중 하나를 선택하세요. 몇 가지 유형의 실시간 시계 유형이 있습니다. 그러나 이 접근 방식에는 몇 가지 단점이 있습니다. 앱이 다른 언어로 잘 번역되지 않을 수 있으며 사용자가 기기의 시간 설정을 변경하면 앱에서 예기치 않은 동작이 발생할 수 있습니다. 또한 실시간 시계 알람 유형을 사용하면 위에서 설명한 대로 확장이 잘 되지 않습니다. '실시간 경과 시간' 알람 할 수 있습니다.

다음은 유형 목록입니다.

  • ELAPSED_REALTIME: 기기가 초기화된 후 경과한 시간을 기준으로 대기 중인 인텐트를 실행합니다. 부팅되었지만 기기의 절전 모드를 해제하지는 않습니다. 이 경과 시간에는 기기가 절전 모드였던 시간이 포함됩니다.

  • ELAPSED_REALTIME_WAKEUP: 지정된 길이 이후에 기기의 절전 모드를 해제하고 대기 중인 인텐트를 실행합니다. 경과한 시간을 나타냅니다.

  • RTC: 지정된 시간에 대기 중인 인텐트를 실행하지만 기기의 절전 모드는 해제하지 않습니다.

  • RTC_WAKEUP: 지정된 시간에 기기의 절전 모드를 해제하여 대기 중인 인텐트를 실행합니다.

실제 경과 시간 알람의 예

다음은 ELAPSED_REALTIME_WAKEUP를 사용하는 예입니다.

30분 후, 30분마다 기기의 절전 모드를 해제하여 알람을 울립니다. 그 후에는 다음과 같이 합니다.

Kotlin

// 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
)

자바

// 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분 후에 기기의 절전 모드를 해제하여 일회성 알람(반복 없음)을 실행합니다.

Kotlin

private var alarmMgr: AlarmManager? = null
private lateinit var alarmIntent: PendingIntent
...
alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent ->
    PendingIntent.getBroadcast(context, 0, intent, 0)
}

alarmMgr?.set(
        AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + 60 * 1000,
        alarmIntent
)

자바

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);

실시간 시계 알람의 예

다음은 RTC_WAKEUP

대략 오후 2시에 기기의 절전 모드를 해제하여 알람을 실행하고 하루에 한 번씩 동일한 시간에 반복합니다.

Kotlin

// Set the alarm to start at approximately 2:00 p.m.
val calendar: Calendar = Calendar.getInstance().apply {
    timeInMillis = System.currentTimeMillis()
    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.timeInMillis,
        AlarmManager.INTERVAL_DAY,
        alarmIntent
)

자바

// 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분마다 기기의 절전 모드를 해제하여 알람을 실행합니다. 이후:

Kotlin

private var alarmMgr: AlarmManager? = null
private lateinit var alarmIntent: PendingIntent
...
alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent ->
    PendingIntent.getBroadcast(context, 0, intent, 0)
}

// Set the alarm to start at 8:30 a.m.
val calendar: Calendar = Calendar.getInstance().apply {
    timeInMillis = System.currentTimeMillis()
    set(Calendar.HOUR_OF_DAY, 8)
    set(Calendar.MINUTE, 30)
}

// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr?.setRepeating(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        1000 * 60 * 20,
        alarmIntent
)

자바

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);

알람이 얼마나 정확해야 하는지 결정

앞서 설명한 것처럼 알람을 만드는 첫 번째 단계는 알람 유형을 선택하는 것입니다. 알람이 얼마나 정확해야 하는지에 따라 구별할 수 있습니다. 있습니다. 대부분의 앱에서 setInexactRepeating() 하는 것이 올바른 선택입니다 이 메서드를 사용하면 Android는 여러 개의 부정확한 반복 알람을 동기화하고 동시에 실행합니다. 이렇게 하면 배터리 소모를 줄일 수 있습니다.

가능하면 정확한 알람을 사용하지 마세요. 하지만 경직된 앱의 경우 시간이 필요한 경우 다음을 호출하여 정확한 알람을 설정할 수 있습니다. setRepeating()

setInexactRepeating()을 사용하는 경우 setRepeating()과 같은 방법으로는 맞춤 간격을 지정할 수 없습니다. INTERVAL_FIFTEEN_MINUTES, INTERVAL_DAY 등 간격 상수 중 하나를 사용해야 합니다. 전체 목록은 AlarmManager를 참고하세요.

알람 취소

앱에 따라 알람을 취소하는 기능을 포함할 수도 있습니다. 알람을 취소하려면 알람 관리자의 cancel()을 호출하여 더 이상 실행하지 않을 PendingIntent를 전달합니다. 예를 들면 다음과 같습니다.

Kotlin

// If the alarm has been set, cancel it.
alarmMgr?.cancel(alarmIntent)

자바

// If the alarm has been set, cancel it.
if (alarmMgr!= null) {
    alarmMgr.cancel(alarmIntent);
}

기기가 다시 시작되면 알람 시작

기본적으로 기기를 종료하면 모든 알람이 취소됩니다. 이런 상황을 방지하려면 사용자가 기기를 재부팅할 때 자동으로 반복 알람을 다시 시작하도록 애플리케이션을 디자인해야 합니다. 이 AlarmManager가 사용자가 수동으로 알람을 다시 시작하지 않아도 작업을 계속 수행할 수 있습니다.

다음 단계를 따르세요.

  1. 애플리케이션의 매니페스트에 RECEIVE_BOOT_COMPLETED 권한을 설정합니다. 이 권한을 사용하면 시스템 부팅이 끝난 후에 앱은 브로드캐스팅되는 ACTION_BOOT_COMPLETED를 받습니다(사용자가 최소 한 번 이상 앱을 시작한 경우에만 동작함).

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  2. 구현 BroadcastReceiver 를 사용하여 브로드캐스트를 수신합니다.

    Kotlin

    class SampleBootReceiver : BroadcastReceiver() {
    
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.action == "android.intent.action.BOOT_COMPLETED") {
                // Set the alarm here.
            }
        }
    }
    

    자바

    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. 다음과 같이 앱의 매니페스트 파일에 ACTION_BOOT_COMPLETED 작업을 필터링하는 인텐트 필터와 함께 수신기를 추가합니다.

    <receiver android:name=".SampleBootReceiver"
            android:enabled="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"></action>
        </intent-filter>
    </receiver>

    매니페스트에서 부팅 수신기는 android:enabled="false"로 설정되어 있습니다. 즉, 수신자는 를 호출할 수 없습니다. 이렇게 하면 부팅 수신기가 불필요하게 호출되는 것을 방지할 수 있습니다. 다음과 같이 수신기를 사용할 수 있습니다(예: 사용자가 알람을 설정한 경우).

    Kotlin

    val receiver = ComponentName(context, SampleBootReceiver::class.java)
    
    context.packageManager.setComponentEnabledSetting(
            receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP
    )
    

    자바

    ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
    PackageManager pm = context.getPackageManager();
    
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);
    

    이런 방식으로 한 번 수신기를 사용하면 사용자가 기기를 재부팅해도 수신기는 사용할 수 있는 상태로 남아 있습니다. 즉, 프로그래매틱 방식으로 수신자를 사용 설정하는 것입니다. 매니페스트 설정을 재정의합니다. 수신자는 계속 앱에서 이를 중지할 때까지 사용하도록 설정해야 합니다 수신기를 사용 중지할 수 있습니다 (예: 경보를 취소하는 경우)에 따라 달라집니다.

    Kotlin

    val receiver = ComponentName(context, SampleBootReceiver::class.java)
    
    context.packageManager.setComponentEnabledSetting(
            receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP
    )
    

    자바

    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)을 실행하는 기기는 잠자기 사용할 수 있습니다. 기기의 배터리 수명을 연장하는 데 도움이 됩니다. 기기가 다음 상태일 때 알람이 울리지 않음 잠자기 모드 예약된 알람은 기기가 잠자기 모드를 종료할 때까지 지연됩니다. 기기가 유휴 상태일 때도 작업을 완료해야 하는 경우 사용할 수 있는 몇 가지 옵션이 있습니다.

  • 정확한 알람을 설정하세요.

  • 다음을 수행하도록 빌드된 WorkManager API를 사용합니다. 실행할 수도 있습니다 작업이 최대한 빨리 완료되도록 시스템에서 작업을 신속하게 처리해야 한다고 지정할 수 있습니다. 자세한 내용은 WorkManager로 작업 예약을 참고하세요.

권장사항

반복 알람 설정 시 선택하는 모든 선택에 따라 결과가 달라질 수 있습니다. 앱이 시스템 리소스를 사용 (또는 악용)하는 방식 예를 들어 서버에 동기화할 수 있습니다. 동기화 작업이 시계 시간을 기반으로 하고 앱의 모든 인스턴스가 오후 11시에 동기화된다면 서버의 부하로 지연 시간이 늘어나거나 '서비스 거부'가 발생할 수 있습니다. 알람 사용에 대한 권장사항은 다음과 같습니다.

  • 모든 네트워크 요청에 임의성 (지터)을 알람이 울리면 트리거됩니다.

    • 알람이 트리거될 때 로컬 작업을 수행합니다. '로컬 작업'은 서버에 도달하지 않거나 서버의 데이터를 요구하지 않는 모든 작업입니다.

    • 이와 동시에 발생할 수 있습니다.

  • 알람 빈도를 최소한으로 유지합니다.

  • 불필요하게 기기의 절전 모드를 해제하지 마세요(이 동작은 알람 유형 선택에 설명한 알람 유형에 따라 결정됨).

  • 알람 트리거 시간을 필요한 수준보다 정밀하게 설정하지 마세요.

    setRepeating() 대신 setInexactRepeating()을 사용하세요. setInexactRepeating()을 사용하면 Android는 여러 앱의 반복 알람을 동기화하고 동시에 실행합니다. 이렇게 하면 시스템이 기기의 절전 모드를 해제해야 하는 총횟수가 줄어들어 배터리 소모가 감소합니다. Android 4.4 기준 (API 수준 19) - 모든 반복 알람은 부정확한 알람입니다. setInexactRepeating()setRepeating()보다 개선되었지만 앱의 모든 인스턴스가 거의 동시에 서버에 도달하면 여전히 서버에 부담이 될 수 있습니다. 따라서 네트워크 요청의 경우 이전에 설명한 것처럼 알람에 임의성을 추가합니다.

  • 가능하면 시계 시간을 기준으로 알람을 설정하지 않도록 합니다.

    정확한 트리거 시간을 기준으로 하는 반복 알람은 확장되지 않습니다. 사용 다음 경우 ELAPSED_REALTIME 할 수 있습니다. 다양한 알람 유형은 다음 섹션에서 자세히 설명합니다.