【发布时间】:2019-12-30 05:47:36
【问题描述】:
在 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());
}
}
最后,只需通过startForegroundService(new Intent(this, TestService.class)); 启动服务(例如单击按钮)
有没有其他人遇到过这个问题或者能够使用上面的代码重现它?考虑到我在 Android 9 上进行测试并且行为仅因 OEM 而不同,我该如何修复甚至只是调试它?
【问题讨论】:
-
尽可能使用 IntentService 或 JobIntentService
-
@AmitGoswami 是否使用
Service或IntentService完全取决于一个人的用例,不在此问题的范围内,该问题旨在提供Minimal, Reproducible Example。我尝试将上面的sn-p切换为IntentService和onHandleIntent,但效果都一样。 -
嗯,所以你是说
stopForeground()开始执行,并在该函数内阻塞约 5 秒? -
@greeble31 实际上在调试时似乎没有阻止执行,但仅在 5 秒后才删除通知。
-
因此您的问题可以简单地重述为“Fairphone 3 上的前台通知始终显示至少 5 秒”。我可以理解为什么你会觉得这种行为很奇怪甚至令人反感,但同时我认为 OEM 有权以这种方式做事。通过一次只运行几毫秒来阻止人们创建“隐藏”在后台的偷偷摸摸的前台服务。您是否考虑过使用常规的旧后台服务来代替您知道不需要执行很长时间的情况?
标签: android service foreground-service