Android 应用程序 - 检测应用程序推送通知是否关闭

use*_*897 19 android push-notification

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

2 问题:

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

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

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

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

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

感谢您的输入!

ljt*_*mev 54

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

NotificationManagerCompat.from(context).areNotificationsEnabled()
Run Code Online (Sandbox Code Playgroud)

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

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

爪哇

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();
  }
}
Run Code Online (Sandbox Code Playgroud)

科特林

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
}
Run Code Online (Sandbox Code Playgroud)

  • 在 &gt;=Android O 的块中,代码可以更简单:`notificationManager.notificationChannels.none { it.importance == notificationManager.IMPORTANCE_NONE }` (3认同)

小智 11

从Android O开始,引入了通知组,Android 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
}
Run Code Online (Sandbox Code Playgroud)

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

if (!NotificationManagerCompat.from(requireContext()).areNotificationsFullyEnabled()) {
            //todo notifications DISABLED
        }
Run Code Online (Sandbox Code Playgroud)


小智 6

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

要检查通知的当前状态,您首先必须知道您所在的设备是否低于 Oreo。在 Oreo 下,它就像调用areNotificationsEnabled()支持库的NoticificationManagerCompat对象(从版本 24.1.0 开始可用)一样简单。在奥利奥或以上,你需要通过调用每个通知通道,检查getImportance()一个上NotificationChannel对象。如果通知被禁用,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();
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!