Planowanie alarmów

Alarmy (na podstawie AlarmManager klasa), możesz w niej zagrać, oparte na czasie operacje poza okresem działania aplikacji. Na przykład możesz użyć alarmu do zainicjowania długo trwającej operacji, takiej jak uruchamiając usługę raz dziennie, aby pobrać prognozę pogody.

Alarmy mają następujące cechy:

  • Umożliwiają uruchamianie intencji w ustalonych odstępach czasu lub w określonych odstępach czasu.

  • Można ich używać w połączeniu z odbiornikami, aby zaplanować jobs lub WorkRequests do wykonania inne operacji.

  • Działają one poza Twoją aplikacją, więc możesz ich używać do aktywowania zdarzeń ani działań nawet wtedy, gdy aplikacja nie jest uruchomiona, nawet jeśli urządzenie sam śpi.

  • Pomagają zminimalizować wymagania dotyczące zasobów aplikacji. Możesz zaplanować bez uwzględniania liczników czasu i ciągłego działania usług.

.

Ustaw alarm niedokładny

Gdy aplikacja ustawi alarm nieprecyzyjny, system w pewnym momencie wyświetli alarm w przyszłości. Alarmy nieprecyzyjne dają pewne gwarancje czasu dostarczania alarmów przy jednoczesnym przestrzeganiu ograniczeń dotyczących oszczędzania baterii, takich jak: Uśpienie.

Deweloperzy mogą wykorzystać poniższe gwarancje interfejsu API, aby dostosować czas podanie nieprecyzyjnego alarmu.

Włącz alarm po określonej godzinie

Jeśli aplikacja wywołuje set(), setInexactRepeating(), lub setAndAllowWhileIdle(), alarm nigdy nie włączy się przed podanym czasem wyzwalania.

Na Androidzie 12 (poziom interfejsu API 31) i nowszych system wywołuje alarm w ciągu jednego godz. podanego czasu wyzwalania, chyba że występują jakiekolwiek ograniczenia oszczędzania baterii funkcji, takiej jak Oszczędzanie baterii lub Uśpienie.

Dostarcz alarm w wybranym przedziale czasu

Jeśli aplikacja zadzwoni pod numer setWindow(), alarm nigdy nie włączy się przed dostarczonym w czasie wyzwalacza. Jeśli nie są włączone żadne ograniczenia dotyczące oszczędzania baterii, alarm jest włączony dostarczone w określonym przedziale czasu, począwszy od danego wyzwalacza obecnie się znajdujesz.

Jeśli Twoja aplikacja jest kierowana na Androida 12 lub nowszego, system może opóźnić wywołanie nieprecyzyjnego alarmu z wyznaczonym przedziałem czasu o co najmniej 10 minut. Dla: z tego powodu, windowLengthMillis wartości parametru w kolumnie 600000 jest przycięte do 600000

Uruchamiaj powtarzający się alarm w mniej więcej regularnych odstępach czasu

Jeśli aplikacja wywołuje setInexactRepeating(), system wywołuje kilka alarmów:

  1. Pierwszy alarm uruchomi się w określonym przedziale czasu, licząc od danego czasu wyzwalacza.
  2. Kolejne alarmy zwykle włączają się po określonym przedziale czasu upłynie. Czas między dwoma kolejnymi wywołaniami alarmu może się różnić.

Ustaw dokładny alarm

System wywołuje dokładny alarm w konkretnym momencie w przyszłości.

Większość aplikacji może planować zadania i wydarzenia za pomocą nieprecyzyjnych alarmów, aby: wykonać kilka typowych przypadków użycia. Jeśli podstawowy element aplikacji działanie zależy od konkretnego czasu alarmu – np. w przypadku aplikacji budzika lub w aplikacji kalendarza – możesz zamiast tego użyć konkretnego alarmu.

Przypadki użycia, które mogą nie wymagać alarmów precyzyjnych

Na liście poniżej znajdziesz typowe przepływy pracy, które mogą nie wymagać dokładnego alarmu:

