Usługi działające na pierwszym planie

Usługi działające na pierwszym planie wykonują operacje, które są widoczne dla użytkownika.

Usługi działające na pierwszym planie pokazują pasek stanu. , aby poinformować użytkowników, aplikacja wykonuje zadanie na pierwszym planie i zużywa zasoby systemowe.

Przykłady aplikacji korzystających z usług na pierwszym planie:

  • Aplikacja odtwarzacza muzyki, która odtwarza muzykę w usłudze na pierwszym planie. Powiadomienie może zawierać aktualnie odtwarzany utwór.
  • Aplikacja do fitnessu, która rejestruje aktywność użytkownika w usłudze na pierwszym planie po uzyskać zgodę użytkownika. Powiadomienie może zawierać odległość pokonany przez użytkownika podczas bieżącej sesji fitness.

Używaj usług na pierwszym planie tylko wtedy, gdy aplikacja musi wykonać określone działanie jest zauważalna dla użytkownika, nawet jeśli nie wchodzi w bezpośrednią interakcję z aplikację. Jeśli działanie jest na tyle mało ważne, że chcesz użyć tagu powiadomienie o minimalnym priorytecie, utwórz tło zadania.

Ten dokument opisuje uprawnienia wymagane do korzystania z usług na pierwszym planie. oraz jak uruchomić usługę na pierwszym planie i usunąć ją z tle. Dodatkowo opisuje, jak powiązać określone przypadki użycia z typami usług na pierwszym planie; ograniczenia dostępu obowiązujące po uruchomieniu usługi na pierwszym planie; z aplikacji, która działa w tle.

Użytkownik może domyślnie zamknąć powiadomienie

Od Androida 13 (poziom interfejsu API 33) użytkownicy mogą zamknąć powiadomienie powiązane z usługą na pierwszym planie. Aby to zrobić, użytkownicy muszą przesunąć palcem wykonać gest na powiadomieniu. Zazwyczaj powiadomienie nie jest zamykana, chyba że usługa działająca na pierwszym planie zostanie zatrzymana lub usunięta

Jeśli chcesz, aby użytkownik nie mógł zamknąć powiadomienia, przekaż true w: setOngoing() podczas tworzenia powiadomienia za pomocą funkcji Notification.Builder.

Usługi, które wyświetlają powiadomienie natychmiast

Jeśli usługa działająca na pierwszym planie ma co najmniej jedną z tych cech, pokazuje powiązane powiadomienie tuż po uruchomieniu usługi, nawet na urządzeniach z Androidem 12 lub nowszym:

Na Androidzie 13 (poziom interfejsu API 33) lub nowszym, jeśli użytkownik odmówi zgody zgodę na wyświetlanie powiadomień, nadal widzą powiadomienia związane z usługami na pierwszym planie Menedżer zadań ale nie widać ich w panelu powiadomień.

Deklarowanie usług działających na pierwszym planie w pliku manifestu

W pliku manifestu aplikacji zadeklaruj każdą usługę działającą na pierwszym planie z <service> . W przypadku każdej usługi użyj parametru Atrybut android:foregroundServiceType do zadeklarowania rodzaju pracy wykonywanej przez usługę.

Jeśli na przykład aplikacja tworzy usługę na pierwszym planie, która odtwarza muzykę, może zadeklarować usługę w ten sposób:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
  <application ...>

    <service
        android:name=".MyMediaPlaybackService"
        android:foregroundServiceType="mediaPlayback"
        android:exported="false">
    </service>
  </application>
</manifest>

Jeśli do Twojej usługi ma zastosowanie kilka typów, rozdziel je za pomocą atrybutu | . Na przykład usługa, która używa kamery i mikrofonu będzie wyglądać tak:

android:foregroundServiceType="camera|microphone"

Wysyłanie prośby o uprawnienia usługi na pierwszym planie

