创建状态栏通知 notification

来源:互联网 发布:mac svn上传新项目 编辑:程序博客网 时间:2024/04/26 08:28

懒骨头(http://blog.csdn.com/iamlazybone)

一个状态栏通知,会在系统的状态栏添加一个图标,并且在状态窗口添加一条信息。当用户点击这个信息时,android会发送一个intent请求,通常是启动一个已定义的activity。你可以添加声音、震动、闪屏给设备来提醒用户。

通常一个后台服务运行时,如果需要提醒用户一些事件、或者让用户反馈一些信息时,通常用到状态栏提醒。一个后台Service永远不会自己运行一个activity来接受用户交互,一般的,后台服务会添加一个状态栏通知来与用户进行交互。

下图显示了一个状态栏通知:

 

接下来的会显示状态栏窗口。用户可以打开这个窗口通过下滑状态栏。或者使用menu菜单键选择。

 


--------------------------------------------------------------------------------

基础知识

一个activity或者Service可以初始化状态栏通知,因为activity只有在活动状态下才能执行一些命令,所以你需要从一个service来建立状态通知。当用户启动了其他程序或者设备已经休眠时,通过这种方式,通知就可以在后台被创建。你要用到这两个类:Notification类和NotificationManager类。

Notification类来定义状态通知的属性,比如图标,提示信息,或者提示声音。NotificationManager是一个android系统的服务,来管理和运行所有通知的,他不能被实例化,你可以用getSystemService()方法获得他的句柄。当你想通知用户时,调用notify()方法即可。

创建一个菜单栏通知:

1-获得MotificationManager的引用。

view plaincopy to clipboardprint?
01.String ns = Context.NOTIFICATION_SERVICE;  
02.NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); 
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);

2-实例化Notification:

view plaincopy to clipboardprint?
01.int icon = R.drawable.notification_icon;  
02.CharSequence tickerText = "Hello";  
03.long when = System.currentTimeMillis();  
04.Notification notification = new Notification(icon, tickerText, when); 
int icon = R.drawable.notification_icon;
CharSequence tickerText = "Hello";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);

3-定义Notification,如显示icon、目标intent等信息

view plaincopy to clipboardprint?
01.Context context = getApplicationContext();  
02.CharSequence contentTitle = "My notification";  
03.CharSequence contentText = "Hello World!";  
04.Intent notificationIntent = new Intent(this, MyClass.class);  
05.PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);  
06.notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent); 
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-传递给Manager.

view plaincopy to clipboardprint?
01.private static final int HELLO_ID = 1;  
02.mNotificationManager.notify(HELLO_ID, notification); 
private static final int HELLO_ID = 1;
mNotificationManager.notify(HELLO_ID, notification);

好了,一个通知写完了。


--------------------------------------------------------------------------------

管理你的通知

NotificationManager是一个管理所有通知的系统服务。你可以通过getSystemService()方法得到她的句柄:

view plaincopy to clipboardprint?
01.String ns = Context.NOTIFICATION_SERVICE;  
02.NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); 
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);

当你想发送一个状态栏通知时,通过notify(int,Notification)方法传递Notification对象给NotificationManager,第一个参数是Notification的id,第二个参数是通知的对象。id是一个唯一的标示,当你改变通知或者进行一些的活动时必须要用到它。

当用户从通知窗口选择了某个通知时,会给这个通知添加一个“FLAG_AUTO_CANCEL”标记来移除这个通知。你也可以使用cancel(int)方法,通过指定通知id来取消某个通知,或者干脆cancelAll()。


--------------------------------------------------------------------------------

 建立一个通知

一个通知对象定义了显示在状态栏的一些细节信息,和所有通知方式,例如声音、闪光。

一个状态栏通知必须包括以下几点:

@ 显示在状态栏的图标

@ 一个标题(除非你自定义了提示界面)

@ 一个Pending Intent,即点击后要做的操作。

可选项包括以下:

@ 状态栏提示文本

@ 提示声音

@ 震动

@ 闪光

初学者套件?为新的通知包含了MNotification(int,CharSequence,long)构造方法和setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent)方法。这些参数是一个通知的必要参数。下面的代码片段是一个简单的例子:

view plaincopy to clipboardprint?
01.int icon = R.drawable.notification_icon;        // icon from resources  
02.CharSequence tickerText = "Hello";              // ticker-text  
03.long when = System.currentTimeMillis();         // notification time  
04.Context context = getApplicationContext();      // application Context  
05.CharSequence contentTitle = "My notification";  // expanded message title  
06.CharSequence contentText = "Hello World!";      // expanded message text  
07.Intent notificationIntent = new Intent(this, MyClass.class);  
08.PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);  
09.// the next two lines initialize the Notification, using the configurations above  
10.Notification notification = new Notification(icon, tickerText, when);  
11.notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent); 
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);

更新通知

你可以在事件改变时修改状态栏的通知。例如,当有一条未读短信时又来了一条短信,此时状态栏应该显示新的短信。像这种情况下,添加一条洗得通知不如更改原有通知更加合理,因为后者能避免通知的混乱。

因为每个通知都有一个唯一的Id,你可以通过setLatestEventInfo()方法修改通知,然后调用notify()让其显示。

你可以修改每个属性,除了context和下拉状态栏时显示的标题和文本。你可以通过setLatestEventInfo()方法给contentTitle和conTentText设置文本信息,然后调用notify()方法来更新通知。(当然了你可以创建自己的布局文件,那样的话更新显示文本就没有效果了)。

添加声音

你可以使用默认的声音来提醒用户有一个新通知。方法是添加一个“DEFAULT_SOUND”参数。

view plaincopy to clipboardprint?
01.notification.defaults |= Notification.DEFAULT_SOUND; 
notification.defaults |= Notification.DEFAULT_SOUND;

如果使用非默认的声音,需要传递一个URI资源引用。例如:

view plaincopy to clipboardprint?
01.notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3"); 
notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3");

下个例子中,音频文件从MediaStore类中获取:

view plaincopy to clipboardprint?
01.notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6"); 
notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");

这种情况下,资源id为6的音频文件时已知的,并且已添加到content的URI中。如果你不知道exact ID,你必须在MediaStore中查询所有可用的资源。参考 Content Providers文档。

如果你想让提示声音一直播放知道用户响应位置,你可以添加“FLAG_INSISTENT”参数。

注意:如果包含“DEFAULT_SOUND”参数,那么默认声音会覆盖其他的声音设置。

添加震动

你可以使用默认的震动方式提示用户:

view plaincopy to clipboardprint?
01.notification.defaults |= Notification.DEFAULT_VIBRATE; 
notification.defaults |= Notification.DEFAULT_VIBRATE;

 或者使用自己的振动方式,例如:

view plaincopy to clipboardprint?
01.long[] vibrate = {0,100,200,300};  
02.notification.vibrate = vibrate; 
long[] vibrate = {0,100,200,300};
notification.vibrate = vibrate;

 这个数组定义了交替的震动和关闭,一毫秒为单位。第一个值是等待多久开始震动,第二个值是第一次震动的时间,第三个是停止震动的时间,以此类推。定义多长时间都行,但是不能设置为重复。

注意:如果设置了默认,则其他振动方式无效。

添加手机灯闪烁

让手机闪动LED灯,你可以实现默认的闪动色绘制。或者定义自己的闪动效果。

使用默认的闪光效果,代码如下:

view plaincopy to clipboardprint?
01.notification.defaults |= Notification.DEFAULT_LIGHTS; 
notification.defaults |= Notification.DEFAULT_LIGHTS;

定义自己的效果,可以设置颜色、定义显示的时间,一些常用的值如下:

view plaincopy to clipboardprint?
01.notification.ledARGB = 0xff00ff00;  
02.notification.ledOnMS = 300;  
03.notification.ledOffMS = 1000;  
04.notification.flags |= Notification.FLAG_SHOW_LIGHTS; 
notification.ledARGB = 0xff00ff00;
notification.ledOnMS = 300;
notification.ledOffMS = 1000;
notification.flags |= Notification.FLAG_SHOW_LIGHTS;

在这个例子里,绿灯先显示300毫秒然后关闭一秒钟,设备不是支持所有的颜色,而且不是所有的设备都支持相同颜色。所以设备会按照指定值显示最接近的颜色。绿色是常见的颜色。

通知的更多特性

你可以添加几个特性到你的通知中去。下面是一些有用的设置:

"FLAG_AUTO_CANCEL"标记

这个标记会在用户选择查看通知窗口后自动关闭通知。

