Odmowa dostępu: startForeground wymaga android.permission.FOREGROUND_SERVICE

195

Ostatnio widzimy nagle kilka następujących śladów stosu. Dlaczego tak może być? Dzieje się tak, gdy aplikacja próbuje przenieść na pierwszy plan usługę komentarza audio z powiadomieniem medialnym i wszystkim innym.

java.lang.SecurityException: Permission Denial: startForeground from pid=1824, uid=10479 requires android.permission.FOREGROUND_SERVICE
    at android.os.Parcel.createException(Parcel.java:1942)
    at android.os.Parcel.readException(Parcel.java:1910)
    at android.os.Parcel.readException(Parcel.java:1860)
    at android.app.IActivityManager$Stub$Proxy.setServiceForeground(IActivityManager.java:5198)
    at android.app.Service.startForeground(Service.java:695)
    at com.example.app.services.AudioService.setUpMediaNotification(AudioService.java:372)
    at com.example.app.services.AudioService.setUpAndStartAudioFeed(AudioService.java:328)
    at com.example.app.services.AudioService.onStartCommand(AudioService.java:228)
    at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3667)
    at android.app.ActivityThread.access$1600(ActivityThread.java:199)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1681)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
 Caused by: android.os.RemoteException: Remote stack trace:
    at com.android.server.am.ActivityManagerService.enforcePermission(ActivityManagerService.java:9186)
    at com.android.server.am.ActiveServices.setServiceForegroundInnerLocked(ActiveServices.java:1189)
    at com.android.server.am.ActiveServices.setServiceForegroundLocked(ActiveServices.java:870)
    at com.android.server.am.ActivityManagerService.setServiceForeground(ActivityManagerService.java:20434)
    at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:976)
Roy Solberg
źródło

Odpowiedzi:

413

Stanie się tak, jeśli ustawiłeś targetSdkVersion = 28(Android 9 / Pie) lub nowszy i nie zadeklarowałeś korzystania z FOREGROUND_SERVICEpozwolenia.

Z notatek o migracji dla Androida 9:

Aplikacje, które chcą korzystać z usług pierwszego planu, muszą najpierw poprosić o pozwolenie FOREGROUND_SERVICE. Jest to normalne pozwolenie, więc system automatycznie przyznaje je żądającej aplikacji. Uruchomienie usługi pierwszego planu bez zgody zgłasza wyjątek SecurityException.

Rozwiązaniem jest po prostu dodać następujące elementy AndroidManifest.xml:

<manifest ...>
     ...
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
     ...
     <application ...>
     ...
</manifest>
Roy Solberg
źródło
8
Czy to oznacza, że ​​jeśli nasz targetSdkVersionma mniej niż 28, nie potrzebujemy żadnego pozwolenia na uruchamianie usług Foreground na urządzeniach z 28?
3
To brzmi jak dziwne rozwiązanie dla mnie, aby obniżyć celSdkVersion
Denny
2
@Sjd Zainstalują się dobrze. To nie tak maxSdkVersion.
Roy Solberg
9
Głosowanie w górę na twoją odpowiedź, ale informacje o wersji nie są usprawiedliwieniem do tworzenia interfejsów API niekompatybilnych wstecz. W takim przypadku Google mógł poprosić użytkownika o wyrażenie zgody lub przynajmniej podpowiedź zamiast bezgłośnego zawieszania aplikacji. Android staje się ostatnio bardzo trudny w utrzymaniu.
Oleg Gryb
2
@miladsalimi Jeśli otworzysz AndroidManifest.xml w Android Studio, możesz zobaczyć „scalony manifest”. Może istnieje zależność, która wstrzykuje dla ciebie to uprawnienie?
Roy Solberg,
43

Odmowa dostępu: startForeground wymaga android.permission.FOREGROUND_SERVICE

Aplikacje kierowane na system Android 9 (poziom API 28) lub wyższy i korzystające z usług pierwszego planu muszą poprosić o FOREGROUND_SERVICE permission.

Więc teraz musimy dodać pozwolenie na serwis Foreground w pliku manifestu

  • Umożliwia korzystanie ze zwykłej aplikacji Service.startForeground

PRÓBA

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

FOREGROUND_SERVICE jest normalnym pozwoleniem, więc system automatycznie przyznaje je żądającej aplikacji.

Sprawdź notatki migracji systemu Android 9 / Pie

  • Zmiana

Pozwolenie na usługi na pierwszym planie

  • Podsumowanie

Aplikacje, które chcą korzystać z usług pierwszego planu, muszą najpierw poprosić o pozwolenie FOREGROUND_SERVICE. Jest to normalne pozwolenie, więc system automatycznie przyznaje je żądającej aplikacji. Uruchomienie usługi pierwszego planu bez zgody zgłasza wyjątek SecurityException.

Przeczytaj także startForeground()

  • Aplikacje kierowane na interfejs API Build.VERSION_CODES.Plub nowszy muszą poprosić o pozwolenie Manifest.permission.FOREGROUND_SERVICE, aby korzystać z tego interfejsu API.
Nilesh Rathod
źródło
Sir, wypróbowałem twoje rozwiązanie, ale nie działa dla mnie na wszystkie urządzenia z Androidem. jak w Oppo F11 Pro działa, ale w aplikacji na telefony Samsung, Nokia i Mi jest zawieszone i dostał ten sam błąd w logu. czy możesz mi powiedzieć, co robię dla naprawić?
Kapil soni
@Kapilsoni `dostał ten sam błąd w logu` jaki otrzymujesz błąd
Nilesh Rathod
dostałem ten błąd „android.app.RemoteServiceException: Złe powiadomienie dla startForeground:”
Kapil soni
8

W przypadku interfejsu API poziomu 28 lub nowszego wymaga pozwolenia FOREGROUND_SERVICE. W przeciwnym razie nie będzie można uruchomić i uzyskał wyjątek.

Zostanie to rozwiązane poprzez dodanie

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

w pliku AndroidManifest.xml.

Zaman
źródło
dodałem, ale nie naprawiłem dla mnie
Kapil soni
@Kapilsoni dla mnie ten sam problem, dodany, ale wciąż ulega awarii z powodu niewystarczającego pozwolenia na API 29, czy udało Ci się go rozwiązać?
ArturM
4

targetSdkVersionPrzynajmniej 28będzie obowiązkowe od 1 listopada 2019 do aktualizacji aplikacji w Sklepie Play. Musisz więc zmienić docelowy interfejs API, a następnie poprosić o pozwolenie, FOREGROUND_SERVICEaby uniknąć awariistartForeground()

Hermano Mclintock
źródło
0

Należy zauważyć, że FOREGROUND_SERVICEnie wymaga to wymogu posiadania uprawnień do wykonywania. dodaj tylko poniżej do Manifestów

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

powyższą linię należy dodać wcześniej <application

Atef Farouk
źródło