Aplikacje kierowane na Androida 9 (poziom interfejsu API 28) lub nowszego i korzystające z usług działających na pierwszym planie poprosić o FOREGROUND_SERVICE w manifeście aplikacji, jak widać w tym fragmencie kodu. To normalne uprawnienia, tak więc system automatycznie przyznaje go aplikacji, która wysłała żądanie.

Ponadto jeśli aplikacja jest kierowana na interfejs API na poziomie 34 lub wyższym, musi żądać parametru odpowiedni typ uprawnień do danego rodzaju pracy, co robię. Każdy typ usługi na pierwszym planie. ma odpowiedni typ uprawnienia. Jeśli na przykład aplikacja uruchamia usługa działająca na pierwszym planie, która korzysta z kamery, musisz zażądać FOREGROUND_SERVICE i FOREGROUND_SERVICE_CAMERA uprawnień. To są wszystkie normalne uprawnienia, które system przyznał automatycznie, o ile są uwzględnione w pliku manifestu.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>

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

    <application ...>
        ...
    </application>
</manifest>

Wymagania wstępne usługi działającej na pierwszym planie

Począwszy od Androida 14 (poziom interfejsu API 34) po uruchomieniu usługi na pierwszym planie system sprawdza określone wymagania wstępne na podstawie typu usługi. Przykład: jeśli spróbujesz uruchomić usługę działającą na pierwszym planie typu location, system sprawdzi, aby upewnić się, że aplikacja ma już te uprawnienia: ACCESS_COARSE_LOCATION lub Uprawnienia: ACCESS_FINE_LOCATION. Jeśli nie, system zgłasza SecurityException

Z tego powodu musisz potwierdzić, że zostały spełnione wymagane warunki wstępne przed uruchomieniem usługi na pierwszym planie. Usługa działająca na pierwszym planie type zawiera listę wymagań wstępnych dla każdego typu usługi na pierwszym planie.

Uruchom usługę na pierwszym planie

Zanim poprosisz system o uruchomienie usługi jako usługi na pierwszym planie, uruchom samej usługi:

Kotlin

val intent = Intent(...) // Build the intent for the service
context.startForegroundService(intent)

Java

Context context = getApplicationContext();
Intent intent = new Intent(...); // Build the intent for the service
context.startForegroundService(intent);

W usłudze, zwykle w onStartCommand(), możesz poprosić o dostęp uruchomienia usługi na pierwszym planie. Aby to zrobić, zadzwoń: ServiceCompat.startForeground() (funkcja dostępna w systemie Androidx z rdzeniem 1.12 lub nowszym). Ta metoda przyjmuje następujące parametry:

Te typy mogą być podzbiorem typów zadeklarowanych w pliku manifestu, w zależności od konkretnego przypadku użycia. Jeśli chcesz dodać więcej typów usług, możesz ponownie zadzwonić do: startForeground().

Załóżmy na przykład, że aplikacja do fitnessu korzysta z usługi z trackerem, który zawsze potrzebuje informacji z usługi location, ale być może nie będzie potrzebować multimediów. Ty będzie musiał zadeklarować w pliku manifestu zarówno location, jak i mediaPlayback. Jeśli rozpoczyna bieg i chce tylko śledzić jego lokalizację, aplikacja powinna wywołać startForeground() i przekazać tylko uprawnienie ACCESS_FINE_LOCATION. Następnie: jeśli użytkownik chce zacząć odtwarzać dźwięk, zadzwoń ponownie do startForeground() przekazywać bitową kombinację wszystkich typów usług na pierwszym planie (w tym przypadku ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK).

Oto przykład, który uruchamia usługę kamery na pierwszym planie:

Kotlin

class MyCameraService: Service() {

