Уведомления Android Oreo - проверьте, включен ли определенный канал

Im, используя этот фрагмент, чтобы проверить, включены ли уведомления:

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

однако, если пользователь отключает только канал, я не могу знать об этом.

Любая идея? введите описание изображения здесь

Ответ 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();
        }
    }

Ответ 2

Проверьте документы здесь.

Пользователи могут изменять параметры каналов уведомлений, в том числе такие поведения, как вибрация и звук оповещения. Вы можете вызвать следующие два метода, чтобы узнать настройки, которые пользователь применил к каналу уведомлений:

Чтобы получить один канал уведомлений, вы можете вызвать getNotificationChannel(). Чтобы получить все каналы уведомлений, принадлежащие вашему приложению, вы можете вызвать getNotificationChannels(). После того как у вас есть NotificationChannel, вы можете использовать такие методы, как getVibrationPattern() и getSound() чтобы выяснить, какие настройки в данный момент имеет пользователь. Чтобы узнать, заблокировал ли пользователь канал уведомлений, вы можете вызвать getImportance(). Если канал уведомления блокируется, getImportance() возвращает IMPORTANCE_NONE.

Ответ 3

Этот метод может помочь:

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);
    }

Ответ 4

Я думаю, что пример by @itzhar имеет один недостаток: когда пользователь полностью отключил уведомления в приложении, мы можем получить ложный положительный результат (когда сам канал не был отключен).

Обновленный код (в Котлине) может выглядеть так:

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

Используйте это, чтобы проверить, отключены ли уведомления в целом или каналы, и привести пользователя к соответствующим настройкам:

В вызывающем методе:

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);
}

Ответ 6

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();
        }