I noticed some very strange behavior when testing foreground notifications on Android 9.
Situation: I have some foreground services where I don't know how long they'll need to run for, be it 1 second or a whole minute. Finally, when the service is done, it will call stopForeground(true)
. This used to work fine on all Android 8, 9 and 10 devices, where stopForeground(true)
, even if called immediately, always reliably removed the notification.
Problem: Testing on a Fairphone 3 (and I hope someone else encountered this on some other devices, because for me this is not happening on any emulator or other device), stopForeground
is not working as expected. Instead of immediately removing the notification, the notification always shows for at least 5 seconds, even if I call stopForeground
straight away. These 5 seconds happen to be the exact 5 second limit of the dreaded error Context.startForegroundService() did not then call Service.startForeground() - still a problem. Very peculiar! Reproducing this and checking whether your device is affected is very easy with the code below.
Inside AndroidManifest.xml
:
<service
android:name="<your package name>.TestService"
android:exported="false" />
Class 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());
}
}
Finally, simply start the service (for example on button click) via startForegroundService(new Intent(this, TestService.class));
Has anyone else experienced this issue or is able to reproduce it with the code above? How can I fix or even just debug it, considering I'm testing on Android 9 and the behaviour is different simply because of the OEM?
Latest security patch claims that it's normal behaviour: https://issuetracker.google.com/issues/147792378
However I'm not sure why it's happening already on Android 9.