  private fun startForeground() {
    // Before starting the service as foreground check that the app has the
    // appropriate runtime permissions. In this case, verify that the user has
    // granted the CAMERA permission.
    val cameraPermission =
            PermissionChecker.checkSelfPermission(this, Manifest.permission.CAMERA)
    if (cameraPermission != PermissionChecker.PERMISSION_GRANTED) {
        // Without camera permissions the service cannot run in the foreground
        // Consider informing user or updating your app UI if visible.
        stopSelf()
        return
    }

    try {
        val notification = NotificationCompat.Builder(this, "CHANNEL_ID")
            // Create the notification to display while the service is running
            .build()
        ServiceCompat.startForeground(
            /* service = */ this,
            /* id = */ 100, // Cannot be 0
            /* notification = */ notification,
            /* foregroundServiceType = */
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
            } else {
                0
            },
        )
    } catch (e: Exception) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
                && e is ForegroundServiceStartNotAllowedException) {
            // App not in a valid state to start foreground service
            // (e.g. started from bg)
        }
        // ...
    }
  }
}

Java

public class MyCameraService extends Service {

    private void startForeground() {
        // Before starting the service as foreground check that the app has the
        // appropriate runtime permissions. In this case, verify that the user
        // has granted the CAMERA permission.
        int cameraPermission =
            ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
        if (cameraPermission == PackageManager.PERMISSION_DENIED) {
            // Without camera permissions the service cannot run in the
            // foreground. Consider informing user or updating your app UI if
            // visible.
            stopSelf();
            return;
        }

        try {
            Notification notification =
                new NotificationCompat.Builder(this, "CHANNEL_ID")
                    // Create the notification to display while the service
                    // is running
                    .build();
            int type = 0;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                type = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA;
            }
            ServiceCompat.startForeground(
                    /* service = */ this,
                    /* id = */ 100, // Cannot be 0
                    /* notification = */ notification,
                    /* foregroundServiceType = */ type
            );
        } catch (Exception e) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
                    e instanceof ForegroundServiceStartNotAllowedException
            ) {
                // App not in a valid state to start foreground service
                // (e.g started from bg)
            }
            // ...
        }
    }

    //...
}

Usuwanie usługi z pierwszego planu

Aby usunąć usługę z pierwszego planu, wywołaj stopForeground() Ta metoda korzysta z wartości logicznej, która wskazuje, czy usunąć pasek stanu powiadomienia. Pamiętaj, że usługa będzie nadal działać.

Jeśli zatrzymasz usługę, gdy działa na pierwszym planie, jej powiadomienie została usunięta.

Obsługuj zainicjowane przez użytkownika zatrzymywanie aplikacji działających na pierwszym planie

U dołu szuflady powiadomień znajduje się przycisk, który wskazuje
    liczba aplikacji działających obecnie w tle. Po naciśnięciu
    pojawi się okno z listą nazw różnych aplikacji. 
    Przycisk zatrzymania znajduje się po prawej stronie każdej aplikacji
Rysunek 1. Procedura w Menedżerze zadań na urządzeniach, mieć system Android 13 lub nowszy,

Począwszy od Androida 13 (poziom interfejsu API 33) użytkownicy mogą wykonywać przepływ pracy z poziomu interfejsu panel powiadomień do zatrzymania aplikacji, która ma włączone usługi na pierwszym planie, niezależnie od tego, docelową wersję pakietu SDK. Afordancja, nazywana Menedżer zadań zawiera listę aplikacji, które są uruchomiono usługę na pierwszym planie.

Ta lista jest oznaczona jako Aktywne aplikacje. Obok każdej aplikacji znajduje się przycisk Zatrzymaj. Ilustracja 1 przedstawia Przepływ pracy w Menedżerze zadań na uruchomionym urządzeniu Android 13.

Gdy użytkownik naciśnie przycisk Zatrzymaj obok Twojej aplikacji w Menedżera zadań, wykonaj te czynności:

  • System usunie aplikację z pamięci. W związku z tym cała aplikacja zostanie zatrzymana, a nie tylko działającą na pierwszym planie.
  • System usunie stos aktywności w aplikacji.
  • Odtwarzanie multimediów zostanie zatrzymane.
  • Powiadomienie powiązane z usługą na pierwszym planie zostanie usunięte.
  • Aplikacja pozostaje w historii.
  • Zaplanowane zadania są wykonywane o zaplanowanej godzinie.
  • Alarmy dzwonią o zaplanowanej godzinie lub w przedziale czasowym.
