gpt4 book ai didi

android - 禁用通知权限后启动前台服务导致崩溃(Android 13)

转载 作者:行者123 更新时间:2023-12-04 23:44:19 29 4
gpt4 key购买 nike

所以,我一直在试验新的 Android 模拟器(即 Android 13 或 Android Tiramisu,API 33),在应用程序上,我需要前台服务。
该应用的目标 SDK 目前是 33。
由于通知要求,我添加了 android.permission.POST_NOTIFICATIONS到 list 。而且,因为它也是一个运行时权限,所以我是在打开应用程序后询问权限。
如果,用户拒绝该权限,但在使用 startForegroundService 启动前台服务后尝试执行涉及前台服务的任务, 调用 startForeground从我的服务中,我遇到了崩溃:

android.app.RemoteServiceException$CannotPostForegroundServiceNotificationException: Bad notification for startForeground
at android.app.ActivityThread.throwRemoteServiceException(ActivityThread.java:1983)
at android.app.ActivityThread.-$$Nest$mthrowRemoteServiceException(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2242)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7898)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
注意异常名称: CannotPostForegroundServiceNotificationException .显然,系统有效地阻止了我发布前台服务通知。这发生在 startForeground 之后。调用一个有效的通知(直到 API 32,我没有看到 API 32 和 API 33 之间用于构建通知本身的变化,除了 setOngoing(true) 这是我已经在做的事情)。
所以,我检查了我是否可以发布通知,使用 NotificationManager.areNotificationsEnabled() .如果用户按预期拒绝权限,则返回 false。代码现在看起来像这样:
if (mNotificationManager.areNotificationsEnabled())
startForeground(123, mNotificationBuilder.build())
而且,正如预期的那样, startForeground不会被调用。但是,需要执行的任务可能很长(可能大约 2 分钟)并且必须在后台执行,无法在作业中或通过 WorkManager 执行。 ,并且不调用 startForeground ,应用程序会在大约 20 秒后引发异常,并显示以下内容:
android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{ecbbdfb u0 com.example.android/.service.FgService}
at android.app.ActivityThread.generateForegroundServiceDidNotStartInTimeException(ActivityThread.java:2006)
at android.app.ActivityThread.throwRemoteServiceException(ActivityThread.java:1977)
at android.app.ActivityThread.-$$Nest$mthrowRemoteServiceException(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2242)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7898)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Caused by: android.app.StackTrace: Last startServiceCommon() call for this service was made here
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1915)
at android.app.ContextImpl.startForegroundService(ContextImpl.java:1870)
at android.content.ContextWrapper.startForegroundService(ContextWrapper.java:822)
at com.example.android.MainActivity.startTaskWithFgService(MainActivity.kt:30)
at com.example.kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:749)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
我应该注意,如果用户接受通知权限,通知就会正常可见,所以这看起来像是一个权限问题,并且没有观察到崩溃。
编辑:创建的通知 channel 应该发布静默通知。因此,这就是创建通知 channel 的方式(并且在尝试发布通知时也包括在内):
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
withNotificationManager {
if (notificationChannels?.map { it.id }?.contains(SILENT_NOTIF_CHANNEL_ID) == true)
return@withNotificationManager

val channel = NotificationChannel(
SILENT_NOTIF_CHANNEL_ID,
getString(R.string.silent_notif_channel_name),
NotificationManager.IMPORTANCE_MIN).apply {
enableLights(false)
setShowBadge(false)
setSound(null, null)
description = getString(R.string.silent_notif_channel_desc)
vibrationPattern = null
lockscreenVisibility = Notification.VISIBILITY_SECRET
}

createNotificationChannel(channel)
}
}
据我了解,发生了两件事:
  • 我无法使用通知启动前台服务,因为权限被拒绝,
  • 我也无法在没有通知的情况下启动前台服务,因为需要通知。

  • 这两个条件有效地删除了前台服务功能。这对我来说似乎是一个疏忽。
    引用 Android 13 行为更改通知权限 ( link):
    " 应用程序无需请求 POST_NOTIFICATIONS 权限即可启动前台服务。但是,应用程序在启动前台服务时必须包含通知,就像在以前版本的 Android 上一样。 "
    所以,我的问题是:
    如果用户拒绝权限,我应该怎么做才能在没有前台服务的情况下在后台执行长时间任务?
    感谢您阅读这个问题,我感谢任何帮助、回答或讨论。

    最佳答案

    好的,我找到了问题所在。
    显然,这是由于 通知 channel 已创建。到目前为止,根据我的观察,在发布通知之前创建一个 channel 很好,我们没有观察到崩溃/错误。在这种情况下, channel 也是在通知发布之前创建的,也就是在服务启动之后和 startForeground 之前。被称为。
    如果用户事先拒绝该权限,则尝试静默创建通知 channel 会失败,而不会崩溃。然后,在尝试使用 startForeground 发布通知后,它会失败,但会出现问题中发布的异常,并导致无法解决的问题。
    由于我们不希望用户在第一次启动应用程序时拒绝通知权限,因此我将创建通知 channel 任务移至 Application.onCreate()问题就解决了。前台服务工作,它出现在 FGS(前台服务管理器)中。
    尽管据我所知,文档中没有提到这一点。

    关于android - 禁用通知权限后启动前台服务导致崩溃(Android 13),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73067939/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com