权限拒绝:startForeground需要android.permission.FOREGROUND_SERVICE

Roy*_*erg 155 android android-service android-permissions

最近我们突然看到了下面的一些堆栈跟踪.为什么会这样?这是应用程序尝试通过媒体通知和所有内容将音频评论服务移动到前台时.

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)
Run Code Online (Sandbox Code Playgroud)

Roy*_*erg 343

这是因为没有正确阅读发行说明而获得的.这在设置targetSdkVersion = 28(Android 9/Pie)时开始发生,并在例如迁移说明中明确说明:

想要使用前台服务的应用程序现在必须首先请求FOREGROUND_SERVICE权限.这是正常权限,因此系统会自动将其授予请求的应用程序.在没有权限的情况下启动前台服务会抛出SecurityException.

因此,解决方案是添加以下内容FOREGROUND_SERVICE:

<manifest ...>
     ...
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
     ...
     <application ...>
     ...
</manifest>
Run Code Online (Sandbox Code Playgroud)

  • 这是否意味着如果我们的`targetSdkVersion`低于28,我们不需要任何权限在运行28的设备中运行Foreground服务? (7认同)
  • 投票赞成您的答案,但发行说明不是构建非向后兼容API的借口。在这种情况下,Google可能会要求用户给予许可或至少提供提示,而不是使应用程序无声崩溃。Android最近变得很难维护。 (6认同)
  • 这听起来像是一个奇怪的解决方案,降低targetSdkVersion (3认同)
  • @Sjd他们会安装就好。它不像是`maxSdkVersion`。 (2认同)
  • @miladsalimi 如果您在 Android Studio 中打开 AndroidManifest.xml,您可以选择查看“合并清单”。也许有一个依赖项为您注入了该权限使用? (2认同)

Nil*_*hod 36

权限拒绝:startForeground需要android.permission.FOREGROUND_SERVICE

针对Android 9(API级别28)或更高级别并使用前台服务的应用必须请求FOREGROUND_SERVICE permission.

所以现在我们需要在清单文件中添加Foreground服务权限

  • 它允许常规应用程序使用 Service.startForeground

样品

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Run Code Online (Sandbox Code Playgroud)

FOREGROUND_SERVICE 是正常权限,因此系统会自动将其授予请求的应用程序.

请查看Android 9/Pie的迁移说明

  • 更改

前台服务许可

  • 摘要

想要使用前台服务的应用程序现在必须首先请求FOREGROUND_SERVICE权限.这是正常权限,因此系统会自动将其授予请求的应用程序.在没有权限的情况下启动前台服务会抛出SecurityException.

还读 startForeground()

  • 针对API Build.VERSION_CODES.P或更高版本的应用必须请求权限Manifest.permission.FOREGROUND_SERVICE才能使用此API.


صلي*_*ouk 14

请注意,FOREGROUND_SERVICE这不需要运行时权限要求。仅将以下添加到清单

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Run Code Online (Sandbox Code Playgroud)

上面的行应该在之前添加 <application


小智 10

对于 API 级别 28 或更高级别,它需要 FOREGROUND_SERVICE 权限。否则,它无法运行并出现异常。

将通过添加解决

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Run Code Online (Sandbox Code Playgroud)

在 AndroidManifest.xml 文件中。

  • 我已经添加但没有为我修复 (2认同)

小智 6

从 2019 年 11 月 1 日起,Play 商店中的应用更新将强制要求targetSdkVersion至少28为A。因此,您需要更改目标 API,然后请求权限FOREGROUND_SERVICE以避免崩溃startForeground()