Android Notification剖析

本文介绍如何在Android中创建标准和自定义通知,包括获取NotificationManager、实例化Notification、定义通知栏消息及Intent等步骤。

一、要创建一个notification,有如下几个步骤:

1.获取NotificationManager:

String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
2.实例化一个Notification:

int icon = R.drawable.notification_icon;
CharSequence tickerText = "Hello";
long when = System.currentTimeMillis();

Notification notification = new Notification(icon, tickerText, when);
3.定义Notification的通知栏消息和Intent:

Context context = getApplicationContext();
CharSequence contentTitle = "My notification";
CharSequence contentText = "Hello World!";
Intent notificationIntent = new Intent(this, MyClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
4.把notification传作notificationManager的参数:

private static final int HELLO_ID = 1;

mNotificationManager.notify(HELLO_ID, notification);
如果你想激起你的notification,只需把Notification对象传作NotificationManager的notify(int,Notification)方法。第一个参数这个notification的唯一ID,第二个参数就是Notification对象。ID是你的应用的notification的唯一标识,所以如果你想要更新你的notification或者通过在Notification中定义的Intent来完成相应动作,这个ID就是必须且相当有用的。

想要清除notification,添加“FLAG_AUTO_CANCEL”到你的Notification对象中。你也可以通过手动传递notification ID调用cancel(int),或调用cancelAll()清除所有notification。

一个notification需要如下:

1.一个要在状态栏展示的icon图标

2.一个在通知栏view中的标题和消息(除非你定义自定义的通知栏view)

3.一个PendingIntent,当notification被选中时触发

可选的:

一个状态栏的ticker-text消息

一个警报声音

一个振动效果

一个flashing LED效果
下面展示一个Notification的基本用法:

int icon = R.drawable.notification_icon;        // icon from resources
CharSequence tickerText = "Hello";              // ticker-text
long when = System.currentTimeMillis();         // notification time
Context context = getApplicationContext();      // application Context
CharSequence contentTitle = "My notification";  // expanded message title
CharSequence contentText = "Hello World!";      // expanded message text

Intent notificationIntent = new Intent(this, MyClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

// the next two lines initialize the Notification, using the configurations above
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
这里面有个重要的类PendingIntent:

public final class PendingIntent extends Object implements Parcelable
它是一个用来描述Intent和目标操作对象的东西。它的一些实例被用在 getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int), getService(Context, int, Intent, int); 中,这个方法返回的对象可交给其他应用程序,这样你就可以按你自己的描述去完成相关操作。
对于notification而言,getActivity(Context context,int requestCode,Intent intent,int flags) 它返回一个即将启动一个新activity的PendingIntent对象,就像调用Context.startActivity(Intent)一样。注意这个activity将在一个现有activity的context的外面启动,因此你得使用flag=Intent.FLAG_ACTIVITY_NEW_TASK去启动之。

参数:

context:PendingIntent要查这个Context上下文中去启动activity

requestCode:发送者私有的请求码(目前未使用)

intent:要去启动activity的Intent

flags:常用的几个常量如下(注:包含PendingIntent和Notification,PendIngIntent是作其参数,Notification是notification.flags属性):

“FLAG_AUTO_CANCEL”:当notification被点中后自动取消,该通知能被状态栏的清除按钮给清除掉。

"FLAG_NO_CLEAR":该通知不能被状态栏的清除按钮给清除掉

“FLAG_ONGOING_EVENT":将notification组织到”Ongoing"下,这表示这个应用程序在on-going状态,即它的进程仍运行在后台,即便这个应用程序不可见(如播放音乐或打电话)。即通知放置在正在运行。

“FLAG_ONE_SHOT":这个PendingIntent只能被用一次,当设置后,在send()被调用后,它将自动取消。

”FLAG_UPDATE_CURRENTR":如果所描述的PendingIntent已经存在,则保持住它并用新Intent中的数据取代之。

”FLAG_NO_CREATE":如果所描述的PendingIntent不存在,则返回null而非创建它。

“FLAG_CANCEL_CURRENT":如果所描述的Pending已经存在,当前的被取消,然后创建一个新的。

二、创建自定义通知栏:

1.创建xml布局文件,如custom_notification_layout.xml

2.使用RemoteViews的方法去定义image和text,如:

RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout);
contentView.setImageViewResource(R.id.image, R.drawable.notification_image);
contentView.setTextViewText(R.id.text, "Hello, this message is in a custom expanded view");
notification.contentView = contentView;
3.你不需要setLatestEventInfo()方法了,取而代之的是如:

