升级targetSdkVersion至33后ForegroundServiceStartNotAllowedException崩溃求助
解决targetSdkVersion升级到33后ForegroundServiceStartNotAllowedException崩溃问题
问题原因
Android 13(API 33)严格限制了后台启动前台服务的场景,当应用处于后台状态时调用startForeground()会抛出ForegroundServiceStartNotAllowedException,而你当前使用的ExoPlayer 2.18.1的PlayerNotificationManager回调逻辑未适配该限制,导致崩溃。
解决方案
1. 添加并请求前台通知权限
API 33起,前台服务依赖POST_NOTIFICATIONS权限,需先在Manifest中声明:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
在播放启动前或应用初始化阶段动态请求权限:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1001) } }
2. 避免后台触发startForeground()
修改onNotificationPosted方法,先判断应用是否处于前台,仅在前台时启动前台服务:
override fun onNotificationPosted( notificationId: Int, notification: Notification, ongoing: Boolean ) { if (ongoing && !isForegroundService) { playerNotification = notification try { if (isAppInForeground()) { startForeground(notificationId, notification) isForegroundService = true } else { // 后台场景下暂停播放,避免触发前台服务限制 player?.pause() } } catch (e: ForegroundServiceStartNotAllowedException) { // 捕获异常防止崩溃,做降级处理 isForegroundService = false player?.pause() } } else if (!ongoing) { stopForeground(true) isForegroundService = false } } // 判断应用是否处于前台的工具方法 private fun isAppInForeground(): Boolean { val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager return activityManager.runningAppProcesses?.any { it.processName == packageName && it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND } ?: false }
3. 升级ExoPlayer版本
ExoPlayer 2.18.1对Android 13的适配不够完善,官方在后续版本(2.19+)中修复了前台服务启动的适配问题,建议升级到最新稳定版,直接使用适配后的PlayerNotificationManager逻辑。
4. 优化服务生命周期逻辑
确保音乐服务的启动与绑定操作尽可能在前台触发,比如用户点击播放按钮时(此时应用处于前台)再初始化PlayerNotificationManager,避免后台触发前台服务启动。
内容的提问来源于stack exchange,提问作者ZomboY
相关产品推荐
相关产品推荐