Planowanie operacji czasowych w trakcie użytkowania aplikacji
Zajęcia Handler zawierają kilka dobrych do obsługi operacji czasowych, na przykład wykonywanie części zadań Gdy aplikacja jest aktywna, n s: postAtTime() oraz postDelayed(). Pamiętaj, że te interfejsy API zależą od czasu działania systemu a nie w czasie rzeczywistym.
zaplanowane prace w tle, takie jak aktualizowanie aplikacji i przesyłanie dzienników;
WorkManager umożliwia zaplanowanie okresowych okresów zależnego od czasu pracy. Możesz podać interwał powtarzania i flexInterval (co najmniej 15 minut), aby określić szczegółowe środowisko wykonawcze danej pracy.
Działanie określone przez użytkownika, które powinno zostać wykonane po określonym czasie (nawet jeśli system jest nieaktywny)
Użyj alarmu nieprecyzyjnego. A konkretnie chodzi o wywołanie setAndAllowWhileIdle()
Działanie określone przez użytkownika, które powinno zostać wykonane po określonym czasie
Użyj alarmu nieprecyzyjnego. A konkretnie chodzi o wywołanie set()
Działanie określone przez użytkownika, które może zostać wykonane w określonym przedziale czasu
Użyj alarmu nieprecyzyjnego. A konkretnie chodzi o wywołanie setWindow() Jeśli aplikacja jest kierowana na Androida 12 lub nowszego, najmniejszą dozwolona długość okna to 10 minut.

Sposoby ustawiania dokładnego alarmu

Aplikacja może ustawiać alarmy precyzyjne za pomocą jednej z poniższych metod. Metody te są uporządkowane w taki sposób, że te na samym dole listy wyświetlają się częściej do wykonywania kluczowych zadań, ale wymagają więcej zasobów systemowych.

setExact()

Wywołuj alarm w niemal dokładnym momencie w przyszłości, o ile inne oszczędzanie baterii nie działa.

Użyj tej metody, aby ustawić alarmy precyzyjne, chyba że aplikacja ma kluczowe znaczenie dla użytkownika.

setExactAndAllowWhileIdle()

Wywołuj alarm w niemal dokładnym czasie w przyszłości, nawet przy oszczędzaniu baterii środków ochrony.

setAlarmClock()

Wywołaj alarm w konkretnym czasie w przyszłości. Ponieważ te alarmy są są bardzo widoczne dla użytkowników, system nigdy nie dostosowuje czasu dostawy. system określa te alarmy jako najważniejsze i pozostawia niskie zużycie energii w razie potrzeby w celu uruchomienia alarmów.

Wykorzystanie zasobów systemowych

Gdy system aktywuje alarm precyzyjny ustawiony przez aplikację, zużywa dużo zasobów, takich jak żywotność baterii, zwłaszcza jeśli jest w trybie oszczędzania energii. System nie może też łatwo grupować tych żądań. aby efektywniej korzystać z zasobów.

Zdecydowanie zalecamy utworzenie nieprecyzyjnego alarmu, gdy tylko jak to tylko możliwe. Aby wykonać dłuższą pracę, zaplanuj ją za pomocą WorkManager lub JobScheduler od alarmu BroadcastReceiver Aby wykonywać pracę, podczas gdy urządzenie jest w trybie uśpienia, utwórz niedokładny alarm, używając: setAndAllowWhileIdle() i uruchomienie zadania z poziomu alarmu.

Zadeklaruj odpowiednie uprawnienia dostępu do precyzyjnych alarmów

Jeśli Twoja aplikacja jest kierowana na Androida 12 lub nowszego, musisz uzyskać "Alarmy i przypomnienia” aplikacji ze specjalnym dostępem. Aby to zrobić, zadeklaruj parametr SCHEDULE_EXACT_ALARM zgodnie z poniższym fragmentem kodu:

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

