Android - 通知Notification

简介

指 Android 在应用的界面之外显示的消息,旨在向用户提供提醒、来自他人的通信信息或应用中的其他实时信息。用户可以点击通知来打开应用,也可以直接在通知中执行某项操作,比如点击按钮可以切歌,甚至在通知栏上直接回复消息。

显示位置

  1. 状态栏和通知栏
    在状态栏上显示通知图标,在通知栏显示详细内容,用户点击通知栏里面的通知一般会跳转到应用相应页面。
  2. 屏幕上方
    当未锁屏时通知可以显示在屏幕上面,可以伴随着提示音或者震动,提示一会后如果用户没有处理会自动消失
  3. 锁屏显示
    当屏幕锁定时,通知可以显示在锁屏界面上,并且伴随亮屏,用户可根据通知等级控制可显示的通知
  4. 应用图标
    在一些设备上,通知可以显示在应用图标上,一般在右上方显示一个数字代表该应用有多少通知用户未查看,用户可以长按应用图标查看通知列表。

概念

  1. 渠道:从 Android 8.0(API 级别 26)开始,必须为所有通知分配渠道,否则通知将不会显示。用户可以根据渠道接收想要接收的通知
  2. 重要程度: Android 7.1(API 级别 25)及更低版本的设备上,每条通知的重要程度均由通知的 priority 决定;在搭载 Android 8.0(API 级别 26)及更高版本的设备上,通知的重要程度由通知发布到的渠道的 importance 决定。通知的重要程度不同,提示用户的方式就不同,重要度越高提示越明显。
  3. 前台服务的通知:在服务内发送的前台通知,用户无法移除,除非关闭服务或者在服务内部关闭该通知
  4. 勿扰模式:从 Android 5.0(API 级别 21)开始,用户可以启用勿扰模式,来控制被打扰的情况,指定可以打扰的类型。

简单使用

  1. 创建通道
@TargetApi(Build.VERSION_CODES.O)
public static void createNotificationChannel(Context ctx, String channelId, String channelName, String channelDes) {
	NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT);
	channel.setDescription(channelDes);
	channel.setSound(null, null);
	channel.enableLights(true);
	channel.setLightColor(Color.RED);
	channel.setShowBadge(true);
	NotificationManager notifyMgr = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
	notifyMgr.createNotificationChannel(channel);
}
  1. 创建通知
//用户点击通知的意图
Intent intent = new Intent(mContext, MainActivity.class);
//通知中的交互都用延迟意图 PendingIntent
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);

//添加按钮点击意图,在通知里面的按钮点击必须都用过broadcast,在broadcast处理点击事件
Intent btnIntent = new Intent(mContext, MusicReceiver.class);
btnIntent.setAction("com.dean.smartapp.broadcast.music");
btnIntent.putExtra("data", "notification data");
PendingIntent btnPendingIntent = PendingIntent.getBroadcast(mContext, 0, btnIntent, 0);

//使用之前的通道 NotifyUtils.NOTIFY_CHANNEL_MUSIC 创建一个通知,如果较低版本不需要通道,NotificationCompat会自动适配
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, NotifyUtils.NOTIFY_CHANNEL_MUSIC);
builder.setSmallIcon(R.mipmap.ic_launcher)
		.setContentTitle("通知标题")
		.setContentText("这是一条通知的内容")
		//设置通知的展开内容
		.setStyle(new NotificationCompat.BigTextStyle().bigText("这是通知的扩展内容,可以是文本扩展或者其他扩展内容,在通知栏可以直接查看"))
		//设置通知的重要等级以影响通知用户的方式
		.setPriority(NotificationCompat.PRIORITY_DEFAULT)
		//设置用户点击通知后的意图
		.setContentIntent(pendingIntent)
		//用户点击后自动移除
		.setAutoCancel(true)
		//添加按钮,默认最多只能添加三个按钮,而不影响通知本身的正常点击跳转Activity
		.addAction(R.mipmap.ic_launcher, "通知按钮1", btnPendingIntent)
		.addAction(R.mipmap.ic_launcher, "通知按钮2", btnPendingIntent)
		.addAction(R.mipmap.ic_launcher, "通知按钮3", btnPendingIntent);
  1. 显示通知
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(mContext);
notificationManagerCompat.notify(0, builder.build());

在通知栏直接输入文本

在Android 7.0(API 级别 24)允许用户直接在通知中输入文本,然后会直接提交给应用,而不必打开 Activity。比如聊天软件可以在通知栏直接回复(对比了iOS后,哎,效果天壤之别,希望谷歌能够优化吧)

首先创建RemoteInput用来显示输入框,接收用户输入的文字
RemoteInput remoteInput = new RemoteInput.Builder("Key值用来取出用户输入的数据").setLabel("输入框默认文字").build();

使用Broadcast来接收文字
Intent inputIntent = new Intent(mContext, MusicReceiver.class);
inputIntent.setAction("com.dean.smartapp.broadcast.music");
inputIntent.putExtra("data", "notification data");
PendingIntent inputPendingIntent = PendingIntent.getBroadcast(mContext, 0, inputIntent,PendingIntent.FLAG_UPDATE_CURRENT);

