Android前台服务通知不持久化

6
我创建了一个继承自Service并作为前台服务运行的类。我希望我的服务通知是持久的(即不会被刷掉)。然而,我的通知可以通过滑动来取消。
Service文档说明:…前台服务必须为状态栏提供通知,该通知位于“正在进行”标题下。这意味着,除非服务停止或从前台移除,否则不能取消通知…
我设置了断点以检查是否命中了onDestroy()或stopSelf(),但实际情况并非如此。服务正在前台模式下运行,但我仍然可以通过滑动来取消通知。
我发现有很多关于相反情况的问题,即在服务停止后无法取消通知,但没有找到任何类似于我的问题的问题。
该服务通过Intent启动,并按以下方式初始化:
@Override
public void onCreate()
{
    super.onCreate();

    initialize();
}

private void initialize()
{
    Notification n = get_service_notification();
    startForeground(10, n);

    LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter(BroadcastCodes.service_broadcast_intent_name));
}

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
    startServing();
    return START_STICKY;
}

startServing() 订阅位置更新

通知是这样构建的

private Notification get_service_notification()
{
    Intent intent = new Intent(this, LoginActivity.class);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    NotificationCompat.Builder b = new NotificationCompat.Builder(this);

    b.setAutoCancel(false)
            .setWhen(System.currentTimeMillis())
            .setSmallIcon(R.drawable.app_icon)
            .setTicker("some text")
            .setContentTitle("some text")
            .setContentText("some text")
            .setContentIntent(contentIntent)
            .setContentInfo("")
            .setOngoing(true);

    Notification res = b.build();
    res.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;

    return res;
}

我尝试过更改标志和设置setOngoing/setAutoCancel,但结果仍然相同。

SDK版本配置为minSdkVersion 18,targetSdkVersion 25

我非常感谢关于这个问题的任何输入 - 这可能只是一些愚蠢的错误,但我已经花了几个小时试图自己研究...但不幸的是没有任何进展。

编辑1

我仍然没有解决问题。我决定尝试肮脏的hack,但还是没有运气。

我创建了一个PendingIntent,并通过setDeleteIntent()注册它,想法是在通过滑动解除此通知后显示新通知。不幸的是,我无法使其工作(当滑动时意图从未触发)。

我还想澄清,该通知可以被划掉,但不会受到通知面板中的全部清除按钮(垃圾桶图标)的影响。

编辑2

如上所述,我无法使用setDeleteIntent()重新创建我的通知,当它通过滑动取消时。

现在,我采取了一个解决方法 - 我的服务执行一些周期性任务。 我现在正在调用

notificationManager.notify(10, service_notification);

当我的任务运行时,即使被滑动掉,我的通知也会在一段时间后重新创建。
我仍然强烈感觉自己可能误读了文档,因为在我的测试设备(荣耀API23)上有几个通知是无法被滑动掉的。
编辑3:
我在另一台设备(联想API23)上尝试了相同的代码,通知按预期工作(无法解除和滑动)。我的问题似乎是特定于设备的。

@lelloman 我有一个启动活动,在其中使用Intent调用此方法: private void start_service() { // use this to start and trigger a service Intent i= new Intent(this, BackgroundService_Smart.class); getApplicationContext().startService(i); } 其中BackgroundService_Smart是我的前台服务。对于格式问题,抱歉我无法解决。 - Kotuc
为什么要使用这个(我猜是指活动)来创建Intent,然后在应用程序上下文中调用startService()? - lelloman
该活动是一个登录表单(用户输入凭据)。它启动服务,打开到服务器的TCP/IP连接以进行持续数据交换。至于背景,我对Android相当新,并从一些示例中获得了这个(抱歉,无法链接因为那是一段时间以前)。有没有更好的方法来启动服务?我不想使用绑定,因为我需要服务一直运行,直到用户明确停止它(再次使用来自活动的意图)。 - Kotuc
你可以在活动中调用startService(),不过你的问题很奇怪,你的代码看起来没问题。你尝试使用模拟器了吗?在那里是否有同样的问题? - lelloman
无法使仿真器工作,但借了一个联想电脑(也是API23),通知按预期工作。所以猜测这是通知的厂商特定实现? - Kotuc
显示剩余4条评论
1个回答

0

我进行了一些进一步的测试(除了更新中提到的)。我尝试运行来自互联网各地的各种示例/教程,例如this page here

在Honor上最初运行我的测试时,通知总是可以被滑动,而在Lenovo和其他设备上,“正在进行”标志按照文档中所述工作,即无法通过滑动操作解除。

总之,我的问题似乎真的是与设备有关。


同样的事情也发生在我身上。荣耀设备允许通知滑动消失,其中包括: notification.flags |= Notification.FLAG_NO_CLEAR; notification.flags |= Notification.FLAG_ONGOING_EVENT; notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; 我也尝试了 setOngoing(true) 等方法...使用 Flutter 框架,但前台服务是一个插件。荣耀 API 28。 - Şükriye

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