Android Notification显示监听|点击事件|监听删除|同时展示|

显示监听

方法一:通过在通知展示前进行监听

好处:不需要新增权限。
有以下问题:
1、普通的通知栏通知,需要判断“允许通知”是否有开,并且判断对应的“通知类型”是否有开。而且“允许通知”与“通知类型”两个开关是相互独立的,不能只判断“允许通知”。

判断通知的总开关状态
//判断通知的总开关状态
boolean isNotificationsEnabled = NotificationManagerCompat.from(context).areNotificationsEnabled();

通知

判断通知的类型Channel状态
//判断通知的类型Channel状态
boolean isNotificationChannelEnabled;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    NotificationChannel channel = manager.getNotificationChannel(CHANNEL_ID);//对应通知类型的Channel Id
    isNotificationChannelEnabled = channel.getImportance() != NotificationManager.IMPORTANCE_NONE;
} else {
	//因为Android 8之后才有的 Notification Channel,所以小于 Android 8 的我就判断总开关
    isNotificationChannelEnabled = NotificationManagerCompat.from(context).areNotificationsEnabled();
}

在这里插入图片描述
2、锁屏/悬浮通知,这两个通知在部分手机上是有独立开关的,目前并没有这些开关的监听回调,所以该方法将无法监听这两种通知是否真的有展示。

方法二:写一个Service继承NotificationListenerService

好处:可以精确监听,并且提供了很多的方法控制Notification
有以下问题
1、使用NotificationListenerService需要“BIND_NOTIFICATION_LISTENER_SERVICE”权限,因为该权限的级别是“signature”,你需要与系统相同签名的情况才能使用。
2、需要引导用户开启权限,如下是启动的代码逻辑。

private void openNotificationAccess() {
	//跳转页面,让用户开启权限
	startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
}

private boolean checkNotificationListener() {
//判断当前应用是否有“ACTION_NOTIFICATION_LISTENER_SETTINGS”权限
String pkgName = getPackageName();
String flat = Settings.Secure.getString(getContentResolver(), "enabled_notification_listeners");
if (!TextUtils.isEmpty(flat)) {
  final String[] names = flat.split(":");
  for (int i = 0; i < names.length; i++) {
      final ComponentName cn = ComponentName.unflattenFromString(names[i]);
      if (cn != null) {
          if (TextUtils.equals(pkgName, cn.getPackageName())) {
              return true;
          }
      }
  }
}
return false;
}

点击监听

方法一:通过设置通知中Intent的跳转的Activity中加参数

好处:容易操作,自由度高
有以下问题
1、如果是跳转不同的Activity进行后续操作,不好统一控制,建议跳转至中间页进行处理。

方法二:通过这是一个BroadcastReceiver监听

与使用Activity没有什么区别,就一个有界面一个没有界面。

//参考代码
private void showNormlNotification() {
    Intent intent =new Intent(this, NotificationActivity.class); //中转的Activity
    intent.putExtra(NotificationController.NOTIFICATION_TYPE,""); //自己定义的参数,在Activity中接收参数自行处理
    
//    Intent intent = new Intent(context, NotificationBroadcastReceiver.class); //BroadcastReceiver
    PendingIntent contentIntent = PendingIntent.getActivity(this,NORML_NOTIFICAON,intent,PendingIntent.FLAG_MUTABLE);

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            //必须!! 填写小图标
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentTitle("norml notification")
            .setContentText("norml notification content")
            //点击事件触发的PendingIntent
            .setContentIntent(contentIntent)
            //优先级决定,你是以什么形式展示notification
            .setPriority(NotificationCompat.PRIORITY_DEFAULT);

    NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
    mNotificationManager.notify(NORML_NOTIFICAON,builder.build());
}

监听删除

方法一:通过继承NotificationListenerService

同上:显示监听 -> 方法二

方法二:在Notification.Builder中设置 setDeleteIntent

好处:操作方便,使用简单
与点击一样,这里我就用 BroadcastReceiver 来监听