Jeśli Twoja aplikacja jest kierowana na Androida 13 (poziom interfejsu API 33) lub nowszego, możesz wybrać zadeklaruj SCHEDULE_EXACT_ALARM lub USE_EXACT_ALARM uprawnienia.

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

Chociaż uprawnienia SCHEDULE_EXACT_ALARM i USE_EXACT_ALARM które wskazują te same możliwości, są przyznawane w różny sposób i obsługują różne i zastosowania. Aplikacja powinna używać alarmów precyzyjnych i zadeklarować jedną Uprawnienie SCHEDULE_EXACT_ALARM lub USE_EXACT_ALARM – tylko wtedy, gdy jest widoczne dla użytkownika wymaga wykonywania działań w precyzyjnie określonym czasie.

USE_EXACT_ALARM

SCHEDULE_EXACT_ALARM

  • Przyznane przez użytkownika
  • Szerszy zestaw przypadków użycia
  • Aplikacja powinna potwierdzić, że uprawnienia nie zostały cofnięte.

Uprawnienie SCHEDULE_EXACT_ALARM nie jest wstępnie przyznane nowym instalacjom aplikacji kierowane na Androida 13 (poziom interfejsu API 33) i nowsze wersje. Jeśli użytkownik przenosi aplikację na urządzeniu z Androidem 14 w ramach operacji tworzenia i przywracania kopii zapasowej, Uprawnienia dla aplikacji SCHEDULE_EXACT_ALARM zostaną odrzucone na nowym urządzeniu. Jeśli jednak istniejąca aplikacja ma już to uprawnienie, zostanie ono przyznane wstępnie, gdy aktualizacji urządzeń do Androida 14.

Uwaga: jeśli dokładny alarm jest ustawiony przy użyciu tagu OnAlarmListener. taki jak w tagu setExact. API, uprawnienie SCHEDULE_EXACT_ALARM nie jest wymagane.

Korzystanie z uprawnienia SCHEDULE_EXACT_ALARM

W przeciwieństwie do zasady USE_EXACT_ALARM uprawnienie SCHEDULE_EXACT_ALARM musi mieć: przyznanych przez użytkownika. Zarówno użytkownik, jak i system mogą unieważnić Uprawnienie SCHEDULE_EXACT_ALARM.

Aby sprawdzić, czy aplikacja otrzymała odpowiednie uprawnienia, wywołaj canScheduleExactAlarms() zanim spróbujesz ustawić dokładny alarm. Gdy uprawnienie SCHEDULE_EXACT_ALARM zostanie unieważniona w przypadku Twojej aplikacji, aplikacja przestanie działać i wszystkie przyszłe alarmy precyzyjne zostaną zostały anulowane. Oznacza to również, że wartość zwracana przez funkcję Pole canScheduleExactAlarms() jest ważne przez cały cykl życia aplikacji.

Gdy aplikacja otrzyma uprawnienie SCHEDULE_EXACT_ALARMS, system wysyła do niej ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED. transmisję. Aplikacja powinna wdrożyć transmisję odbiornik, który :

  1. potwierdza, że aplikacja nadal ma uprawnienia dostępu do określonych aplikacji. Aby to zrobić, zadzwoń: canScheduleExactAlarms() Ta kontrola chroni aplikację przed przypadkiem, gdy użytkownik przyzna jej uprawnienia, które zostanie cofnięte niemal natychmiast.
  2. Zmienia terminy alarmów precyzyjnych, których potrzebuje aplikacja, na podstawie jej bieżącego stanu. Powinna to być podobna logika do działania aplikacji, gdy otrzyma ACTION_BOOT_COMPLETED transmisję.

Poproś użytkowników o przyznanie uprawnień SCHEDULE_EXACT_ALARM

Opcja „Zezwalaj na ustawianie alarmów i przypomnień”
Rysunek 1. "Alarmy i przypomnienia” aplikacje ze specjalnym dostępem w ustawieniach systemowych. Użytkownicy mogą zezwolić aplikacji na alarmów.

