1. 创建notification
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.id.icon)
.setContentTitle("标题")
.setContentText("详细文本");
通过Builder模式创建Notification.Builder实例,有了builder对象,可以给它添加各种属性,例如标题,内容,图标等
2. 定义Action
给点击Notification后要执行的操作增加一个Intent,由于这个Intent不是马上就执行的,而是有用户触发的,所以Android给这样的Intent提供了一个延迟意图PendingIntent来帮助我们完成这样的操作
PendingIntent的使用非常简单,只需要在Intent的基础上包装一层就可以了,代码如下所示
Intent resultIntent = new Intent(this, ResultActivity.class);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
这样当点击Notification后,就会触发PendingIntent事件,跳转到指定的Activity
3. 设置点击事件
builder.setContentIntent(resultPendingIntent);
注意事项:当点击通知跳转到Activity的时候,Activity会重新走生命周期,想要保持原来的状态,需要给Activity配置一个launchMode = “singleTask”
4. 发送通知
通过NotificationManager通知管理器的notify()方法来发送Notification,并给Notification一个id值,这个id会在更新Notification的时候用到
NotificationManager mNotifyMgr =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
int mNotificationId = 001;
mNotifyMgr.notify(mNotificationId, builder.build());
5. 使用BigView样式
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_stat_notification)
.setContentTitle(getString(R.string.notification))
.setContentText(getString(R.string.ping))
.setDefaults(Notification.DEFAULT_ALL)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.addAction (R.drawable.ic_stat_dismiss,
getString(R.string.dismiss), piDismiss)
.addAction (R.drawable.ic_stat_snooze,
getString(R.string.snooze), piSnooze);
6. 显示Notification进度
int id = 1;
...
NotificationManager mNotifyManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder mBuilder = new Notification.Builder(this);
mBuilder.setContentTitle("Picture Download")
.setContentText("Download in progress")
.setSmallIcon(R.drawable.ic_notification);
new Thread(new Runnable() {
@Override
public void run() {
int i;
for (i = 0; i <= 100; i+=5) {
mBuilder.setProgress(100, i, false);
mNotifyManager.notify(id, mBuilder.build());
Thread.sleep(5*1000);
}
mBuilder.setContentText("Download complete")
.setProgress(0,0,false);
mNotifyManager.notify(id, mBuilder.build());
}
}
).start();
7. 更新通知
根据id来更新通知
8. 自定义通知布局
Notification的自定义布局通过RemoteViews去实现,调用Notification.Builder的setCustomContentView()方法设置自定义的布局
//通过RemoteViews来创建自定义的Notification视图
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notification);
contentView.setTextViewText(R.id.tv, "show me when collapsed");
Notification.Builder builder = new Notification.Builder(this)
.setCustomContentView(contentView);
折叠式Notification
折叠式Notification 也是一种自定义视图的Notification ,常常用于显示长文本。它拥有两个视图状态, 一个是普通状态下的视图状态, 另一个是展开状态下的视图状态。在Notitication中,使用RemoteViews 来帮助我们创建一个自定义的Notification 视图,代码如下所示。
//通过RemoteViews来创建自定义的Notification视图
RemoteViews contentView = new RemoteViews(getPackageName(),R.layout.notification);
contentView.setTextViewText(R.id.tv,"show me when collapsed");
悬挂式Notification
触发悬挂式的Notification的条件有
- Activity处于全屏模式
- Notification拥有很高的优先级
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(Notification.PRIORITY_DEFAULT)
.setCategory(Notification.CATEGORY_MESSAGE)
.setContentTitle("Headsup Notification")
.setContentText("I am Headsup Notification");
Intent push = new Intent();
push.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
push.setClass(this,MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this,0,push,PendingIntent.FLAG_CANCEL_CURRENT);
NotificationManager manager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(1,builder.build());
Notification的显示等级
Android 5.x 将Notification分成了三个等级
- VISIBILITY_PRIVATE:表面只有当没有锁屏的时候才能够显示
- VISIBILITY_PUBLIC:表明任何情况下都会显示
- VISIBILITY_SECRET:表明在pin,password等安全锁和没有锁屏的情况下才能够显示
设置Notification的显示等级
Notification.Builder builder = new Notification.Builder(this)
.setVisibility(Notification.VISIBILITY_PRIVATE);
9. 创建一个常规的activity延迟意图
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ResultActivity"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
</activity>
为Intent创建一个回退栈
...
Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent to the top of the stack
stackBuilder.addNextIntent(resultIntent);
// Gets a PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());
10. 创建一个特别的activity延迟意图
<activity
android:name=".ResultActivity"
...
android:launchMode="singleTask"
android:taskAffinity=""
android:excludeFromRecents="true">
</activity>
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
Intent notifyIntent = new Intent(this, ResultActivity.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent notifyPendingIntent =
PendingIntent.getActivity(
this,
0,
notifyIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
builder.setContentIntent(notifyPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());
11、Android 7.0 通知新特性
在Android N中重新设计了通知,可以达到更容易、更快使用的效果。一些主要的变化包括:
模板更新:更新了通知模板重点内容和头像。开发者将能够利用的新模板的优势,在他们的代码中实现最低限度的调整。
捆绑通知:Android N的通知功能也更加人性化,现在会自动将相同应用的通知捆绑在一起,实现分组显示,并且通过两指滑动实现预览,理论上用户可以在通知界面直接阅读邮件等内容。
直接回复:对于实时通信应用程序,Android系统支持在线回复,使用户可以以短信或短信通知界面内快速、直接响应。
自定义视图:两个新的 API 让用户在通知中使用自定义视图。
Android N 开发者预览版的通知系统中还加入了两个全新的 API 接口:Direct Replies 和 Bundling。前者支持为第三方应用的通知加入快速回复和快捷操作,后者则允许同时发出多条通知的应用进行通知拆分。
当一款应用完美的适配了 Android N,当收到一条消息时就可以直接在下拉通知抽屉甚至是锁屏中直接呼出输入框进行回复,或是选择事先设定好的快速处理操作(标记为已读、转发等)。而当用户同时收到来自不同联系人的消息时,可以点击知卡片上的通知拆分按钮对已经合并的通知进行拆分,拆分后的通知可以像其他的独立通知一样进行回复和处理。
当然,现阶段适配了这两个特性的应用屈指可数,除了 Google 的环聊、Messenger 以及 Gmail 等应用以外,目前仅发现第三方 Telegram 客户端 Plus Messenger 支持以上功能。
面对各种应用的通知推送, Android N取以优先级为核心的通知管理方式,而在 Android N中,通知管理也变得更加简单:只需在需要在相应的通知上左右轻扫便能看见一个设置图标,点击该图标就能在通知上方呼出一个简洁的通知优先级设定界面,在这个界面可以将应用通知设定为“静默显示”、“阻拦所有通知”和“默认”三个等级。
如果在”系统界面调谐器 - 其它“中打开了”Show full importance settings”功能,这三个等级又将变为”屏蔽 - 低 - 一般 - 高 - 紧急”5 个,设定的方式也由纵列选项变为左右滑动。这个看似新颖的设计实际上是对现有通知管理操作的一次简化,在 Android 6.0 中需要在两个界面来回跳转才能完成的操作,在Android 7.0只用在一个界面就可以搞定。
同时,Google 也将其对通知优先级的定义从”幕后”搬到了”台前”,在进行完整的五层次优先级设定时 Google 还会提醒不同优先级所对应的通知效果。最后,勿扰模式也在 Android N 中得到了完善,加入了自动规则并允许用户在“请勿打扰”模式下屏蔽静音通知的弹窗甚至是手机的通知指示灯。
发送一个通知
private int i = 0;
private NotificationManager mNotificationManager;
private static final String GROUP_NAME = "com.heima.notification_type";
//[1]获取一个NotificationManager
mNotificationManager = (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
//[2]创建一个Notification
//[2.1]需要给这个Notification对象指定icon,标题,内容,
final Notification builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_notification)
.setContentTitle(getString(R.string.app_name))
.setContentText("这是一个消息通知")
.setAutoCancel(true)
.setGroup(GROUP_NAME)
.build();
//[3]发送一个通知 需要指定一个Notification对象和一个id,这个id必须是唯一的
mNotificationManager.notify(i++, builder);
updateNotificationSummary();
多个通知放入到一个组内
//[4]创建一个notification组
String notificationContent = "传智播客" + i;
final NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_notification)
.setStyle(new NotificationCompat.BigTextStyle()
.setSummaryText(notificationContent))
.setGroup(GROUP_NAME)
.setGroupSummary(true);
final Notification notification = builder.build();
//[5]发送这个notification组
mNotificationManager.notify(101, notification);
可以回复的通知
private NotificationManager mNotificationManager;
//[1]获取一个NotificationManager
mNotificationManager = (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
//[2]创建remoteInput对象,这个对象指定了这个notification的标题和一个key
String replyLabel = getResources().getString(R.string.app_name);
RemoteInput remoteInput = new RemoteInput.Builder("heima")
.setLabel(replyLabel)
.build();
//[3]创建一个Action对象 可以指定用户一个友好的输入提示,可以指定跳转意图,
Intent deleteIntent = new Intent("");
Notification.Action action =
new Notification.Action.Builder(R.mipmap.ic_launcher,
"请输入内容", PendingIntent.getActivity(this, 10002, deleteIntent, 0))
.addRemoteInput(remoteInput)
.build();
//[3]创建一个Notification对象
Notification notification =
new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_notification)
.setContentTitle("传智播客")
.setContentText("消息通知")
.addAction(action)
.build();
//[4]发送这个notification
mNotificationManager.notify(1, notification);
public class MainActivity extends Activity {
private int i = 0;
private NotificationManager mNotificationManager;
private static final String GROUP_NAME = "com.heima.notification_type";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void sendNotification(View v){
//[1]获取一个NotificationManager
mNotificationManager = (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
//[2]创建一个Notification
//[2.1]需要给这个Notification对象指定icon,标题,内容,
final Notification builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_notification)
.setContentTitle(getString(R.string.app_name))
.setContentText("这是一个消息通知")
.setAutoCancel(true)
.setGroup(GROUP_NAME)
.build();
//[3]发送一个通知 需要指定一个Notification对象和一个id,这个id必须是唯一的
mNotificationManager.notify(i++, builder);
}
public void sendGroup(View v){
//[1]获取一个NotificationManager
mNotificationManager = (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
//[2]创建一个Notification
//[2.1]需要给这个Notification对象指定icon,标题,内容,
final Notification builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_notification)
.setContentTitle(getString(R.string.app_name))
.setContentText("这是一个消息通知")
.setAutoCancel(true)
.setGroup(GROUP_NAME)
.build();
//[3]发送一个通知 需要指定一个Notification对象和一个id,这个id必须是唯一的
mNotificationManager.notify(i++, builder);
//[4]创建一个notification组
String notificationContent = "传智播客" + i;
final NotificationCompat.Builder builder1 = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_notification)
.setStyle(new NotificationCompat.BigTextStyle()
.setSummaryText(notificationContent))
.setGroup(GROUP_NAME)
.setGroupSummary(true);
final Notification notification = builder1.build();
//[5]发送这个notification组
mNotificationManager.notify(101, notification);
}
public void send(View v){
//[1]获取一个NotificationManager
mNotificationManager = (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
//[2]创建remoteInput对象,这个对象指定了这个notification的标题和一个key
String replyLabel = getResources().getString(R.string.app_name);
RemoteInput remoteInput = new RemoteInput.Builder("heima")
.setLabel(replyLabel)
.build();
//[3]创建一个Action对象 可以指定用户一个友好的输入提示,可以指定跳转意图,
Intent deleteIntent = new Intent(this,MainActivity.class);
Notification.Action action =
new Notification.Action.Builder(R.mipmap.ic_launcher,
"请输入内容", PendingIntent.getActivity(this, 10002, deleteIntent, 0))
.addRemoteInput(remoteInput)
.build();
//[3]创建一个Notification对象
Notification notification =
new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_notification)
.setContentTitle("传智播客")
.setContentText("消息通知")
.addAction(action)
.build();
//[4]发送这个notification
mNotificationManager.notify(1, notification);
}
}
http://android.xsoftlab.net/guide/topics/ui/notifiers/notifications.html#CustomNotification
http://android.xsoftlab.net/design/patterns/notifications.html
自定义Notification
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="自定义的notification" />
<ProgressBar
android:id="@+id/progressBar1"
android:max="100"
android:progress="50"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
实现代码
public class DemoActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void click(View view){
System.out.println("haha");
//1.创建notification 的管理器
NotificationManager manager = (NotificationManager) this.getSystemService(NOTIFICATION_SERVICE);
//2 .创建notification的实例
Notification notification = new Notification();
notification.flags = Notification.FLAG_AUTO_CANCEL;
notification.icon = R.drawable.ic_launcher;
notification.tickerText="自定义notification";
//notification.contentView;
//远程的view 我们的view对象 是要显示在另外一个进程里面 另外一个程序里面 所以就需要一个remote view
RemoteViews rv = new RemoteViews(getPackageName(), R.layout.custom_notification);
rv.setTextViewText(R.id.textView1, "textview 自定义notification");
rv.setProgressBar(R.id.progressBar1, 100, 50, false);
notification.contentView = rv;
Intent intent = new Intent(this,DemoActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
notification.contentIntent = pendingIntent;
manager.notify(2, notification);
}
}
源码位置
https://github.com/JiangHaiYang01/NotificationDemo