前台服务通知始终至少显示5秒钟。

6

在测试Android 9上的前台通知时,我注意到了一些非常奇怪的行为。

情况:我有一些前台服务,我不知道它们需要运行多长时间,可能是1秒或整整一分钟。最后,当服务完成时,它会调用stopForeground(true)。在所有Android 8、9和10设备上,这都可以正常工作,即使立即调用stopForeground(true),也总是可靠地删除通知。

问题:测试Fairphone 3时(我希望其他人也在其他设备上遇到了这个问题,因为对我来说,在任何模拟器或其他设备上都没有出现这种情况),stopForeground没有如预期般工作。通知未能立即移除,即使我立刻调用stopForeground,通知仍然会显示至少5秒。这5秒恰好是令人生畏的错误Context.startForegroundService() did not then call Service.startForeground() - still a problem的确切5秒限制。非常奇怪!使用下面的代码很容易重现此问题并检查您的设备是否受到影响。

AndroidManifest.xml中:

<service
    android:name="<your package name>.TestService"
    android:exported="false" />

TestService.java:

package <your package name>;

import android.annotation.TargetApi;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;

import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;

@TargetApi(Build.VERSION_CODES.O)
public class TestService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        showNotification();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        showNotification();
        stopForeground(true);
        return super.onStartCommand(intent, flags, startId);
    }

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

    private void showNotification() {
        String channelId = "TEST";
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (notificationManager.getNotificationChannel(channelId) == null)
            notificationManager.createNotificationChannel(new NotificationChannel(channelId, "TEST NOTIFICATIONS", NotificationManager.IMPORTANCE_DEFAULT));
        startForeground(1, new NotificationCompat.Builder(this, channelId).setContentText("TEST NOTIFICATION").build());
    }
}

最后,只需通过启动服务(例如在按钮点击时)。

是否有其他人遇到了这个问题或者能够用上面的代码重现它?考虑到我正在 Android 9 上进行测试,并且由于 OEM 的不同行为有所不同,我该如何修复或甚至只是调试它?


如果可能的话,请尝试使用IntentService或JobIntentService。 - Amit Goswami
@AmitGoswami 是否使用Service还是IntentService完全取决于使用情况,不在本问题的范围内。本问题旨在提供一个最小可重现示例。我尝试将上面的片段切换到IntentServiceonHandleIntent,但效果都是一样的。 - 0101100101
嗯,你的意思是stopForeground()开始执行,并且在该函数内部阻塞了约5秒钟? - greeble31
@greeble31 实际上在调试时似乎没有阻止执行,但通知只有在那5秒后才被移除。 - 0101100101
因此,您的问题可以简单地重新阐述为“在Fairphone 3上,前台通知始终至少显示5秒钟”。我可以理解您为什么会觉得这种行为奇怪甚至是不可接受的,但同时我认为OEM有权以这种方式处理事情。这样可以防止人们创建偷偷藏在后台的前台服务,只运行几毫秒的时间。您是否考虑过在那些您知道不必执行很长时间的情况下,改用普通的后台服务呢? - greeble31
@greeble31 正确。是的,我考虑过后台服务。对于我最初提供的用例(立即停止启动的服务),你是正确的,使用后台服务很容易。但在我的情况下仍不是一个选项。请看我的更新答案,应该清楚为什么不能使用后台服务。 - 0101100101
2个回答

5

球!感谢您发现了这个问题。我可以想象在Fairphone Android 9上特别是如此,因为当涉及到安全补丁时,他们往往处于前沿,所以他们可能手动包含了该补丁。 - 0101100101
超级混乱的行为,在文档中没有提到(或者是有吗?) - sprajagopal

0

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