W razie potrzeby można również przekierować użytkowników do sekcji Alarmy i ekran z przypomnieniami tak jak na rys. 1. W tym celu wykonaj następujące czynności:

  1. W interfejsie aplikacji wyjaśnij użytkownikowi, dlaczego musi ona dokładnie zaplanować alarmów.
  2. Wywołaj intencję, która zawiera parametr ACTION_REQUEST_SCHEDULE_EXACT_ALARM działanie intencji.

Ustawianie powtarzania alarmu

Powtarzające się alarmy umożliwiają systemowi powiadamianie aplikacji harmonogram.

Źle zaprojektowany alarm może spowodować wyczerpanie baterii i znaczne obciążenie serwerów. Dlatego w Androidzie 4.4 (poziom interfejsu API 19) i nowszych powtarzające się alarmy to alarmy nieprecyzyjne.

Powtarzające się alarmy mają następujące cechy:

  • Typ alarmu. Więcej informacji znajdziesz w artykule Wybieranie typu alarmu.

  • Czas wyzwalania. Jeśli podany czas wyzwolenia przypada w przeszłości, uruchamia się natychmiast.

  • Interwał alarmu. Na przykład raz dziennie, co godzinę lub co 5 minut.

  • Intencja oczekująca, która uruchamia się po aktywowaniu alarmu. Jeśli ustawisz drugi alarm, który korzysta z tej samej oczekującej intencji, zastępuje pierwotny alarm.

Aby anulować: PendingIntent(), prześlij FLAG_NO_CREATE. do PendingIntent.getService() aby pobrać wystąpienie intencji (jeśli istnieje), a potem przekazać tę intencję do 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)
}

Java

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

Wybierz typ alarmu

Jedną z pierwszych kwestii, które należy wziąć pod uwagę, jest typ powtarzającego się alarmu. co powinno być takie samo.

Istnieją 2 ogólne typy zegarów dla alarmów: „Czas rzeczywisty” oraz "zegar w czasie rzeczywistym" (RTC). Czas, jaki upłynął, używa „czasu od uruchomienia systemu” jako a zegar w czasie rzeczywistym używa czasu UTC (zegara ściennego). Oznacza to, że upłynięcia czasu rzeczywistego jest odpowiedni do ustawiania alarmu na podstawie upływu czasu (na np. alarm uruchamiany co 30 sekund), który nie na niego oddziałuje strefy czasowej lub języka. Zegar w czasie rzeczywistym lepiej sprawdza się w przypadku alarmów, które: zależą od regionu.

Oba rodzaje „wybudzenia” mają czyli wybudzać procesor, jeśli ekran jest wyłączony. Dzięki temu alarm uruchomi się o zaplanowanej godzinie. Jest to przydatne, jeśli aplikacja ma zależność czasową. Na przykład: przez ograniczony czas na wykonanie określonej operacji. Jeśli nie używasz tagu wybudzenia typu, to potem zostaną uruchomione wszystkie powtarzające się alarmy. gdy urządzenie zostanie wybudzone.

Jeśli chcesz, aby alarm uruchomił się w określonych odstępach czasu (na przykład co pół godziny), użyj jednego z rodzajów czasu rzeczywistego. Ogólnie rzecz biorąc, to lepszy wybór.

Jeśli chcesz, aby alarm uruchomił się o określonej porze dnia, wybierz jeden z podanych terminów. zegarów w czasie rzeczywistym. Pamiętaj jednak, że to podejście może mają pewne wady. Aplikacja może nie tłumaczyć prawidłowo na inne języki, a jeśli użytkownik zmieni ustawienie czasu na urządzeniu, może to spowodować nieoczekiwane działanie w aplikacji. Nie skaluje się też korzystanie z typu budzika zegara czasu rzeczywistego, omówiono powyżej. Zalecamy korzystanie z raportów „Upłynęło w czasie rzeczywistym”, alarm jeśli to możliwe.