Intent notificationIntent = new Intent(this, MyClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.contentIntent = contentIntent;
4.发送通知:

mNotificationManager.notify(CUSTOM_VIEW_ID, notification);


下面来看一下notify的两个方法的比较

public void notify (int id, Notification notification)

Post a notification to be shown in the status bar. If a notification with the same id has already been posted by your application and has not yet been canceled, it will be replaced by the updated information.

Parameters:
id(int):An identifier for this notification unique within your application.
notification(Notification):A Notification object describing what to show the user. Must not be null.

public void notify (String tag, int id, Notification notification)
Post a notification to be shown in the status bar. If a notification with the same tag and id has already been posted by your application and has not yet been canceled, it will be replaced by the updated information.

Parameters:
tag(String): A string identifier for this notification. May be null.
id(int):An identifier for this notification. The pair (tag, id) must be unique within your application.
notification(Notification):A Notification object describing what to show the user. Must not be null.

详见:国内Creating Status Bar Notifications 、google官网中文文档

最后,给出一个真实的例子,大家看看效果:

package com.example.testnotification;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RemoteViews;

public class MainActivity extends Activity {
	private NotificationManager nm;
	private Button btn1, btn2, btn3, btn4;
	private int count = 0;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

		btn1 = (Button) findViewById(R.id.btn1);
		btn1.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				count++;
				Notification n = new Notification(R.drawable.ic_launcher, "我是通知提示", System.currentTimeMillis());
				n.flags = Notification.FLAG_AUTO_CANCEL;
				n.number = count;
				Intent it = new Intent(MainActivity.this, SecondActivity.class);
				it.putExtra("name", "name:" + count);
				PendingIntent pi = PendingIntent.getActivity(MainActivity.this, 100, it,
						PendingIntent.FLAG_CANCEL_CURRENT);
				n.setLatestEventInfo(MainActivity.this, "标题", "启动多次通知只显示一条", pi);
				nm.notify(1, n);

			}
		});
		btn2 = (Button) findViewById(R.id.btn2);
		btn2.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				count++;
				Notification n = new Notification(R.drawable.ic_launcher, "我是通知提示", System.currentTimeMillis());
				n.flags = Notification.FLAG_AUTO_CANCEL;
				n.number = count;
				Intent it = new Intent(MainActivity.this, SecondActivity.class);
				it.putExtra("name", "name:" + count);
				PendingIntent pi = PendingIntent.getActivity(MainActivity.this, 100, it,
						PendingIntent.FLAG_CANCEL_CURRENT);
				n.setLatestEventInfo(MainActivity.this, "标题", "启动多次通知显示多条,但只能用最新的通知跳转到活动", pi);
				nm.notify(count, n);

			}
		});
		btn3 = (Button) findViewById(R.id.btn3);
		btn3.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				count++;
				Notification n = new Notification(R.drawable.ic_launcher, "我是通知提示", System.currentTimeMillis());
				n.flags = Notification.FLAG_AUTO_CANCEL;
				n.number = count;
				Intent it = new Intent(MainActivity.this, SecondActivity.class);
				it.putExtra("name", "name:" + count);
				PendingIntent pi = PendingIntent.getActivity(MainActivity.this, count, it,
						PendingIntent.FLAG_CANCEL_CURRENT);
				n.setLatestEventInfo(MainActivity.this, "标题", "启动多次通知显示多条,每一条通知都能跳转到对应的活动", pi);
				nm.notify(count, n);

			}
		});
		btn4 = (Button) findViewById(R.id.btn4);
		btn4.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				count++;
				Notification n = new Notification(R.drawable.ic_launcher, "我是通知提示", System.currentTimeMillis());
				n.flags = Notification.FLAG_ONGOING_EVENT;
				RemoteViews rv = new RemoteViews(MainActivity.this.getPackageName(), R.layout.notify);
				n.contentView = rv;
				Intent it = new Intent(MainActivity.this, SecondActivity.class);
				it.putExtra("name", "name:" + count);
				PendingIntent pi = PendingIntent.getActivity(MainActivity.this, count, it, 0);
				n.contentIntent = pi;
				nm.notify(count, n);
				rv.setTextViewText(R.id.tv2, "我是自定义布局");
				Intent clickIntent = new Intent("ONCLICK");
				PendingIntent clickPending = PendingIntent.getBroadcast(MainActivity.this, count, clickIntent, 0);
				rv.setOnClickPendingIntent(R.id.cancel, clickPending);
			}
		});

	}

}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

itzyjr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值