Android前台服务通知延迟

4

我在构建应用程序(编译/目标SDK 31,最小SDK 24)时遇到了一个奇怪的问题。我有一个计时器服务,如果应用程序/活动不再处于前台,则需要运行该服务。在我的活动的onPause中,我使用以下方式启动我的服务:

Intent serviceIntent = new Intent(activity, TimerService.class);
startService(serviceIntent);

服务启动很好,当我观察控制台日志时,它正在进行正确的计算以计算剩余时间。

我遇到的问题是,当应用程序首次启动或奇怪的是,如果它处于空闲状态超过5分钟(通常在我使用其他应用程序时在后台处于空闲状态),当我首次启动服务时,第一个通知会延迟15秒以上。由于服务确实在运行,就好像手机忽略了这15秒钟内的所有通知请求,因为出现的第一个通知将在正确的时间开始(例如,如果定时器设置为1分钟,则剩余45秒)。

该服务如下:

    public static final int timerRunningId = 1;

    private Timer timer;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        startForeground(timerRunningId, timerRunningNotification("Timer starting..."));
        super.onCreate();
    }

    @Override
    public int onStartCommand(final Intent intent, int flags, int startId) {
        timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                // timer logic, ignored for brevity but it would be calculate the timestamp needed for method below
                Notification notification = timerRunningNotification("dummyTimestamp");
                updateNotification(displayTime);
            }
        }, 0, 500);
        return START_REDELIVER_INTENT;
    }

    private void updateNotification(Notification notification ) {
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(timerRunningId, notification);
    }

    private Notification timerRunningNotification(String content) {
        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent contentIntent = PendingIntent.getActivity(this,
                65, notificationIntent, PendingIntent.FLAG_IMMUTABLE);
        return new NotificationCompat.Builder(this, Variables.TIMER_RUNNING_CHANNEL) // note i define this in my MainActivity according to the docs
                .setContentTitle("Timer")
                .setContentText(content)
                .setSmallIcon(R.drawable.notification_icon)
                .setSound(null)
                .setContentIntent(contentIntent)
                .setOnlyAlertOnce(true)
                .build();
    }

据我了解,该服务应在onCreate()中启动,并使用id = 1初始化通知,显示“计时器开始”,然后立即由倒计时通知替换,因为updateNotification方法更新到相同的id = 1。

由于此错误仅在应用程序首次启动或空闲一段时间后发生,我很难调试可能出错的地方。错误发生后,我可以完美地使用计时器,一旦服务启动,通知就会正确显示。

有人对正在发生的事情有任何想法吗?我将这个代码写了快两年了,所以可能有更好的方式来启动通知,但从文档中看到,我的updateNotification方法应该是有效的。

我正在测试这个设备运行Android 12,所以我也很好奇它是否只适用于某些设备(我不记得在两年前发布Android 12之前的版本中看到过这个错误)。

1个回答

12
将该方法添加到NotificationCompat.Builder中:
new NotificationCompat.Builder(...)
                .setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)

来自文档

运行Android 12(API级别31)或更高版本的设备为短时前台服务提供了简化的体验。在这些设备上,系统会在显示与前台服务相关联的通知之前等待10秒钟。但也有一些例外情况,一些类型的服务会立即显示通知。

如果一个前台服务具有以下至少一种特征,则系统将立即显示其关联的通知,在运行Android 12或更高版本的设备上也是如此:

  • 该服务与包含操作按钮的通知相关联。
  • 该服务具有mediaPlayback、mediaProjection或phoneCall的foregroundServiceType。
  • 该服务提供了与电话、导航或媒体播放相关的用例,如通知的category属性中定义的那样。
  • 该服务通过在设置通知时将FOREGROUND_SERVICE_IMMEDIATE传递给setForegroundServiceBehavior()来选择退出行为更改。

它对我有用,谢谢您提供的快速解决方案。 - Ali Imran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接