Oto lista typów:

  • ELAPSED_REALTIME: Uruchamia intencję oczekującą na podstawie czasu, który upłynął od jest uruchamiany, ale go nie wybudza. Upłynęło – obejmuje każdy czas, w którym urządzenie było uśpione.

  • ELAPSED_REALTIME_WAKEUP: Wybudza urządzenie i uruchamia intencję oczekującą po określonej długości ile czasu upłynęło od uruchomienia urządzenia.

  • RTC: Uruchamia oczekującą intencję o określonym czasie, ale nie wybudza urządzenia.

  • RTC_WAKEUP: wybudzenia w określonym czasie, aby uruchomić intencję oczekującą.

Przykłady alarmów upływających w czasie rzeczywistym

Oto kilka przykładów użycia ELAPSED_REALTIME_WAKEUP

Wybudź urządzenie po 30 minutach i co 30 minut potem:

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
)

Java

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

Wybudź urządzenie w ciągu minuty, aby uruchomić jednorazowy (niepowtarzający się) alarm:

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
)

Java

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

Przykłady alarmów zegara w czasie rzeczywistym

Oto kilka przykładów użycia funkcji RTC_WAKEUP

Obudź urządzenie, aby uruchomić alarm około 14:00. powtarzaj raz dziennie o tej samej porze:

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
)

Java

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

Wybudź urządzenie, aby alarm uruchomił się dokładnie o 8:30 i co 20 minut potem:

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
)

Java

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

Określ, jak dokładny ma być alarm

Jak już wspomnieliśmy, wybór typu alarmu jest często pierwszym krokiem tworzenia alarmu. Kolejną różnicą jest to, jak dokładny jest alarm. . W przypadku większości aplikacji setInexactRepeating() jest właściwym wyborem. Gdy używasz tej metody, Android synchronizuje wiele nieprecyzyjnie powtarzanych alarmów i pożarów jednocześnie. Zmniejszy to zużycie baterii.

W miarę możliwości unikaj alarmów precyzyjnych. W rzadkich aplikacjach, które działają sztywno czas, możesz ustawić dokładny alarm, dzwoniąc pod numer setRepeating().

Dzięki setInexactRepeating() nie możesz określić niestandardowego interwału w taki sam sposób, jak setRepeating() Musisz użyć jednej ze stałych interwałów, np. INTERVAL_FIFTEEN_MINUTES INTERVAL_DAY, i tak dalej. Zobacz AlarmManager aby zobaczyć ich pełną listę.

Anuluj alarm

W zależności od aplikacji warto dodać opcję anulowania alarmu. Aby anulować alarm, zadzwoń pod numer cancel() w Menedżerze alarmów, podając PendingIntent, których już nie chcesz wystrzelić. Na przykład:

Kotlin

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

Java

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

Włącz alarm po ponownym uruchomieniu urządzenia

Domyślnie wszystkie alarmy są anulowane po wyłączeniu urządzenia. Aby temu zapobiec, możesz zaprojektować aplikację aby automatycznie powtarzać alarm, gdy użytkownik uruchomi urządzenie ponownie. Ten gwarantuje, że AlarmManager kontynuowanie pracy bez konieczności ręcznego ponownego uruchamiania alarmu.

