Android Oreo 通知 - 检查特定频道是否已启用

Android Oreo Notifications - check if specific channel enabled

我正在使用此代码段来检查通知是否已启用:

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

但是,如果用户只禁用频道,我就不知道了。

有什么想法吗?

查看文档 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.

此方法可以提供帮助:

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

具有向后兼容性:

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 的例子有一个缺陷:当用户在应用程序中完全禁用通知时,我们可能会得到误报(当​​频道本身没有被禁用时)。

更新后的代码(在 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

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

在调用方法中:

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

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

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

这是我的完整代码:

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

考虑到 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
  }