Android版本迭代速度很快,API也是改的很迅速,特别是Notification,很多API版本提供的方法样式都不一样,但是好在Android在appcompat-v7库里面提供了一个NofificationCompat类来处理兼容。在平时开发通知用的比较少,也没有去总结他们,但是现在看到很多app的通知都比较炫酷,自己不熟悉心里有个疙瘩。我们总结一些通知的类型以及使用。
通知分类
我们把通知分为如下这四类:
- 正常视图,经常在状态栏看到的高度为64dp的通知视图;
- 在API16中引入的以Style方式展示的MediaStyle,InboxStyle,BigTexStyle,BigPictureStyle四种风格样式
- 自定义通知通知布局
- 在API21中加入的headsUpContentView
由于国产手机的定制我在自己的小米5Android 7.0系统上面显示通知有一些问题,所以我们下面的分类图以及代码是根据Galaxy_Nexus_API_25的Android模拟器来做的。
普通通知
效果图:
实现代码:
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext());
Notification notification = builder
.setContentTitle("这是普通通知标题")
.setContentText("这是普通通知内容")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher2)
.setLargeIcon(BitmapFactory.decodeResource(
getResources(), R.mipmap.ic_launcher2))
.build();
manager.notify(1, notification);
这类通知是我们平时看到App的最多的通知类型,实现代码页挺简单。
API16以上的四种Style类型通知
在普通通知的基础上面,可以增添这四种Style的类型
MediaStyle
我们通常看到音乐播放器之类的App会显示这个通知类型。
效果图:
注意这个可以收缩的看我们从普通的通知模式到扩展Style的显示样式。
实现代码:
private void typeMedia() {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle("MediaStyle");
builder.setContentText("Song Title");
builder.setSmallIcon(R.mipmap.ic_launcher2);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher2));
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
Intent intent = new Intent(this, ImageActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 1, intent, 0);
builder.setContentIntent(pIntent);
//第一个参数是图标资源id 第二个是图标显示的名称,第三个图标点击要启动的PendingIntent
builder.addAction(R.drawable.ic_skip_previous_white_24dp, "", null);
builder.addAction(R.drawable.ic_stop_white_24dp, "", null);
builder.addAction(R.drawable.ic_play_arrow_white_24dp, "", pIntent);
builder.addAction(R.drawable.ic_skip_next_white_24dp, "", null);
NotificationCompat.MediaStyle style = new NotificationCompat.MediaStyle();
style.setMediaSession(new MediaSessionCompat(this, "MediaSession",
new ComponentName(MainActivity.this, Intent.ACTION_MEDIA_BUTTON), null).getSessionToken());
//CancelButton在5.0以下的机器有效
style.setCancelButtonIntent(pIntent);
style.setShowCancelButton(true);
//设置要现实在通知右方的图标 最多三个
style.setShowActionsInCompactView(2, 3);
builder.setStyle(style);
builder.setShowWhen(false);
Notification notification = builder.build();
manager.notify(TYPE_MEDIA, notification);
}
InboxStyle
收件箱样式,支持展示具有一串消息内容的样式,按行显示,适用于短信,邮件,IM等。
private void typeInboxStyle() {
NotificationCompat.InboxStyle style = new android.support.v4.app.NotificationCompat.InboxStyle();
style.setBigContentTitle("这是InboxStyle的标题");
for (int i = 0; i < 5; i++) {
style.addLine("行" + i);
}
Notification notification = builder
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(
getResources(), R.mipmap.ic_launcher))
.setStyle(style)
.build();
manager.notify(TYPE_INBOX, notification);
}
BigTextStyle
可以显示大段文字内容。
private void typeBigText() {
NotificationCompat.BigTextStyle style = new android.support.v4.app.NotificationCompat.BigTextStyle();
style.bigText("很长的文本很长的文本很长的文本很长的文本" +
"很长的文本很长的文本很长的文本很长的文本" +
"很长的文本很长的文本很长的文本很长的文本");
style.setBigContentTitle("这是很长的标题");
style.setSummaryText("这是很长的末尾");
Notification notification = builder
.setContentTitle("这是通知标题")
.setContentText("这是通知内容")
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(
getResources(), R.mipmap.ic_launcher))
.setStyle(style)
.build();
manager.notify(TYPE_BIG_TEXT, notification);
}
BigPictureStyle
大图样式,除了在通知栏显示标题和内容外,还可以显示一张大图片,最大高度为256dp。
public void bigPictureStyle(){
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
android.support.v4.app.NotificationCompat.BigPictureStyle style = new android.support.v4.app.NotificationCompat.BigPictureStyle();
style.setBigContentTitle("BigPictureTitle");
style.setSummaryText("SummaryText");
style.bigPicture(BitmapFactory.decodeResource(getResources(),R.drawable.big_picture));
builder.setStyle(style);
builder.setAutoCancel(true);
Intent intent = new Intent(this,ImageActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
//设置点击大图后跳转
builder.setContentIntent(pIntent);
Notification notification = builder.build();
manager.notify(TYPE_BIG_PICTURE,notification);
}
自定义通知布局
当以上的通知都无法满足我们的需求的时候我们可以选择RemoteViews来进行自定义通知的布局文件。
private void typeCustom(){
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.statu_view);
builder.setContent(remoteViews);
Intent intent = new Intent(this,ImageActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,1,intent,0);
remoteViews.setOnClickPendingIntent(R.id.reply,pendingIntent);
remoteViews.setTextViewText(R.id.title,"我是自定义标题");
remoteViews.setTextViewText(R.id.content,"我是自定义内容");
Notification notification = builder.build();
manager.notify(TYPE_CUSTOM,notification);
}
上述的设置的View我们发现是一个固定的64dp的高度。如果我们想要一个比这个高的咋办呢,在API16引入了bigContentView它最大支持256dp。
布局文件高度更改,代码稍微改动一下
private void typeCustom(){
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.statu_view);
Notification notification = builder.build();
if(android.os.Build.VERSION.SDK_INT >= 16) {
notification = builder.build();
notification.bigContentView = remoteViews;
}
builder.setContent(remoteViews);
Intent intent = new Intent(this,ImageActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,1,intent,0);
remoteViews.setOnClickPendingIntent(R.id.reply,pendingIntent);
remoteViews.setTextViewText(R.id.title,"我是自定义标题");
remoteViews.setTextViewText(R.id.content,"我是自定义内容");
manager.notify(TYPE_CUSTOM,notification);
}
关于通知布局适配手机通知的背景颜色可以参考这篇文章:查看。其实就是通过获取手机的通知栏显示的颜色来决定我们的布局颜色。
headsUpContentView
这个通知不显示在通知栏而是以横幅的方式显示在应用上方。这个效果在API21上才有效。
private void typeHeadsUpContentView(){
builder.setContentTitle("横幅通知标题");
builder.setContentText("横幅通知内容");
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
Intent intent = new Intent(this,ImageActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
builder.setContentIntent(pIntent);
//这句是重点
builder.setFullScreenIntent(pIntent,true);
builder.setAutoCancel(true);
Notification notification = builder.build();
manager.notify(TYPE_HEAD_UP,notification);
}
开发中使用过的通知
下载通知进度
- 使用NotificationCompat.Builder.setProgress来实现
private void typeProgress() {
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("下载");
builder.setContentText("正在下载");
manager.notify(TYPE_PROGRESS, builder.build());
builder.setProgress(100, 0, false);
//下载以及安装线程模拟
new Thread(new Runnable() {
@Override
public void run() {
float preProgress = 0;
//模拟下载文件的小数点的progress避免1.01,1.02都更新倒置卡死应用。
for (float progress = 0; progress < 100; progress++) {
int currProgress = (int) progress;
if (preProgress < currProgress) {
builder.setContentText(progress + "%");
builder.setProgress(100, (int) progress, false);
//下载进度提示
builder.setContentText("下载" + currProgress + "%");
manager.notify(TYPE_PROGRESS, builder.build());
}
preProgress = progress;
try {
Thread.sleep(50);//演示休眠50毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//下载完成后更改标题以及提示信息
builder.setContentTitle("开始安装");
builder.setContentText("安装中...");
//设置进度为不确定,用于模拟安装
builder.setProgress(0, 0, true);
manager.notify(TYPE_PROGRESS, builder.build());
// manager.cancel(TYPE_PROGRESS);//设置关闭通知栏
}
}).start();
}
- 使用系统提供的DownloadManager来实现
参考查看
参考链接:
基本使用介绍
版本变更以及坑的解决
小图标灰色问题
基础知识以及适配