40

I'm using the following call to check whether notifications are enabled:

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

However, if a user disables only the channel, I cannot know about it.

How do I check whether a specific notification channel is enabled?

Screenshot of Notifications screen in Settings

Adil Hussain
  • 30,049
  • 21
  • 112
  • 147
itzhar
  • 12,743
  • 6
  • 56
  • 63

8 Answers8

65

with backwards compatibility:

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();
        }
    }
itzhar
  • 12,743
  • 6
  • 56
  • 63
  • 1
    A very minor thing, I prefer `""` [instead of](https://stackoverflow.com/questions/4095501/is-stringutils-empty-recommended) `StringUtils.EMPTY_STRING` – g2server Nov 16 '17 at 08:42
  • 1
    `String channelId` should be `@Nullable` instead of `@NonNull` given that you might not use it for SDK < Oreo... Nullable works fine with `TextUtils.isEmpty()` as well – Hugo Allexis Cardona May 16 '18 at 14:35
  • Instead of an empty string I would check for `channel != null`, because this could also be caused by a not empty but invalid channel id – Florian Walther Sep 09 '18 at 09:17
  • 18
    `areNotificationsEnabled` should also be checked on Oreo+, because a channel could be enabled while the overall notifications are disabled – Florian Walther Sep 09 '18 at 11:12
  • 4
    like @FlorianWalther said should also call areNotificationsEnabled(). like this `return (channel.getImportance() != NotificationManager.IMPORTANCE_NONE) && NotificationManagerCompat.from(context).areNotificationsEnabled();` – nommer Oct 15 '18 at 21:53
  • 3
    This is not working. I have disabled my app's channel and still receiving `IMPORTANCE_DEFAULT` – LMaker Feb 08 '19 at 13:16
  • Is there perhaps a callback/listener for when the settings change of specific/all notification groups ? Maybe also the new notification permission? – android developer Sep 02 '22 at 18:26
33

Check out the docs here.

Users can modify the settings for notification channels, including behaviors such as vibration and alert sound. You can call the following two methods to discover the settings a user has applied to a notification channel:

To retrieve a single notification channel, you can call getNotificationChannel(). To retrieve all notification channels belonging to your app, you can call getNotificationChannels(). After you have the NotificationChannel, you can use methods such as getVibrationPattern() and getSound() to find out what settings the user currently has. To find out if a user blocked a notification channel, you can call getImportance(). If the notification channel is blocked, getImportance() returns IMPORTANCE_NONE.

ditn
  • 1,386
  • 1
  • 10
  • 23
  • thansk. exacly what i need – itzhar Oct 25 '17 at 14:12
  • 1
    Did Google remove that from their documentation? I can't find it anywhere. Is this still a reliable way to tell if your channel is disabled? – Francois Dermu May 30 '18 at 20:08
  • 1
    Seems to have moved https://developer.android.com/reference/android/app/NotificationChannel#getImportance() – ditn May 31 '18 at 11:01
  • 1
    The note that `IMPORTANCE_NONE` means blocked (by the user) is not (anymore) in the linked docs.:-( – Harald Mar 04 '20 at 07:56
  • 1
    @Harald It has been moved to the section on the BLOCK_STATE_CHANGED notification "Intent that is broadcast when a NotificationChannel is blocked (when `NotificationChannel#getImportance()` is `IMPORTANCE_NONE`)" https://developer.android.com/reference/android/app/NotificationManager#ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED – Shankari Oct 28 '21 at 17:05
12

Use this to check if either the notifications overall or the channels are disabled and bring the user to the corresponding settings:

In the calling method:

if (!notificationManager.areNotificationsEnabled()) {
        openNotificationSettings();
        return;
    }

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

In your class:

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);
}
Florian Walther
  • 6,237
  • 5
  • 46
  • 104
4

I think example by @itzhar have one flaw: when user completely disabled notifications in app, we can get false positive (when channel itself wasn't disabled).

Updated code (in Kotlin) can look like:

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
thorin86
  • 604
  • 11
  • 26
3

This method can help :

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);
    }
shailesh mota
  • 309
  • 2
  • 7
2

Here is my full code:

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;
}
thomasgalliker
  • 1,279
  • 13
  • 19
thirtyyuan
  • 603
  • 2
  • 8
  • 13
0
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();
        }
Max Droid
  • 924
  • 9
  • 10
0

Just an implementation in Kotlin taking into account areNotificationsEnabled (For API level >= 26).

@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
  }
kike
  • 4,255
  • 5
  • 23
  • 41