Notification使用常见问题(坑)

最近在做Notification遇到了挺多问题,查了不少资料,也参考了网上一些博客,对这些问题做了总结

1.动态设置开启或关闭通知声音(震动、铃声等)

Android O 引入了 通知渠道(NotificationChannels),以提供统一的配置来帮助用户管理通知,如果是针对androidO为目标平台时,必须实现一个或者多个通知渠道,以向用户显示通知。

Android O 的用户可以使用一致的系统UI管理大多数与通知有关的设置。所有发布至通知渠道的通知都具有相同的行为。

误区一 调用NotificationChannel.setSound()方法来修改

先看下官方文档的描述

fun setSound(
    sound: Uri!, 
    audioAttributes: AudioAttributes!
): Unit

Sets the sound that should be played for notifications posted to this channel and its audio attributes. Notification channels with an importance of at least NotificationManager#IMPORTANCE_DEFAULT should have a sound. Only modifiable before the channel is submitted to NotificationManager#createNotificationChannel(NotificationChannel).

意思是只能在createNotificationChannel()创建渠道之前修改铃声,在创建之后不支持修改。一旦通知渠道创建了,其设置和行为就不能更改,由用户掌握,只能引导用户进行修改。以下示例代码说明如何通过创建启动 Activity 的 Intent 将用户重定向到通知渠道的设置。

Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_CHANNEL_ID,mChannel.getId());
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());startActivity(intent);

如果不想采用上面的方案,只能重新创建一个新的渠道来设置铃声。对于之前创建的渠道,还需要通过deleteNotificationChannel()去删除。

根据业务需要设置相应的improtance

 NotificationManager.IMPORTANCE_NONE 关闭通知
 NotificationManager.IMPORTANCE_MIN 开启通知,不会弹出,但没有提示音,状态栏中无显示
 NotificationManager.IMPORTANCE_LOW 开启通知,不会弹出,不发出提示音,状态栏中显示
 NotificationManager.IMPORTANCE_DEFAULT 开启通知,不会弹出,发出提示音,状态栏中显示
 NotificationManager.IMPORTANCE_HIGH 开启通知,会弹出,发出提示音,状态栏中显示
误区二 deleteNotificationChannel()
NotificationManager  

open fun deleteNotificationChannel(channelId: String!): Unit

Deletes the given notification channel.
If you create a new channel with this same id, the deleted channel will be un-deleted with all of the same settings it had before it was deleted.

在deleteNotificationChannel()需要注意,官方文档是这么描述的,“如果你新建的channel和要删除的channel是同一个channelId的话。新建的channel的属性会和要删除的那个channel是保持一致”,这意味着如果我们要动态修改通知声音的时候,创建的channelId不能相同,不然还是没有效果。

但是这里又有另外一个坑。你什么时候去删除呢?第一次测试我是在修改铃声或者振动的时候创建一个新的渠道,把之前所有旧的渠道都删除,但是这样会有一个bug,之前渠道上还在状态栏显示的Notification都会删除掉,所有要做一个判断,如果当前渠道在状态栏没有notification显示则删除,否则继续保存,代码如下:

@RequiresApi(Build.VERSION_CODES.O)
private fun deleteNoActiveChannelId(manager: NotificationManager, channelId: String) {
    if (manager.notificationChannels.size == 0) return
    manager.notificationChannels.forEach {
        if (it.id.isNotNullOrEmpty() && it.id != channelId) {
            if (getActivieChannelConunt(manager, it.id) == 0) {
                manager.deleteNotificationChannel(it.id)
            }
        }
    }
}

/**
 * 获取某个渠道下状态栏上通知显示个数
 */
@RequiresApi(Build.VERSION_CODES.O)
private fun getActivieChannelConunt(manager: NotificationManager, itemChannelId: String): Int {
    var count = 0
    manager.activeNotifications.forEach {
        if (it.notification != null && it.notification.channelId == itemChannelId) {
            count++
        }
    }
    return count
}

如果需要通知静音,在创建Channel时,设置重要性Importance NotificationManager.IMPORTANCE_MIN,通知就是静默的状态。而设置NotificationManager.IMPORTANCE_HIGH,就是随系统使用声音或振动。

2.设置点击自动清除和不可滑动删除类型的通知

可以通过设置提醒标志符flag实现
创建通知栏之后通过给他添加.flags属性赋值

Notification notification = mBuilder.build();  
notification.flags = Notification.FLAG_AUTO_CANCEL; 

各标志符介绍