.

Aby sprawdzić, czy aplikacja działa zgodnie z oczekiwaniami podczas i po zatrzymaniu app, uruchom następujące polecenie ADB w oknie terminala:

adb shell cmd activity stop-app PACKAGE_NAME

Zwolnienia

System zapewnia kilka poziomów odstąpień dla określonych rodzajów aplikacji: co zostały opisane w kolejnych sekcjach.

Wykluczenia dotyczą poszczególnych aplikacji, a nie procesów. Jeśli system wykluczy jeden proces w wszystkie inne procesy w tej aplikacji również są wykluczone.

.

wykluczenia z wyświetlania w Menedżerze zadań.

Te aplikacje mogą działać jako usługi na pierwszym planie i nie pojawiają się w Menedżer zadań:

  • Aplikacje na poziomie systemu
  • aplikacje zwiększające bezpieczeństwo; czyli aplikacje, które zawierają Rola ROLE_EMERGENCY
  • Urządzenia, które znajdują się w: tryb demonstracyjny

Wykluczenia, których użytkownicy mogą nie zatrzymać

Gdy te typy aplikacji uruchamiają usługę na pierwszym planie, pojawiają się w sekcji Menedżera zadań, ale obok przycisku Zatrzymaj nie ma przycisku Zatrzymaj. nazwa aplikacji, którą użytkownik może kliknąć:

Używaj przeznaczonych do tego interfejsów API zamiast usług działających na pierwszym planie

W wielu przypadkach istnieją interfejsy API platformy lub Jetpack, których można użyć do pracy. w przeciwnym razie możesz użyć usługi na pierwszym planie. Jeśli istnieje odpowiedni interfejsu API stworzonego pod kątem celu, powinien być prawie zawsze używany zamiast pierwszego planu posprzedażna. Specjalistyczne interfejsy API często zapewniają dodatkowe, specyficzne dla danego przypadku użycia które w innym wypadku nie stworzyliby samodzielnie. Przykład: interfejs Bubbles API obsługuje złożoną logikę UI aplikacje do obsługi wiadomości, które muszą korzystać z funkcji dymków na czacie.

Dokumentacja typów usług działających na pierwszym planie. dobrych rozwiązań alternatywnych zamiast usług na pierwszym planie.

Ograniczenia dotyczące uruchamiania usług na pierwszym planie w tle

Aplikacje kierowane na Androida 12 lub nowszego nie mogą rozpoczynać się na pierwszym planie usług, gdy aplikacja działa w tle, z wyjątkiem kilku specjalnych . Jeśli aplikacja próbuje uruchomić usługa na pierwszym planie, gdy aplikacja działa w tle oraz na pierwszym planie nie spełniono jednego z wyjątkowych przypadków, system wysyła żądanie ForegroundServiceStartNotAllowedException

Ponadto, jeśli aplikacja chce uruchomić usługę na pierwszym planie, która wymaga uprawnienia podczas użytkowania (np. dostęp do czujnika na ciele, aparatu, mikrofonu lub lokalizacja uprawnienia), nie może utworzyć usługi, gdy aplikacja działa w tle, nawet jeśli aplikacja należy do jednego z wykluczeń z uruchamiania w tle ograniczeń. Wyjaśniono w sekcji Ograniczenia uruchamianie usług działających na pierwszym planie, które wymagają uruchomienia. .

Wykluczenia z ograniczeń uruchamiania w tle

W tych sytuacjach aplikacja może uruchamiać usługi na pierwszym planie nawet wtedy, gdy aplikacja działa w tle:

Ograniczenia dotyczące uruchamiania usług działających na pierwszym planie, które wymagają uprawnień podczas używania

W Androidzie 14 (poziom interfejsu API 34) lub nowszym istnieją szczególne sytuacje, o których należy pamiętać czy uruchamiasz usługę na pierwszym planie, która wymaga uprawnień podczas używania.

