某些应用如何阻止/替换抬头通知?

时间:2016-09-25 10:28:07

标签: android notifications heads-up-notifications

背景

自Android上出现单挑通知以来,一些人喜欢它的快速处理,但有些人讨厌在应用程序(尤其是游戏)上展示。

为了显示单挑通知,开发人员可以使用类似的东西:

    final NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
            .setContentTitle("aa").setContentText("bb").setTicker("cc")
            .setColor(0xffff0000).setSmallIcon(R.mipmap.ic_launcher)
            .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
            .setPriority(Notification.PRIORITY_HIGH);
    if (Build.VERSION.SDK_INT >= 21)
        builder.setVibrate(new long[0]);
    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(1, builder.build());

正因为如此,一些应用程序提出了显示以某种方式替换它们的滚动条文本通知的想法,就像在单挑通知之前一样:

https://play.google.com/store/apps/details?id=com.jamworks.noheadsup&hl=en

有各种可能有用的情况。例如,对于使用全屏的游戏,它可能是有用的。这是因为如果用户要按顶部区域并显示抬头通知,我们希望避免意外点击此通知。

问题

我不仅无法找到人们如何做到的方式,而且似乎它不再适用于新版本的Android(在Android 7上测试过)。

我发现阻止通知的唯一应用是: https://play.google.com/store/apps/details?id=com.aboutmycode.NotificationsOff&hl=en

但它并没有将抬头通知转换为"正常"那些。相反,它只是阻止它们。此外,它需要root,并且似乎只是将通知的设置更改为"被阻止" 。

问题

是否可以临时阻止抬头通知(并将其转换为没有抬头通知的那些)?如果是这样,怎么样?

它有哪些限制?没有root可以工作吗?如果它可以用root,怎么样? " NotificationsOff"工作?

也许以前这种能力是可能的,但现在不是吗?

1 个答案:

答案 0 :(得分:6)

在Android 18+上有一个NotificationListenerService。显示新通知时会通知此服务。然后,我知道有三种方法可以采取行动:

  • 拦截通知,以便不显示(不完全确定可以这样做)选中:如果NotificationListenerService没有调用{{1}收到通知时,也会显示通知。所以这种方法似乎不起作用。
  • 在发布时清除通知。为此,您可以使用NotificationManager来清除给定的通知或clearAllNotifications 已检查:它部分用于清除通知,但您仍然会看到通知显示,然后它不在通知区域(它的奇怪效果)。
  • 在API 21+ Lollipop中,您似乎可以覆盖super.xxx。此方法可以返回NotificationListenerService#getCurrentInterruptionFilter()(或任何其他常量),(尚未经过测试,应该验证)。已检查:NotificationListenerService#INTERRUPTION_FILTER_NONE是最终的,因此无法覆盖
  • 在API 23+中,您可以同时使用NotificationManager#setNotificationPolicy()NotificationManager#setInterruptionFilter()(按特定顺序)来控制向用户显示哪些通知。这些API的Permissions are required请注意,此方法似乎方便了访问功能,但跳过实现完整的NotificationListenerService#getCurrentInterruptionFilter() 这是唯一能以令人满意的方式运作的选项

关于NotificationListenerService,您可以在GitHub kpbird/NotificationListenerService-Example和此post中看到以下示例。

关于NotificationManager,请参阅this post in StackOverflow (specially interesting the highlighted comment)和此post中的其他信息。

示例,测试和其他说明

我已经使用基于kpbird的示例上传了以下repository to GitHub,以测试所有假设并提供最终结论。

请注意,必须遵循应用程序的following steps to enable the permission才能访问通知,以便应用程序正常运行。这个答案还提供了一种在正确的部分打开系统设置的方法。

此外,为了完整性,following answer提供了一种检查权限是否已被授予的方法。

补充说明:显然,Marshmallow的第一个版本有一个NotificationListenerService不起作用的错误。请参阅herehere