"FLAG_INSISTENT"

在用户响应之前一直重复

"FLAG_ONGOING_EVENT"

添加这个标记把通知分在“正在运行”组中,说明程序正在运行,或者后台运行,甚至当程序不可见时,例如播放音乐或者接听电话时。

"FLAG_NO_CLEAR"

这个标记让你的通知不会被Clear按钮所取消。对一直进行中的通知非常有用。

number field

标记表示当前通知所代表的事件数。这个数字显示在icon之上。如果你打算这样使用,当通知第一次建立时必须从1开始计数。如果你改变了他的值从0或其他值开始,那么他将不会显示。

iconLevel field

这个值指当前icon的LevelListDrawable等级。通过改变这个值,你可以让状态栏的icon显示动画。

更多详细的特性和使用方法餐卡Notification类。


--------------------------------------------------------------------------------

建立一个自定义的通知视图

 

默认情况下,下拉的Notification窗口包含一个标题和文本信息。setLatestEventInfo()有两个默认的参数contentTitle和contentText 。然而你通过RemoteViews也可以定义自己下拉通知视图。上卖弄的截图就显示了一个自定义布局的通知视图,包括一个TextView和ImageView。

定义自己的通知视图,实例化RemoteViews对象并且传递给contentView。给contentIntent字段传递PendingIntent值。创建一个自定义的通知视图最好的理解方法就是写一个例子:

1-建立xml布局文件。例如:custom_notification_layout.xml:

view plaincopy to clipboardprint?
01.<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
02.              android:orientation="horizontal" 
03.              android:layout_width="fill_parent" 
04.              android:layout_height="fill_parent" 
05.              android:padding="3dp" 
06.              > 
07.    <ImageView android:id="@+id/image" 
08.              android:layout_width="wrap_content" 
09.              android:layout_height="fill_parent" 
10.              android:layout_marginRight="10dp" 
11.              /> 
12.    <TextView android:id="@+id/text" 
13.              android:layout_width="wrap_content" 
14.              android:layout_height="fill_parent" 
15.              android:textColor="#000" 
16.              /> 
17.</LinearLayout> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="horizontal"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:padding="3dp"
              >
    <ImageView android:id="@+id/image"
              android:layout_width="wrap_content"
              android:layout_height="fill_parent"
              android:layout_marginRight="10dp"
              />
    <TextView android:id="@+id/text"
              android:layout_width="wrap_content"
              android:layout_height="fill_parent"
              android:textColor="#000"
              />
</LinearLayout>

这是一个自定义的扩展通知的视图,但是ImageView和TextView仍然需要程序定义。RemoteViews提供一些方便的方法来让你定义content。

2-下面的代码,使用RemoveViews 的方法定义image和text。然后传递RemoteViews 对象给通知的contentView字段。如下:

view plaincopy to clipboardprint?
01.RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout);  
02.contentView.setImageViewResource(R.id.image, R.drawable.notification_image);  
03.contentView.setTextViewText(R.id.text, "Hello, this message is in a custom expanded view");  
04.notification.contentView = contentView; 
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;

就像显示的那样,传递程序的包名,布局的资源id给RemoteViews的构造方法。然后,定义ImageView和TextView的content,使用setImageViewResource()和setTextViewText().这种情况下,传递你要设置的view对象的引用id。最后把RemoteViews 对象传递给contentView。

3-因为你不需要setLatestEventInfo()了,你必须为通知定义一个intent,例如:

view plaincopy to clipboardprint?
01.Intent notificationIntent = new Intent(this, MyClass.class);  
02.PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);  
03.notification.contentIntent = contentIntent; 
Intent notificationIntent = new Intent(this, MyClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.contentIntent = contentIntent;

4-通知可以这样调用:

view plaincopy to clipboardprint?
01.mNotificationManager.notify(CUSTOM_VIEW_ID, notification); 
mNotificationManager.notify(CUSTOM_VIEW_ID, notification);

RemoteViews 类也包含一些方法让你轻松地添加Chronometer或者ProgressBar在你的通知view里。

注意:当建立一个自定义的通知view,你必须特别小心自定义的布局来适用不同设备的分辨率。尤其这种情况下,更要特别的小心,过于复杂的布局一定要多多测试


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/iamlazybone/archive/2010/10/22/5959598.aspx

原创粉丝点击