java 当现有服务已存在时,Context.startForegroundService()未在计划的AlarmClockInfo上调用Service.startForeground()错误

wgeznvg7  于 5个月前  发布在  Java
关注(0)|答案(1)|浏览(42)

TLDR:如果定时alarmClockInfo(PendingIntent)打开服务示例,而应用程序通过context.bindService()在前端使用ACTIVE服务示例.
详细信息:
我的目标是当应用程序在前面时,通知会静默排队.这意味着当一个通知正在被关注时(打开Activity的Action),传入的计划警报会填充Service示例中的队列.并且不会显示任何通知。
我的问题是.与SO中的大多数情况相反,我无法控制服务启动的方式,在这种情况下,通过AlarmManager调度。

@RequiresApi(api = Build.VERSION_CODES.O)
        public static PendingIntent foregroundServicePendingIntent(Context context, int reqCode, Supplier<Intent> intentSupplier) {
            assert Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
            return PendingIntent.getForegroundService(myService,
                    reqCode,
                    intentSupplier.get(),
                    PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
            );
        }

字符串
Intent是基本的东西.使用context + destination构造函数(android.content.Intent#Intent(android.content.Context, java.lang.Class<?>)),以及一个带有info.的bundle,其中MyService.class作为destination。
请注意,PednignIntent正在安排一个从MyService到同一个MyService的定时警报。
(我已经看到了Broadcast mediator选项,但我还不明白如果Broadcaster仍然被迫进入服务顺序事件循环,为什么需要这种间接性)
调度如下:

assert isAtLeastOreo;
                    PendingIntent pendingIntent =
                            PendingIntent.getActivity( // This defines what will get shown when clicking in the clock icon on top of the android status bar.
                                    context,
                                    prefix_code + id,
                                    openAlarmsFragmentIntent,
                                    flag);
                    manager.setAlarmClock(
                            new AlarmManager.AlarmClockInfo(timeMillis, pendingIntent),
                               foregroundServicePendingIntent // variable created via foregroundServicePendingIntent(context, intent)
                    );


由于不再允许“VERSION O(26+)”Trampoline事件,这意味着无论Service在解析trampoline Action之前执行了什么逻辑,现在都需要在创建/到达Activity目的地之后在目的地中解析,因此Activity目的地中的Service示例必须在onCreate()onNewIntent(Intent)中解析Intent的bundle。
这就是可能导致错误的原因...
当服务处理通知时......当应用程序没有出现在前面时,什么也没有发生,一切都很好。多个通知可以处理同一个服务示例,并且不会出现错误......很好。

**案例A:

如果我安排了一个单一的报警.
当单个通知的Action打开“MainActivity”时...
根据通知的要求,此Activity必须获取服务示例,以实现Intent的bundle解析。
我有一个单例,当警报第一次调用服务时,它被分配,当服务调用onDestroy()时,它被清除。
一旦活动被打开,我可以使用该服务来执行更多的警报调度任务。删除,推迟等。
未出现错误。
现在,如果第二个通知在事件发生后到达,则出现错误,无论此警报是在Activity被带到前面后立即出现,还是在5秒或1分钟后出现。

**情况B:

如果MainActivity首先示例化一个Service,也会发生这种情况.通过:

context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);


在这种情况下,服务成为活动的...绑定MainActivity生命周期,此服务也存储在清除onDestroy()的单例中。
以下情况下无错误:
1.随着活动和服务在后台.
1.单个定时报警打开服务示例(MainActivity中的同一示例),构建并显示通知。
1.通知操作打开触发onNewIntent(Intent)的活动示例

  1. Activity使用Service示例继续Intent操作+额外的东西...
    ......完成......没有问题。
    错误发生时间:
    在步骤“3”之后,如果第二个警报调用onStartCommand(Intent intent, int flags, int startId),则应用程序将在5秒后出现ANR错误。
    我无法控制警报如何决定打开服务,因为这是在创建AlarmClockInfo时指定的,所以我不知道我应该如何解决这个问题.
    一个关键的事实是.
xoshrz7s

xoshrz7s1#

当我让通知出现时,错误消失。
这意味着.

本处有义务让通知出现.

这很奇怪,因为它与服务根据文档应该提供的目的不一致,这不一定是显示通知,但它也可能用于执行其他后台任务。
另一个罪魁祸首可能是报警器触发服务激活的方式,这表明它的唯一功能应该是显示通知。
总之,这似乎是一个安全对策......在所有诚实似乎与我罚款。

相关问题