【问题标题】:Android app - detect if app push notification is offAndroid 应用程序 - 检测应用程序推送通知是否关闭
【发布时间】:2016-11-07 00:22:40
【问题描述】:

在我们的 Android 应用(使用 SDK23 编译)中,“推送通知”设置在应用安装后默认为“开启”。但当然用户可以手动将其“关闭”。

2 个问题:

从应用程序内部,使用 Android API,是否有可能(简而言之如何?):

  1. 检查“推送通知”设置的当前状态是什么(打开或关闭)?

  2. 类似于如果 GPS 关闭,我们可以将用户重定向到 GPS 设备设置,如果设置为“关闭”,我们是否也可以将用户重定向到“推送通知设置”,以便用户然后,如果他愿意,可以将其重新“打开”吗?

令我们大吃一惊(也许我们错了?因此我们在这里寻求您的意见/确认)似乎上面的“1”和“2”都不可能???!!

如果我们错了,我们可能会感谢一个简短的“如何,简而言之”来实现这一目标。

感谢您的输入!

【问题讨论】:

  • 如果你指的是一般的通知,有一个new method 来检查应该在latest support library update 中的启用状态,但最后我听说它还没有发布,并且我目前无法检查。
  • 检查this post是否有帮助。这里有人问了一个类似的问题

标签: android push-notification


【解决方案1】:

您可以使用以下命令检查用户是否允许通知您的应用程序:

NotificationManagerCompat.from(context).areNotificationsEnabled()

这个单行代码从 API 级别 19+ 开始工作。但是,从 android O 开始,引入了通知通道。这允许用户从应用程序设置屏幕中仅禁用特定的通知渠道,并禁用来自应用程序的所有通知。使用上面的命令,您只能检查整个应用程序是否允许通知,而不是特定渠道。这意味着,即使上面的命令给出的值为true,您也看不到任何通知

仅当应用程序允许所有通知并且所有现有通知渠道都已启用时,以下代码才会返回true。从 API 级别 19+ 开始工作,包括从 Android O 开始所需的更改:

Java

public boolean areNotificationsEnabled() {
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    if (!manager.areNotificationsEnabled()) {
      return false;
    }
    List<NotificationChannel> channels = manager.getNotificationChannels();
    for (NotificationChannel channel : channels) {
      if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
        return false;
      }
    }
    return true;
  } else {
    return NotificationManagerCompat.from(context).areNotificationsEnabled();
  }
}

科特林

fun areNotificationsEnabled(notificationManager: NotificationManagerCompat) = when {
    notificationManager.areNotificationsEnabled().not() -> false
    Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
        notificationManager.notificationChannels.firstOrNull { channel ->
            channel.importance == NotificationManager.IMPORTANCE_NONE
        } == null
    }
    else -> true
}

【讨论】:

  • 作为 Kotlin 扩展函数:fun NotificationManagerCompat.areNotificationsEnabled() = when { areNotificationsEnabled().not() -> false Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> { notificationChannels. firstOrNull { channel -> channel.importance == NotificationManager.IMPORTANCE_NONE } == null } else -> true }
  • 如果 api 级别 >= 28,请不要忘记检查组是否被禁用。
  • 在>=Android O的块中,代码可以更简单:notificationManager.notificationChannels.none { it.importance == NotificationManager.IMPORTANCE_NONE }
【解决方案2】:

根据文档,第一个是可能的。我没有调查您问题的第二部分(将用户带到通知设置)。

要查看通知的当前状态,您首先必须知道您使用的设备是否低于 Oreo。在 Oreo 下,它就像在 Support Library 的 NoticificationManagerCompat 对象上调用 areNotificationsEnabled() 一样简单(从 24.1.0 版开始可用)。在 Oreo 或更高版本上,您需要通过在 NotificationChannel 对象上调用 getImportance() 来检查每个通知通道。如果通知被禁用,getImportance() 将返回NotificationManager.IMPORTANCE_NONE。如果它返回任何其他内容,则它们已启用。下面是一些可以完成这项工作的代码:

public boolean areNotificationsEnabled(Context context, String channelId) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        if(!TextUtils.isEmpty(channelId)) {
            NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            NotificationChannel channel = manager.getNotificationChannel(channelId);
            return channel.getImportance() != NotificationManager.IMPORTANCE_NONE;
        }
        return false;
    } else {
        return NotificationManagerCompat.from(context).areNotificationsEnabled();
    }
}

希望这会有所帮助!

【讨论】:

  • 我会删除 !TextUtils.isEmpty(channelId) 并检查 `channel != null",因为无效的频道 ID 字符串也可能导致此问题
  • 即使从设置中禁用通知,它总是返回 IMPORTANCE_HIGH
  • @FlorianWalther btw,TextUtils.isEmpty() 检查 null 和 length==0
  • manager.getNotificationChannel(channelId);它返回 NULL
【解决方案3】:

Android O 开始,引入了通知 groupsANDAndroid P 开始,这成为可能禁用整个组。必须考虑到这一点。请参阅下面的代码 sn-p 以及示例解决方案。

fun NotificationManagerCompat.areNotificationsFullyEnabled(): Boolean {
    if (!areNotificationsEnabled()) return false
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        for (notificationChannel in notificationChannels) {
            if (!notificationChannel.isFullyEnabled(this)) return false
        }
    }
    return true
}

@RequiresApi(Build.VERSION_CODES.O)
fun NotificationChannel.isFullyEnabled(notificationManager: NotificationManagerCompat): Boolean {
    if (importance == NotificationManager.IMPORTANCE_NONE) return false
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        if (notificationManager.getNotificationChannelGroup(group)?.isBlocked == true) return false
    }
    return true
}

例如,您可以从片段中调用它:

if (!NotificationManagerCompat.from(requireContext()).areNotificationsFullyEnabled()) {
            //todo notifications DISABLED
        }

【讨论】:

    【解决方案4】:

    您可以通过此命令检查您的系统推送是启用还是禁用。

    NotificationManagerCompat.from(context).areNotificationsEnabled()
    

    【讨论】:

      猜你喜欢
      • 2013-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-17
      • 1970-01-01
      • 1970-01-01
      • 2013-01-06
      相关资源
      最近更新 更多