Jeśli aplikacja jest kierowana na Androida 14 lub nowszego, system operacyjny sprawdza podczas tworzenia usługi na pierwszym planie, czy aplikacja ma wszystkie odpowiednie uprawnienia dla danego typu usługi. Jeśli na przykład utworzysz usługa na pierwszym planie typu microphone, system sprawdza, czy aplikacja ma obecnie RECORD_AUDIO. uprawnienia. Jeśli nie masz tych uprawnień, system przesyła SecurityException

W przypadku uprawnień podczas używania może to powodować problem. Jeśli Twoja aplikacja ma gdy jest używane, ma je tylko wtedy, gdy znajduje się w na pierwszym planie. Oznacza to, że jeśli aplikacja działa w tle i próbuje utworzyć usługę działającą na pierwszym planie, taką jak kamera, lokalizacja czy mikrofon, aplikacja nie ma obecnie wymaganych uprawnień i zwraca SecurityException

Podobnie, jeśli aplikacja działa w tle i tworzy służba zdrowia, która wymaga uprawnień BODY_SENSORS_BACKGROUND, aplikacja nie ma obecnie tego uprawnienia, a system zgłosi wyjątek. (Nie dotyczy to placówek ochrony zdrowia, które wymagają różnych pozwoleń, np. ACTIVITY_RECOGNITION). Dzwonię PermissionChecker.checkSelfPermission(). nie zapobiega temu problemowi. jeśli Twoja aplikacja ma uprawnienie do używania podczas używania; wywołuje metodę checkSelfPermission(), aby sprawdzić, czy ma to uprawnienie. zwraca wartość PERMISSION_GRANTED, nawet jeśli aplikacja działa w tle. Gdy zwraca wartość PERMISSION_GRANTED, pojawia się komunikat „Twoja aplikacja ma to uprawnienie gdy aplikacja jest używana”.

Dlatego jeśli usługa na pierwszym planie wymaga uprawnień podczas używania, musi wywołać funkcję Context.startForegroundService() lub Context.bindService() podczas w przypadku aplikacji występuje aktywność, chyba że usługa należy do jednej z określonych wykluczeń.

Wykluczenia z ograniczeń dotyczących uprawnień podczas użycia

W niektórych sytuacjach, nawet jeśli usługa na pierwszym planie jest uruchomiona podczas aplikacji biegi w tle, dostęp do lokalizacji informacji z kamery i mikrofonu, gdy aplikacja działa na pierwszym planie („podczas używania”).

W tych samych sytuacjach, jeśli usługa deklaruje typ usługi na pierwszym planie wynosi location i jest uruchamiana przez aplikację, która ma ACCESS_BACKGROUND_LOCATION uprawnień, usługa ma stały dostęp do informacji o lokalizacji, nawet jeśli która działa w tle.

Oto lista sytuacji:

  • Komponent systemu uruchamia usługę.
  • Działanie usługi rozpoczyna się od interakcji z aplikacją widżety.
  • Działanie usługi rozpoczyna się od interakcji z powiadomieniem.
  • Usługa jest uruchamiana jako PendingIntent, który jest wysyłany z inną, widoczną aplikację.
  • Usługa jest uruchamiana przez aplikację, która jest zasadami dotyczącymi urządzeń , który działa w trybie właściciela urządzenia.
  • Usługa jest uruchamiana przez aplikację, która udostępnia interfejs VoiceInteractionService.
  • Usługa jest uruchamiana przez aplikację, która ma START_ACTIVITIES_FROM_BACKGROUND z podwyższonymi uprawnieniami.
Określ, których usług dotyczy Twoja aplikacja

Podczas testowania aplikacji uruchom jej usługi na pierwszym planie. Jeśli uruchomiona usługa ma ograniczony dostęp do lokalizacji, mikrofonu i aparatu, ten komunikat pojawia się w dzienniku Logcat:

Foreground service started from background can not have \
location/camera/microphone access: service SERVICE_NAME