创建action
NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.mipmap.ic_launcher, "按钮名称", inputPendingIntent)
		.addRemoteInput(remoteInput).build();

Intent intent = new Intent(mContext, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);

NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, NotifyUtils.NOTIFY_CHANNEL_MUSIC);
builder.setSmallIcon(R.mipmap.ic_launcher)
		.setContentTitle("通知标题")
		.setContentText("这是一条通知的内容")
		.setContentIntent(pendingIntent)
		.setAutoCancel(true)
		//将action添加到通知上
		.addAction(action);
显示通知
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(mContext);
notificationManagerCompat.notify(0, builder.build());


最后在Receiver中接收文字并且处理,如果需要在通知上显示用户新输入的文字,即发送一个新通知
注意发送通知的flag要和之前一样,用来覆盖之前的通知
public class MusicReceiver extends BroadcastReceiver {
    private static final String LOG_TAG = MusicReceiver.class.getSimpleName();
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
        if (remoteInput != null) {
            Log.d(LOG_TAG, "用户通知栏输入 data = " + remoteInput.getCharSequence("a"));
        }
    }
}

自定义视图

可以使用setCustomContentView和setCustomBigContentView来为通知设置自定义视图,在通知中可以通过长按来切换这两种样式

Notification自定义view使用RemoteViews
RemoteViews smallRemoteViews = new RemoteViews(mContext.getPackageName(), R.layout.notification_small_layout);
RemoteViews bigRemoteViews = new RemoteViews(mContext.getPackageName(), R.layout.notification_big_layout);

Notification customNotification = new NotificationCompat.Builder(context, CHANNEL_ID)
		.setSmallIcon(R.drawable.notification_icon)
		.setStyle(new NotificationCompat.DecoratedCustomViewStyle())
		.setCustomContentView(smallRemoteViews )
		.setCustomBigContentView(bigRemoteViews)
		.build();

运行效果
在这里插入图片描述

在这里插入图片描述

添加发送人

在Android P版本以上需要Person来让通知达到最佳呈现,即谁发送了这个通知,它在不支持的设备上无效。

//先创建一个Person
Person person = new Person.Builder()
                .setName("胡汉三")
                .setIcon(IconCompat.createWithResource(mContext, R.mipmap.ic_launcher))
                .build();

//在创建MessaginStyle,如果多人,可以使用setGroupConversation标记为一个组
NotificationCompat.MessagingStyle style = new NotificationCompat.MessagingStyle(person);
            style.addMessage("这是胡汉三发送的通知", System.currentTimeMillis(), person);
            style.setConversationTitle("胡汉三发送通知啦");

将他设置给notification 正常显示通知即可
NotificationCompat.Builder.setStyle(style)

其他功能

  1. 关于渠道,应用应该为一类的通知开启单独的渠道,以便用户可以根据渠道管理来控制应用中的通知
  2. 同一类通知可以添加分组
NotificationCompat.Builder.setGroup(GROUP_KEY_WORK_EMAIL)
为分组添加描述
NotificationCompat.Builder.setStyle(new NotificationCompat.InboxStyle()
                    .addLine("Alex Faarborg  Check this out")
                    .addLine("Jeff Chang    Launch Party")
                    .setBigContentTitle("2 new messages")
                    .setSummaryText("dean"))
NotificationCompat.Builder.setGroupSummary(true)
  1. Builder的setStyle()可以为通知设置许多展开后的样式,比如展开大文本、展开大图,甚至是音乐播放器的一些播控,但是谷歌提供的默认样式不一定适用,这时可用自定义样式来处理
  2. notificationManagerCompat.notify显示通知时可以使用相同的id来覆盖之前的通知,为了避免提示用户的方式多次发生,可以使用setOnlyAlertOnce()来设置只提醒一次。
  3. 移除通知的方式除了用户处理,代码中可通过cancelAll() 来取消所有通知,或者使用setTimeoutAfter() 为通知设置超时,当时间到了自动消失
  4. 可以通过setVisibility()来控制通知在锁屏时的显示内容。取值有三个:
VISIBILITY_PUBLIC 显示通知的完整内容。
VISIBILITY_SECRET 不在锁定屏幕上显示该通知的任何部分。
VISIBILITY_PRIVATE 显示基本信息,例如通知图标和内容标题,但隐藏通知的完整内容
  1. 需要显示进度条时可以使用setProgress
builder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
然后通过ID发送相同的通知来更新进度
如果完成后需要取消进度条,需要设置
.setProgress(0,0,false);
  1. 关于PendingIntent最后一个参数FLAG
FLAG_ONE_SHOT:获取的PendingIntent只能使用一次
FLAG_NO_CREATE:利用FLAG_NO_CREAT获取的PendingIntent,若描述的Intent不存在则返回NULL值
FLAG_CANCEL_CURRENT:如果描述的PendingIntent已经存在,则在产生新的Intent之前会先取消掉当前的
FLAG_UPDATE_CURRENT:能够新new一个 Intent
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值