Notification.FLAG_SHOW_LIGHTS              //三色灯提醒,在使用三色灯提醒时候必须加该标志符
Notification.FLAG_ONGOING_EVENT          //发起正在运行事件(活动中)
Notification.FLAG_INSISTENT             //让声音、振动无限循环,直到用户响应 (取消或者打开)
Notification.FLAG_ONLY_ALERT_ONCE      //发起Notification后,铃声和震动均只执行一次
Notification.FLAG_AUTO_CANCEL          //用户单击通知后自动消失
Notification.FLAG_NO_CLEAR              //只有代码调用全部清除时,Notification才会清除 
Notification.FLAG_FOREGROUND_SERVICE    //表示正在运行的服务
  • 设置flag的时候要把notification.flags 原先的配置带上
    setOnlyAlertOnce(true)时 相当于配置了Notification.FLAG_ONLY_ALERT_ONCE
    setAutoCancel(true) 相当于配置了 Notification.FLAG_AUTO_CANCEL

    所以配置的时候需要注意写法:
    notification.flag = notification.flag or Notification.FLAG_XXXX_XXXX

  • 如果是简单的点击自动清除,可以直接通过
    Notification.FLAG_AUTO_CANCEL 或者 setAutoCancel(true)

  • 如果是需要在下拉通知栏常驻(点击全部清除按钮、右滑都不会清除该通知)
    Notification.FLAG_AUTO_CANCEL or Notification.FLAG_NO_CLEAR

注意点

  • 如果是采用自定义RemoteView样式发送通知,自己设置了点击处理intent,那么设置autoCancel标志位就会失效,这种情况下想要取消通知,只能调用系统方法主动取消。
// 在这里设置点击事件,点击后不会消失,可以根据需求来选择
remoteView.setOnClickPendingIntent(R.id.ll_newpush_root,contentIntent);

如果想让上面设置的flag生效,此时务必使用以下方式来指定notification的点击事件:

 notification.contentIntent = pendingIntent

不能把pendingIntent设置在RemoteViews中

3.取消Notification的方式

  1. 点击通知栏的清除按钮,会清除所有可清除的通知
  2. 设置了 setAutoCancel() 或 FLAG_AUTO_CANCEL 的通知,点击该通知时会清除它
  3. 通过 NotificationManager 调用 cancel(int id) 方法清除指定 ID 的通知
  4. 通过 NotificationManager 调用 cancel(String tag, int id) 方法清除指定 TAG 和 ID 的通知
  5. 通过 NotificationManager 调用 cancelAll() 方法清除所有该应用之前发送的通知如果你是通过 NotificationManager.notify(String tag, int id, Notification notify) 方法创建的通知,那么只能通过 NotificationManager.cancel(String tag, int id)方法才能清除对应的通知,调用NotificationManager.cancel(int id) 无效。
  6. 在NotificationServiceListener中调用cancelNotification(String key)清除对应通知
  7. 如果在使用创建通知时设置超时 setTimeoutAfter(),系统会在指定的持续时间过后取消通知。如果需要,您可以在指定的超时持续时间过去之前取消通知
  8. 如果RemoteView里面有按钮设置了点击事件,点击按钮无法触发通知的setAutoCancel(),即点击后通知不会自动消失
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
NotificationAndroid 操作系统中的一个重要组件,可用于向用户发送各种提示信息。在 Android 应用程序中使用 Notification 的步骤如下: 1. 创建 Notification 对象 你可以通过 Notification.Builder 或者 NotificationCompat.Builder 对象来创建 Notification 对象,设置通知的标题、内容、图标等参数。 2. 发送 Notification 使用 NotificationManager 对象的 notify() 方法来发送 Notification。 3. 处理 Notification 的点击事件 如果用户点击了 Notification,你可以通过 PendingIntent 对象来启动一个 Activity 或者执行一个操作。 以下是一个简单的示例代码,用于创建和发送一个 Notification: ```java // 创建 Notification.Builder 对象 Notification.Builder builder = new Notification.Builder(this); builder.setContentTitle("标题"); builder.setContentText("内容"); builder.setSmallIcon(R.drawable.icon); // 发送 Notification NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(0, builder.build()); // 处理 Notification 的点击事件 Intent intent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); builder.setContentIntent(pendingIntent); ``` 这样就可以发送一个简单的 Notification,并且处理用户的点击事件。需要注意的是,为了让应用程序发送 Notification,你需要在 AndroidManifest.xml 文件中添加相应的权限:`<uses-permission android:name="android.permission.VIBRATE" />` 和 `<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />`。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值