Aby to zrobić:

  1. Ustawianie RECEIVE_BOOT_COMPLETED w pliku manifestu aplikacji. Dzięki temu aplikacja będzie mogła otrzymywać ACTION_BOOT_COMPLETED który jest wysyłany po zakończeniu rozruchu systemu (działa to tylko wtedy, gdy została już co najmniej raz uruchomiona przez użytkownika):

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  2. Zaimplementuj BroadcastReceiver aby odebrać transmisję:

    Kotlin

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

    Java

    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. Dodaj odbiorcę do pliku manifestu aplikacji za pomocą filtra intencji, który filtry w ACTION_BOOT_COMPLETED działanie:

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

    Zwróć uwagę, że w manifeście odbiornik jest ustawiony na android:enabled="false" Oznacza to, że odbiorca nie może być wywoływana, dopóki aplikacja jej nie włączy. Zapobiega to odbiornika rozruchowego przed niepotrzebnym wywoływaniem. Możesz włączyć odbiornik (na przykład po ustawieniu przez użytkownika alarmu):

    Kotlin

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

    Java

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

    Po włączeniu tego sposobu odbiornik pozostanie włączony, nawet jeśli użytkownik uruchamia urządzenie ponownie. Innymi słowy, automatyczne włączenie odbiornika zastępuje ustawienie manifestu, nawet po ponownym uruchomieniu. Odbiorca zostanie będzie włączony, dopóki aplikacja go nie wyłączy. Możesz wyłączyć odbiornik (na przykład jeśli użytkownik anuluje alarm) w następujący sposób:

    Kotlin

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

    Java

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

Wywołuj alarmy, gdy urządzenie jest w trybie uśpienia

Urządzenia z Androidem 6.0 (poziom interfejsu API 23) Uśpienie który pomaga wydłużyć czas pracy urządzenia na baterii. Alarmy nie są sygnalizowane, gdy urządzenie jest w Tryb uśpienia Wszystkie zaplanowane alarmy zostaną odłożone do momentu zamknięcia urządzenia. W razie potrzeby nawet gdy urządzenie jest bezczynne, istnieje kilka opcji dostępne:

Sprawdzone metody

Każdy wybór dokonany przy projektowaniu powtarzającego się alarmu może mieć konsekwencje sposobu wykorzystywania (lub nadużywania) zasobów systemowych przez aplikację. Wyobraź sobie na przykład, że chcesz utworzyć jest to popularna aplikacja, która synchronizuje się z serwerem. Jeśli operacja synchronizacji jest oparta na zegarze a każde jej wystąpienie synchronizuje się o 23:00, a obciążenie może spowodować duże opóźnienia, a nawet „doskonałej jakości usługi”. Postępuj zgodnie z tymi sprawdzonymi metodami używania alarmów:

  • Dodaj losowość (zakłócenia) do wszystkich żądań sieciowych, które uruchomienie w wyniku powtarzającego się alarmu:

    • Po uruchomieniu alarmu wykonaj dowolną pracę lokalną. „Praca lokalna” oznacza wszystko, nie dociera do serwera ani nie wymaga danych od serwera.

    • Jednocześnie zaplanuj alarm, który zawiera żądania sieciowe dotyczące uruchamiały się w losowym czasie.

  • Dopilnuj, aby częstotliwość alarmu była jak najmniejsza.

  • Nie wybudzaj urządzenia niepotrzebnie (to działanie jest zależne od zgodnie z opisem w sekcji Wybieranie typu alarmu).

  • Nie ustawiaj dokładnej godziny włączenia alarmu.

    Używaj setInexactRepeating() zamiast setRepeating() Gdy korzystasz z setInexactRepeating(), Android synchronizuje powtarzające się alarmy z wielu aplikacji i pożarów jednocześnie. Zmniejsza to łączną liczbę przypadków, w których system musi wybudzić urządzenia, zmniejszając w ten sposób obciążenie baterii. Od Android 4.4 (poziom API 19), wszystkie powtarzające się alarmy są alarmami nieprecyzyjnymi. Notatka że chociaż setInexactRepeating() jest lepszy niż setRepeating(), może on mimo wszystko obciążyć serwer, jeśli dotrze do niego każde wystąpienie aplikacji. mniej więcej w tym samym czasie. Dlatego w przypadku żądań sieciowych zwiększ losowość jak już wcześniej omówiliśmy alarmy.

  • W miarę możliwości unikaj używania budzika na podstawie godziny.

    Powtarzające się alarmy oparte na dokładnym czasie aktywacji nie są dobrze skalowane. Używaj ELAPSED_REALTIME, jeśli jak to możliwe. Inny alarm omówiono bardziej szczegółowo w następnej sekcji.