【问题标题】:Android Oreo Notifications - check if specific channel enabledAndroid Oreo 通知 - 检查是否启用了特定频道
【发布时间】:2017-10-25 09:33:58
【问题描述】:

我正在使用这个 sn-p 来检查通知是否启用:

NotificationManagerCompat.from(getContext()).areNotificationsEnabled()

然而,如果用户只禁用频道,我无法知道。

有什么想法吗?

【问题讨论】:

    标签: android notifications android-8.0-oreo


    【解决方案1】:

    具有向后兼容性:

    public boolean isNotificationChannelEnabled(Context context, @Nullable 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();
            }
        }
    

    【讨论】:

    • 一个很小的东西,我更喜欢""instead ofStringUtils.EMPTY_STRING
    • String channelId 应该是 @Nullable 而不是 @NonNull ,因为您可能不会将它用于 SDK TextUtils.isEmpty()
    • areNotificationsEnabled 也应该在 Oreo+ 上进行检查,因为可以在禁用整体通知的同时启用频道
    • 像@FlorianWalther 所说的也应该调用areNotificationsEnabled()。像这样return (channel.getImportance() != NotificationManager.IMPORTANCE_NONE) && NotificationManagerCompat.from(context).areNotificationsEnabled();
    • 这不起作用。我已禁用我的应用程序频道,但仍收到IMPORTANCE_DEFAULT
    【解决方案2】:

    查看文档here

    用户可以修改通知渠道的设置,包括 振动和警报声等行为。您可以致电 以下两种方法来发现用户应用到的设置 通知渠道:

    要检索单个通知通道,您可以调用 getNotificationChannel()。检索所有通知渠道 属于您的应用程序,您可以致电getNotificationChannels()。后 你有NotificationChannel,你可以使用诸如 getVibrationPattern()getSound() 找出哪些设置 用户当前拥有。 了解用户是否阻止了通知 频道,您可以拨打getImportance()。如果通知渠道是 被阻止,getImportance() 返回IMPORTANCE_NONE

    【讨论】:

    • 谢谢。正是我需要的
    • 谷歌是否从他们的文档中删除了它?我在任何地方都找不到它。这仍然是判断您的频道是否被禁用的可靠方法吗?
    • IMPORTANCE_NONE 表示(被用户)阻止的注释不在(不再)链接文档中。:-(
    • @Harald 已移至 BLOCK_STATE_CHANGED 通知部分“Intent that is broadcast when a NotificationChannel is blocked (when NotificationChannel#getImportance() is IMPORTANCE_NONE)”developer.android.com/reference/android/app/…
    【解决方案3】:

    使用它来检查整个通知或频道是否被禁用,并将用户带到相应的设置:

    在调用方法中:

    if (!notificationManager.areNotificationsEnabled()) {
            openNotificationSettings();
            return;
        }
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
                isChannelBlocked(CHANNEL_1_ID)) {
            openChannelSettings(CHANNEL_1_ID);
            return;
        }
    

    在你的课堂上:

    private void openNotificationSettings() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
            intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
            startActivity(intent);
        } else {
            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivity(intent);
        }
    }
    
    @RequiresApi(26)
    private boolean isChannelBlocked(String channelId) {
        NotificationManager manager = getSystemService(NotificationManager.class);
        NotificationChannel channel = manager.getNotificationChannel(channelId);
    
        return channel != null &&
                channel.getImportance() == NotificationManager.IMPORTANCE_NONE;
    }
    
    @RequiresApi(26)
    private void openChannelSettings(String channelId) {
        Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
        intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
        intent.putExtra(Settings.EXTRA_CHANNEL_ID, channelId);
        startActivity(intent);
    }
    

    【讨论】:

      【解决方案4】:

      我认为@itzhar 的示例有一个缺陷:当用户在应用程序中完全禁用通知时,我们可能会误报(当频道本身没有被禁用时)。

      更新后的代码(在 Kotlin 中)可能如下所示:

      fun isNotificationAllowed(context: Context): Boolean {
          return if (isOOrLater()) {
              areNotificationsEnabled(context) and isChannelDisabled(context)
          } else {
              areNotificationsEnabled(context)
          }
      }
      
      private fun areNotificationsEnabled(context: Context) =
          NotificationManagerCompat.from(context).areNotificationsEnabled()
      
      @RequiresApi(api = Build.VERSION_CODES.O)
      private fun isChannelDisabled(context: Context): Boolean{
          val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
          val channel = notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID)
          return channel.importance != NotificationManager.IMPORTANCE_NONE
      }
      
      private fun isOOrLater() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
      

      【讨论】:

        【解决方案5】:

        这个方法有帮助:

        public boolean isNotificationChannelDisabled(@NonNull String channelId) {
                if(!channelId.equals(EMPTY)) {
                    NotificationChannel channel = getManager().getNotificationChannel(channelId);
                    return channel.getImportance() == NotificationManager.IMPORTANCE_NONE;
                }
        
                return false;
            }
        
        private NotificationManager getManager(@NonNull Context context) {
                return mManager(android.app.NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            }
        

        【讨论】:

          【解决方案6】:

          这是我的完整代码:

          public static boolean isNotificationChannelEnabled(@NonNull String groupId, @NonNull String... channelIds) {
              boolean appNotificationEnable = NotificationManagerCompat.from(AppContext.getContext()).areNotificationsEnabled();
              if (!appNotificationEnable) {
                  return false;
              }
          
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                  NotificationManager manager = (NotificationManager) AppContext.getContext().getSystemService(Context.NOTIFICATION_SERVICE);
                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                      List<NotificationChannelGroup> groupList = manager.getNotificationChannelGroups();
                      for (NotificationChannelGroup group : groupList) {
                          if (TextUtils.equals(group.getId(), groupId)) {
                              if (group.isBlocked()) {
                                  return false;
                              }
                          }
                      }
                  }
          
                  for (String channelId : channelIds) {
                      NotificationChannel channel = manager.getNotificationChannel(channelId);
                      if (channel != null && channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
                          return false;
                      }
                  }
                  return true;
              }
          
              return false;
          }
          

          【讨论】:

            【解决方案7】:
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        if(NotificationManagerCompat.from(context).areNotificationsEnabled()) {
                            for (String channelId : channelIds) {
                                if (!TextUtils.isEmpty(channelId)) {
                                    NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
                                    if (manager != null) {
                                        NotificationChannel channel = manager.getNotificationChannel(channelId);
                                        if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE)
                                            return false;
                                    }
                                }
                            }
                            return true;
                        }else return false;
                    }else{
                        return NotificationManagerCompat.from(context).areNotificationsEnabled();
                    }
            

            【讨论】:

              【解决方案8】:

              考虑到areNotificationsEnabled(对于 API 级别 >= 26),这只是 Kotlin 中的一个实现。

              @TargetApi(Build.VERSION_CODES.O)
              private fun isNotificationChannelEnabled(channelId: String): Boolean {
                  val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                  return if (manager.areNotificationsEnabled()){
                    val channel = manager.getNotificationChannel(channelId)
                    channel.importance != NotificationManager.IMPORTANCE_NONE
                  } else false
                }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-09-18
                • 2017-02-11
                • 2016-12-01
                相关资源
                最近更新 更多