Разрешение отказа: startForeground требует android.permission.FOREGROUND_SERVICE
В последнее время мы неожиданно увидели несколько следов стека. Почему это может быть? Это происходит, когда приложение пытается перенести аудиокомментарий на передний план с уведомлением о мультимедиа и всем остальным.
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)
Ответы
Ответ 1
Это произойдет, если вы установили targetSdkVersion = 28
(Android 9/Pie) или выше и не заявили об использовании разрешения FOREGROUND_SERVICE
.
Из примечаний по миграции для Android 9:
Приложения, желающие использовать службы переднего плана, теперь должны запросить Сначала разрешение FOREGROUND_SERVICE. Это нормальное разрешение, поэтому система автоматически предоставляет его запрашивающему приложению. Начиная служба переднего плана без разрешения выдает исключение SecurityException.
Решение состоит в том, чтобы просто добавить следующее в AndroidManifest.xml
:
<manifest ...>
...
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
...
<application ...>
...
</manifest>
Ответ 2
Permission Denial: startForeground requires android.permission.FOREGROUND_SERVICE
Приложения, предназначенные для Android 9 (уровень API 28) или выше и использующие службы переднего плана, должны запрашивать FOREGROUND_SERVICE permission
.
Теперь нам нужно добавить разрешение службы Foreground в файл манифеста
- Позволяет обычному приложению использовать
Service.startForeground
ОБРАЗЕЦ
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
FOREGROUND_SERVICE
- это обычное разрешение, поэтому система автоматически предоставляет его запрашивающему приложению.
Проверьте это заметки о миграции Android 9/Pie
Разрешение на обслуживание переднего плана
Приложения, желающие использовать службы переднего плана, теперь должны сначала запросить разрешение FOREGROUND_SERVICE. Это нормальное разрешение, поэтому система автоматически предоставляет его запрашивающему приложению. Запуск службы переднего плана без разрешения вызывает исключение SecurityException.
Также прочитайте startForeground()
- Приложения, ориентированные на API
Build.VERSION_CODES.P
или более поздней версии, должны запрашивать разрешение Manifest.permission.FOREGROUND_SERVICE
для использования этого API.
Ответ 3
Для уровня API 28 или выше требуется разрешение FOREGROUND_SERVICE. В противном случае он не может работать и получил исключение.
Это будет решено добавлением
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
в файле AndroidManifest.xml.
Ответ 4
targetSdkVersion
как минимум 28
будет обязательным с 1 ноября 2019 года для обновления приложений в Play Store. Поэтому вам нужно изменить целевой API, а затем запросить разрешение FOREGROUND_SERVICE
, чтобы избежать сбоя startForeground()
Ответ 5
Если вы включите запрос разрешения
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" android:required="false" />
Это приведет к сбою приложения, даже если вы введете required = "false", если только вы не заставите пользователя принять разрешение, тогда как должно быть приемлемо позволить пользователю отказать ему, а затем запустить службу переднего плана без него (так уведомление будет постоянно отображаться в панели уведомлений, код приведен ниже)
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(SERVICE, "com.yourapp")
.setSmallIcon(android.R.drawable.ic_menu_mylocation).setContentTitle(FORGROUND_NAME);
Notification notification = mBuilder
.setOngoing(true)
.setPriority(Notification.PRIORITY_LOW)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
SERVICE.startForeground(FOREGROUND_ID, notification);
Поэтому в настоящее время лучше всего заставить пользователя принять разрешение или вообще не использовать его и принять, что у вас всегда будет панель уведомлений, показывающая, что ваша служба работает в фоновом режиме. Не совсем то, что вы хотите, но, кажется, в настоящее время это все или ничего.