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
}
我正在使用此代码段来检查通知是否已启用:
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 callgetNotificationChannels()
. After you have theNotificationChannel
, you can use methods such asgetVibrationPattern()
andgetSound()
to find out what settings the user currently has. To find out if a user blocked a notification channel, you can callgetImportance()
. If the notification channel is blocked,getImportance()
returnsIMPORTANCE_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
}