//参考代码
private void showNormlNotification() {
    Intent intent =new Intent(this, NotificationActivity.class); //中转的Activity
    intent.putExtra(NotificationController.NOTIFICATION_TYPE,""); //自己定义的参数,在Activity中接收参数自行处理
    Intent dIntent = new Intent(context, NotificationBroadcastReceiver.class); //BroadcastReceiver
    
    PendingIntent contentIntent = PendingIntent.getActivity(this,NORML_NOTIFICAON,intent,PendingIntent.FLAG_MUTABLE);
    PendingIntent deleteIntent = PendingIntent.getBroadcast(this,NORML_NOTIFICAON,dIntent,PendingIntent.FLAG_MUTABLE);
    
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentTitle("norml notification")
            .setContentText("norml notification content")
            .setContentIntent(contentIntent)
            //手动删除监听
            .setDeleteIntent(deleteIntent)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT);

    NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
    mNotificationManager.notify(NORML_NOTIFICAON,builder.build());
}

同时展示多个通知,点击事件响应异常

原因及处理
PendingIntent contentIntent = 
PendingIntent.getActivity(this,NORML_NOTIFICAON,intent,PendingIntent.FLAG_MUTABLE);

在PendingIntent创建的时候,没有明确设置 第二个参数“ requestCode” 多个不同类型或不同功能模块的Notification使用同一个 requestCode,自主定义 requestCode 区分好即可。

对于创建PendingIntent 最后一个参数"flag",请自行查看官方文档下的这些参数代表的场景。根据不同的场景设置正确的参数。

可选参数如下
PendingIntent.FLAG_UPDATE_CURRENT
PendingIntent.FLAG_CANCEL_CURRENT
PendingIntent.FLAG_NO_CREATE
PendingIntent.FLAG_ONE_SHOT
PendingIntent.FLAG_UPDATE_CURRENT
//最后这两个参数是android 12新加的,而且是必须设置。
PendingIntent.FLAG_IMMUTABLE
PendingIntent.FLAG_MUTABLE

自定义通知样式

Android 7的自定义View设置的方式与之后的版本有差别

Notification.Builder customNotification = createNotificationBuilder();
RemoteViews remoteViews = new RemoteViews(mContext.getPackageName(), R.layout.layout_notifcation_ard11);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
    customNotification.setCustomContentView(remoteViews);
}else {
    customNotification.setContent(remoteViews);
}

在Android 12以前,可以做到“完全自定义”即不受限制随意定义,在Android 12后为了让通知栏通知能方便用户处理,不允许在“完全自定义”必须会有应用icon存在,而且高度也有了限制。
详细的自定义使用流程,以及android 12的变动请查看: 安卓官方文档

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android中,我们可以使用`NotificationCompat`来创建通知,通知可以根据需要展开或收缩。当通知被展开时,我们可以自定义通知的布局,并添加一些交互式组件,例如按钮、文本框等。 为了监听通知的展开和收缩事件,我们需要使用`NotificationCompat`提供的`setCustomBigContentView()`和`setCustomContentView()`方法,分别设置通知展开和收缩时的自定义布局。然后,我们可以在自定义布局中添加相应的交互式组件,并为其添加监听器。 示例代码: ``` // 创建通知的Builder NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setAutoCancel(true); // 创建通知展开时的自定义布局 RemoteViews expandedView = new RemoteViews(getPackageName(), R.layout.notification_expanded); // 添加监听器 expandedView.setOnClickPendingIntent(R.id.button1, pendingIntent1); expandedView.setOnClickPendingIntent(R.id.button2, pendingIntent2); // 设置通知展开时的自定义布局 builder.setCustomBigContentView(expandedView); // 创建通知收缩时的自定义布局 RemoteViews collapsedView = new RemoteViews(getPackageName(), R.layout.notification_collapsed); // 添加监听器 collapsedView.setOnClickPendingIntent(R.id.button, pendingIntent); // 设置通知收缩时的自定义布局 builder.setCustomContentView(collapsedView); // 发送通知 NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(notificationId, builder.build()); ``` 在上面的代码中,我们创建了一个通知的Builder,并设置了通知展开和收缩时的自定义布局。为了监听自定义布局中的按钮点击事件,我们使用`setOnClickPendingIntent()`方法为按钮添加了相应的`PendingIntent`。当用户点击按钮时,相应的`PendingIntent`会被触发。 需要注意的是,在自定义布局中添加的交互式组件的ID必须与布局文件中定义的ID一致。否则,添加的监听器将不会生效。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值